aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar dave caruso <me@paperdave.net> 2023-04-27 00:57:49 -0400
committerGravatar GitHub <noreply@github.com> 2023-04-26 21:57:49 -0700
commit5b76ee769e7ba46a1cad08002f1830eed7a34067 (patch)
treeeb550fb40e8781463346604e6c0dfa9727d390dc
parent3a203abc103212bccd487d0c979f93a6b5e2badb (diff)
downloadbun-5b76ee769e7ba46a1cad08002f1830eed7a34067.tar.gz
bun-5b76ee769e7ba46a1cad08002f1830eed7a34067.tar.zst
bun-5b76ee769e7ba46a1cad08002f1830eed7a34067.zip
bundler tests! (#2741)
* bundler tests! * tests
-rw-r--r--test/bundler/bundler_edgecase.test.ts60
-rw-r--r--test/bundler/bundler_plugin.test.ts37
-rw-r--r--test/bundler/esbuild/dce.test.ts59
-rw-r--r--test/bundler/esbuild/default.test.ts761
-rw-r--r--test/bundler/esbuild/lower.test.ts4
-rw-r--r--test/bundler/esbuild/ts.test.ts1
-rw-r--r--test/bundler/expectBundled.ts12
7 files changed, 548 insertions, 386 deletions
diff --git a/test/bundler/bundler_edgecase.test.ts b/test/bundler/bundler_edgecase.test.ts
index d7b994200..cd4b57bc8 100644
--- a/test/bundler/bundler_edgecase.test.ts
+++ b/test/bundler/bundler_edgecase.test.ts
@@ -168,4 +168,64 @@ describe("bundler", () => {
ARBITRARY: "secret environment stuff!",
},
});
+ itBundled("edgecase/StarExternal", {
+ files: {
+ "/entry.js": /* js */ `
+ import { foo } from './foo';
+ import { bar } from './bar';
+ console.log(foo);
+ `,
+ },
+ external: ["*"],
+ });
+ itBundled("edgecase/ImportNamespaceAndDefault", {
+ files: {
+ "/entry.js": /* js */ `
+ import def2, * as ns2 from './c'
+ console.log(def2, JSON.stringify(ns2))
+ `,
+ },
+ external: ["*"],
+ runtimeFiles: {
+ "/c.js": /* js */ `
+ export default 1
+ export const ns = 2
+ export const def2 = 3
+ `,
+ },
+ run: {
+ stdout: '1 {"def2":3,"default":1,"ns":2}',
+ },
+ });
+ itBundled("edgecase/ExternalES6ConvertedToCommonJSSimplified", {
+ files: {
+ "/entry.js": /* js */ `
+ console.log(JSON.stringify(require('./e')));
+ `,
+ "/e.js": `export * from 'x'`,
+ },
+ external: ["x"],
+ runtimeFiles: {
+ "/node_modules/x/index.js": /* js */ `
+ export const ns = 123
+ export const ns2 = 456
+ `,
+ },
+ run: {
+ stdout: `
+ {"ns":123,"ns2":456}
+ `,
+ },
+ });
+ itBundled("edgecase/ImportTrailingSlash", {
+ files: {
+ "/entry.js": /* js */ `
+ import "slash/"
+ `,
+ "/node_modules/slash/index.js": /* js */ `console.log(1)`,
+ },
+ run: {
+ stdout: "1",
+ },
+ });
});
diff --git a/test/bundler/bundler_plugin.test.ts b/test/bundler/bundler_plugin.test.ts
index 69bd221ef..bde2f180c 100644
--- a/test/bundler/bundler_plugin.test.ts
+++ b/test/bundler/bundler_plugin.test.ts
@@ -390,4 +390,41 @@ describe("bundler", () => {
},
};
});
+ itBundled("plugin/ManyFiles", ({ root }) => {
+ const FILES = 200;
+ const create = (fn: (i: number) => string) => new Array(FILES).fill(0).map((_, i) => fn(i));
+
+ let onResolveCount = 0;
+ let importers: string[] = [];
+ return {
+ files: {
+ "index.ts": /* ts */ `
+ ${create(i => `import * as foo${i} from "./${i}.magic";`).join("\n")}
+ ${create(i => `console.log(foo${i}.foo);`).join("\n")}
+ `,
+ },
+ plugins(builder) {
+ builder.onResolve({ filter: /\.magic$/ }, async args => {
+ importers.push(args.importer);
+ onResolveCount++;
+ return {
+ path: args.path,
+ namespace: "magic",
+ };
+ });
+ builder.onLoad({ filter: /\.magic$/, namespace: "magic" }, async args => {
+ return {
+ contents: `export const foo = "${args.path}";`,
+ loader: "js",
+ };
+ });
+ },
+ run: {
+ stdout: create(i => `./${i}.magic`).join("\n"),
+ },
+ onAfterBundle(api) {},
+ };
+ });
});
+
+// TODO: add async on resolve stuff
diff --git a/test/bundler/esbuild/dce.test.ts b/test/bundler/esbuild/dce.test.ts
index 9d4a0c27d..de68742c6 100644
--- a/test/bundler/esbuild/dce.test.ts
+++ b/test/bundler/esbuild/dce.test.ts
@@ -1,6 +1,6 @@
import assert from "assert";
import dedent from "dedent";
-import { itBundled, testForFile } from "../expectBundled";
+import { ESBUILD, itBundled, testForFile } from "../expectBundled";
var { describe, test, expect } = testForFile(import.meta.path);
// Tests ported from:
@@ -88,7 +88,7 @@ describe("bundler", () => {
`,
},
run: {
- stdout: 'hello\n{"default":{"foo":123},"foo":123}',
+ stdout: 'hello\n{"foo":123}',
},
});
itBundled("dce/PackageJsonSideEffectsTrueKeepES6", {
@@ -704,7 +704,6 @@ describe("bundler", () => {
},
});
itBundled("dce/PackageJsonSideEffectsFalseIntermediateFilesChainAll", {
- // GENERATED
files: {
"/Users/user/project/src/entry.js": /* js */ `
import {foo} from "a"
@@ -1038,35 +1037,6 @@ describe("bundler", () => {
stdout: `["F",{"children":[null,{"children":["div",{}]}]}]`,
},
});
- // TODO: Unsure how to port this: https://github.com/evanw/esbuild/blob/main/internal/bundler_tests/bundler_dce_test.go#L1249
- itBundled("dce/DisableTreeShaking", {
- notImplemented: true,
- // GENERATED
- files: {
- "/entry.jsx": /* jsx */ `
- import './remove-me'
- function RemoveMe1() {}
- let removeMe2 = 0
- class RemoveMe3 {}
-
- import './keep-me'
- function KeepMe1() {}
- let keepMe2 = <KeepMe1/>
- function keepMe3() { console.log('side effects') }
- let keepMe4 = /* @__PURE__ */ keepMe3()
- let keepMe5 = pure()
- let keepMe6 = some.fn()
- `,
- "/remove-me.js": `export default 'unused'`,
- "/keep-me/index.js": `console.log('side effects')`,
- "/keep-me/package.json": `{ "sideEffects": false }`,
- },
- ignoreDCEAnnotations: true,
- define: {
- pure: "???",
- "some.fn": "???",
- },
- });
itBundled("dce/DeadCodeFollowingJump", {
notImplemented: true,
files: {
@@ -1308,6 +1278,7 @@ describe("bundler", () => {
dce: true,
});
itBundled("dce/TreeShakingClassStaticProperty", {
+ notImplemented: true,
files: {
"/entry.js": /* js */ `
let remove1 = class { static x }
@@ -1421,6 +1392,7 @@ describe("bundler", () => {
format: "iife",
});
itBundled("dce/TreeShakingNoBundleESM", {
+ notImplemented: true,
files: {
"/entry.js": /* js */ `
function keep() {}
@@ -1434,7 +1406,6 @@ describe("bundler", () => {
dce: true,
});
itBundled("dce/TreeShakingNoBundleCJS", {
- // GENERATED
files: {
"/entry.js": /* js */ `
function keep() {}
@@ -1442,12 +1413,12 @@ describe("bundler", () => {
keep()
`,
},
+ dce: true,
format: "cjs",
treeShaking: true,
mode: "transform",
});
itBundled("dce/TreeShakingNoBundleIIFE", {
- // GENERATED
files: {
"/entry.js": /* js */ `
function keep() {}
@@ -1455,6 +1426,7 @@ describe("bundler", () => {
keep()
`,
},
+ dce: true,
format: "iife",
treeShaking: true,
mode: "transform",
@@ -1483,7 +1455,6 @@ describe("bundler", () => {
},
});
itBundled("dce/DCETypeOf", {
- // GENERATED
files: {
"/entry.js": /* js */ `
// These should be removed because they have no side effects
@@ -1690,6 +1661,7 @@ describe("bundler", () => {
dce: true,
});
itBundled("dce/RemoveUnusedImports", {
+ notImplemented: true,
files: {
"/entry.js": /* js */ `
import REMOVE1 from 'a'
@@ -1698,8 +1670,8 @@ describe("bundler", () => {
`,
},
minifySyntax: true,
- mode: "transform",
dce: true,
+ external: ["a", "b", "c"],
onAfterBundle(api) {
api.expectFile("/out.js").toBe(
dedent`
@@ -1721,6 +1693,7 @@ describe("bundler", () => {
},
minifySyntax: true,
mode: "transform",
+ external: ["a", "b", "c"],
dce: true,
});
itBundled("dce/RemoveUnusedImportsEvalTS", {
@@ -2157,6 +2130,7 @@ describe("bundler", () => {
},
});
itBundled("dce/InlineFunctionCallBehaviorChanges", {
+ notImplemented: true,
files: {
// At the time of writing, using a template string here triggered a bug in bun's transpiler
// making it impossible to run the test.
@@ -2238,6 +2212,7 @@ describe("bundler", () => {
dce: true,
});
itBundled("dce/ConstValueInliningNoBundle", {
+ notImplemented: true,
files: {
"/top-level.js": /* js */ `
// These should be kept because they are top-level and tree shaking is not enabled
@@ -2290,6 +2265,7 @@ describe("bundler", () => {
s_keep, s_keep,
)
}
+ console.log(nested())
`,
"/namespace-export.ts": /* ts */ `
namespace ns {
@@ -2343,10 +2319,12 @@ describe("bundler", () => {
function foo() {
return y_REMOVE
}
+ console.log(foo)
}
+ console.log(nested());
`,
"/disabled-tdz.js": /* js */ `
- foo()
+ console.log(foo())
const x_keep = 1
function foo() {
return x_keep
@@ -2369,6 +2347,7 @@ describe("bundler", () => {
y, y,
)
}
+ console.log(foo())
`,
},
entryPoints: [
@@ -2386,11 +2365,11 @@ describe("bundler", () => {
"/backwards-reference-top-level.js",
"/backwards-reference-nested-function.js",
],
- mode: "transform",
minifySyntax: true,
dce: true,
dceKeepMarkerCount: {
- "/out/top-level.js": 7,
+ "/out/top-level.js": 5,
+ "/out/nested-function.js": 3,
"/out/namespace-export.js": 1,
},
});
@@ -2539,6 +2518,7 @@ describe("bundler", () => {
},
});
itBundled("dce/ConstValueInliningDirectEval", {
+ notImplemented: true,
files: {
"/top-level-no-eval.js": /* js */ `
const keep = 1
@@ -2873,7 +2853,6 @@ describe("bundler", () => {
},
});
itBundled("dce/NestedFunctionInliningWithSpread", {
- // GENERATED
files: {
"/entry.js": /* js */ `
function empty1() {}
diff --git a/test/bundler/esbuild/default.test.ts b/test/bundler/esbuild/default.test.ts
index e178637aa..83822411f 100644
--- a/test/bundler/esbuild/default.test.ts
+++ b/test/bundler/esbuild/default.test.ts
@@ -232,7 +232,8 @@ describe("bundler", () => {
"/e.js": "export default class Foo {}",
},
entryPoints: ["/a.js", "/b.js", "/c.js", "/d.js", "/e.js"],
- mode: "transform",
+ mode: "bundle",
+ external: ["*"],
runtimeFiles: {
"./out/f.js": /* js */ `
export const f = 987;
@@ -312,15 +313,15 @@ describe("bundler", () => {
run: {
file: "/test.js",
},
- external: ["node:assert", "./a", "./b", "./c"],
+ external: ["*"],
} as const;
itBundled("default/ImportFormsWithNoBundle", {
...importFormsConfig,
- });
+ } as any);
itBundled("default/ImportFormsWithMinifyIdentifiersAndNoBundle", {
...importFormsConfig,
minifyIdentifiers: true,
- });
+ } as any);
itBundled("default/ExportFormsCommonJS", {
files: {
"/entry.js": /* js */ `
@@ -1063,6 +1064,7 @@ describe("bundler", () => {
"/entry.js": /* js */ `
try {
const supportsColor = require('not-supports-color'); // bun overrides supports-color
+ exports.colors = false;
if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
exports.colors = [];
}
@@ -1080,7 +1082,7 @@ describe("bundler", () => {
"/test2.js": /* js */ `
globalThis.requireThrows = true;
import assert from 'assert';
- assert.deepEqual((await import('./out')).default, { })
+ assert.deepEqual((await import('./out')).default, { colors: 'it threw' })
`,
"/node_modules/not-supports-color/index.js": /* js */ `
if (requireThrows) {
@@ -1420,10 +1422,10 @@ describe("bundler", () => {
"/test.js": /* js */ `
import fs from "fs";
import assert from "assert";
- import module from './out.js';
- assert(module.fs === fs, 'exports.fs')
- assert(module.readFileSync === fs.readFileSync, 'exports.readFileSync')
- assert(module.foo === 123, 'exports.foo')
+ import * as mod from './out.js';
+ assert(mod.fs === fs, 'exports.fs')
+ assert(mod.readFileSync === fs.readFileSync, 'exports.readFileSync')
+ assert(mod.foo === 123, 'exports.foo')
`,
},
platform: "node",
@@ -1541,16 +1543,33 @@ describe("bundler", () => {
},
});
itBundled("default/TopLevelReturnForbiddenImport", {
+ notImplemented: true,
files: {
"/entry.js": /* js */ `
+ console.log('A');
return
+ console.log('B');
import 'foo'
`,
},
- mode: "transform",
- bundleErrors: {
- "/entry.js": ["Top-level return cannot be used inside an ECMAScript module"],
+ external: ["foo"],
+ runtimeFiles: {
+ "/node_modules/foo/index.js": "console.log('C')",
+ },
+ run: {
+ stdout: "C\nA",
+ },
+ });
+ itBundled("default/TopLevelReturnForbiddenImportAndModuleExports", {
+ notImplemented: true,
+ files: {
+ "/entry.js": /* js */ `
+ module.exports.foo = 123
+ return
+ import 'foo'
+ `,
},
+ external: ["foo"],
});
itBundled("default/TopLevelReturnForbiddenExport", {
files: {
@@ -1947,7 +1966,7 @@ describe("bundler", () => {
})(1,3,5);
`,
},
- format: "esm",
+ format: "iife",
outfile: "/out.js",
minifyIdentifiers: true,
// mode: "transform",
@@ -2204,6 +2223,7 @@ describe("bundler", () => {
},
});
itBundled("default/ImportWithQueryParameter", {
+ notImplemented: true,
files: {
"/entry.js": /* js */ `
// Each of these should have a separate identity (i.e. end up in the output file twice)
@@ -2290,7 +2310,7 @@ describe("bundler", () => {
},
});
itBundled("default/AutoExternalNode", {
- skipOnEsbuild: true,
+ notImplemented: true,
files: {
"/entry.js": /* js */ `
// These URLs should be external automatically
@@ -2299,7 +2319,36 @@ describe("bundler", () => {
// This should be external and should be tree-shaken because it's side-effect free
import "node:path";
- import "bun";
+ import "querystring";
+
+ // This should be external too, but shouldn't be tree-shaken because it could be a run-time error
+ import "node:what-is-this";
+ `,
+ },
+ platform: "node",
+ treeShaking: true,
+ onAfterBundle(api) {
+ const file = api.readFile("/out.js");
+ const imports = new Bun.Transpiler().scanImports(file);
+ expect(imports).toStrictEqual([
+ { kind: "import-statement", path: "node:fs/promises" },
+ { kind: "import-statement", path: "node:what-is-this" },
+ ]);
+ },
+ });
+ itBundled("default/AutoExternalBun", {
+ skipOnEsbuild: true,
+ notImplemented: true,
+ files: {
+ "/entry.js": /* js */ `
+ // These URLs should be external automatically
+ import fs from "node:fs/promises";
+ fs.readFile();
+ import { CryptoHasher } from "bun";
+ new CryptoHasher();
+
+ // This should be external and should be tree-shaken because it's side-effect free
+ import "node:path";
import "bun:sqlite";
// This should be external too, but shouldn't be tree-shaken because it could be a run-time error
@@ -2307,13 +2356,15 @@ describe("bundler", () => {
import "bun:what-is-this";
`,
},
- platform: "node",
+ platform: "bun",
onAfterBundle(api) {
const file = api.readFile("/out.js");
const imports = new Bun.Transpiler().scanImports(file);
expect(imports).toStrictEqual([
+ // bun is transformed in destructuring the bun global
{ kind: "import-statement", path: "node:fs/promises" },
{ kind: "import-statement", path: "node:what-is-this" },
+ { kind: "import-statement", path: "bun:what-is-this" },
]);
},
});
@@ -2457,17 +2508,20 @@ describe("bundler", () => {
}}}}}}}}}}}}}}}}}}}}}}}}}}}
`;
itBundled("default/NestedLabelsBundle", {
+ notImplemented: true,
files: {
"/entry.js": crazyNestedLabelFile,
},
});
itBundled("default/NestedLabelsNoBundle", {
+ notImplemented: true,
files: {
"/entry.js": crazyNestedLabelFile,
},
mode: "transform",
});
itBundled("default/MinifyNestedLabelsNoBundle", {
+ notImplemented: true,
files: {
"/entry.js": crazyNestedLabelFile,
},
@@ -2477,6 +2531,7 @@ describe("bundler", () => {
mode: "transform",
});
itBundled("default/MinifyNestedLabelsBundle", {
+ notImplemented: true,
files: {
"/entry.js": crazyNestedLabelFile,
},
@@ -2618,14 +2673,15 @@ describe("bundler", () => {
stdout: "123",
},
});
- itBundled("default/RelativeEntryPointError", {
+ itBundled("default/RelativeFilepathEntryPoint", {
files: {
"/entry.js": `console.log(123)`,
},
- entryPointsRaw: ["entry"],
+ entryPointsRaw: ["entry.js"],
outfile: "/out.js",
- bundleErrors: {
- "<bun>": [`ModuleNotFound resolving "entry". Did you mean: "./entry"`],
+ run: {
+ file: "/out.js",
+ stdout: "123",
},
});
itBundled("default/MultipleEntryPointsSameNameCollision", {
@@ -2750,7 +2806,7 @@ describe("bundler", () => {
file: "/test.js",
stdout: "foo bar",
},
- mode: "transform",
+ external: ["*"],
});
itBundled("default/ImportMetaCommonJS", {
files: {
@@ -3452,6 +3508,7 @@ describe("bundler", () => {
mode: "transform",
});
itBundled("default/TopLevelAwaitForbiddenRequire", {
+ notImplemented: true,
files: {
"/entry.js": /* js */ `
require('./a')
@@ -3585,6 +3642,7 @@ describe("bundler", () => {
},
});
itBundled("default/AssignToImportNoBundle", {
+ notImplemented: true,
files: {
"/bad0.js": `import x from "foo"; x = 1`,
"/bad1.js": `import x from "foo"; x++`,
@@ -4486,6 +4544,7 @@ describe("bundler", () => {
},
});
itBundled("default/CharFreqIgnoreComments", {
+ notImplemented: true,
files: {
"/a.js": /* js */ `
export default function(one, two, three, four) {
@@ -4689,7 +4748,6 @@ describe("bundler", () => {
// mode: "transform",
// external: ["a", "b", "c", "react/jsx-dev-runtime"],
// });
- if (!RUN_UNCHECKED_TESTS) return;
// I cant get bun to use `this` as the JSX runtime. It's a pretty silly idea anyways.
// itBundled("default/JSXThisValueCommonJS", {
// files: {
@@ -4928,13 +4986,13 @@ describe("bundler", () => {
// `, */
// });
0;
-
itBundled("default/BundlingFilesOutsideOfOutbase", {
- // GENERATED
+ notImplemented: true,
files: {
"/src/entry.js": `console.log('test')`,
},
splitting: true,
+ outdir: "/out",
format: "esm",
outbase: "/some/nested/directory",
});
@@ -5009,17 +5067,14 @@ describe("bundler", () => {
const relocateEntries = ["/top-level.js", "/nested.js", "/let.js", "/function.js", "/function-nested.js"];
itBundled("default/VarRelocatingBundle", {
- // GENERATED
files: relocateFiles,
entryPoints: relocateEntries,
format: "esm",
});
itBundled("default/VarRelocatingNoBundle", {
- // GENERATED
files: relocateFiles,
entryPoints: relocateEntries,
format: "esm",
- mode: "convertformat",
});
itBundled("default/ImportNamespaceThisValue", {
// GENERATED
@@ -5038,11 +5093,12 @@ describe("bundler", () => {
console.log(new def(), new foo())
`,
},
+ external: ["external"],
entryPoints: ["/a.js", "/b.js", "/c.js"],
format: "cjs",
});
+ // esbuild and bun do not give the warning. this is still set to undefined
itBundled("default/ThisUndefinedWarningESM", {
- // GENERATED
files: {
"/entry.js": /* js */ `
import x from './file1.js'
@@ -5052,35 +5108,42 @@ describe("bundler", () => {
"/file1.js": `export default [this, this]`,
"/node_modules/pkg/file2.js": `export default [this, this]`,
},
- /* TODO FIX expectedScanLog: `file1.js: DEBUG: Top-level "this" will be replaced with undefined since this file is an ECMAScript module
- file1.js: NOTE: This file is considered to be an ECMAScript module because of the "export" keyword here:
- node_modules/pkg/file2.js: DEBUG: Top-level "this" will be replaced with undefined since this file is an ECMAScript module
- node_modules/pkg/file2.js: NOTE: This file is considered to be an ECMAScript module because of the "export" keyword here:
- `, */
+ run: {
+ stdout: "[ null, null ] [ null, null ]",
+ },
});
itBundled("default/QuotedProperty", {
- // GENERATED
+ notImplemented: true,
files: {
"/entry.js": /* js */ `
import * as ns from 'ext'
console.log(ns.mustBeUnquoted, ns['mustBeQuoted'])
`,
},
- format: "cjs",
+ external: ["ext"],
+ onAfterBundle(api) {
+ const code = api.readFile("/out.js");
+ expect(code).not.toContain(`"mustBeUnquoted"`);
+ expect(code).toContain(`"mustBeQuoted"`);
+ },
});
itBundled("default/QuotedPropertyMangle", {
- // GENERATED
files: {
"/entry.js": /* js */ `
import * as ns from 'ext'
console.log(ns.mustBeUnquoted, ns['mustBeUnquoted2'])
`,
},
- format: "cjs",
minifySyntax: true,
+ external: ["ext"],
+ onAfterBundle(api) {
+ const code = api.readFile("/out.js");
+ expect(code).toContain(`.mustBeUnquoted`);
+ expect(code).toContain(`.mustBeUnquoted2`);
+ },
});
itBundled("default/DuplicatePropertyWarning", {
- // GENERATED
+ notImplemented: true,
files: {
"/entry.js": /* js */ `
import './outside-node-modules'
@@ -5091,19 +5154,17 @@ describe("bundler", () => {
"/node_modules/inside-node-modules/index.jsx": `console.log({ c: 1, c: 2 }, <div c2 c2={3}/>)`,
"/node_modules/inside-node-modules/package.json": `{ "d": 1, "d": 2 }`,
},
- /* TODO FIX expectedScanLog: `outside-node-modules/index.jsx: WARNING: Duplicate key "a" in object literal
- outside-node-modules/index.jsx: NOTE: The original key "a" is here:
- outside-node-modules/index.jsx: WARNING: Duplicate "a2" attribute in JSX element
- outside-node-modules/index.jsx: NOTE: The original "a2" attribute is here:
- outside-node-modules/package.json: WARNING: Duplicate key "b" in object literal
- outside-node-modules/package.json: NOTE: The original key "b" is here:
- `, */
+ external: ["react"],
+ bundleWarnings: {
+ "/outside-node-modules/index.jsx": ['Duplicate key "a" in object literal', 'Duplicate key "a2" in JSX element'],
+ "/outside-node-modules/package.json": ['Duplicate key "b" in object literal'],
+ },
});
- itBundled("default/RequireShimSubstitution", {
- // GENERATED
+ const RequireShimSubstitutionBrowser = itBundled("default/RequireShimSubstitutionBrowser", {
+ notImplemented: true,
files: {
"/entry.js": /* js */ `
- console.log([
+ Promise.all([
require,
typeof require,
require('./example.json'),
@@ -5116,14 +5177,84 @@ describe("bundler", () => {
require.resolve(window.SOME_PATH),
import('some-path'),
import(window.SOME_PATH),
- ])
+ ]).then(results => {
+ for (let result of results) {
+ if (typeof result === 'string' && result.startsWith(dirname)) {
+ result = result.slice(dirname.length)
+ }
+ console.log(typeof result, JSON.stringify(result))
+ }
+ })
`,
"/example.json": `{ "works": true }`,
},
- external: ["some-path"],
+ runtimeFiles: {
+ "/test.mjs": `
+ import { createRequire } from "module";
+ const require = createRequire(import.meta.url);
+ import { fileURLToPath } from "url";
+ import { dirname } from "path";
+ globalThis.dirname = dirname(fileURLToPath(import.meta.url));
+ globalThis.window = globalThis
+ window.SOME_PATH = 'second-path'
+ window.require = require
+ window.module = { require: (x) => 'dynamic req: ' + x }
+ await import('./out.mjs')
+ `,
+ "/node_modules/some-path/index.js": `module.exports = 123`,
+ "/node_modules/second-path/index.js": `module.exports = 567`,
+ },
+ external: ["*"],
+ platform: "browser",
+ format: "esm",
+ outfile: "/out.mjs",
+ run: {
+ runtime: "node",
+ file: "/test.mjs",
+ stdout: `
+ function undefined
+ string "function"
+ object {"works":true}
+ object {"works":true}
+ number 567
+ object {"works":true}
+ object {"works":true}
+ number 567
+ string "/node_modules/some-path/index.js"
+ string "/node_modules/second-path/index.js"
+ object {"default":123}
+ object {"default":567}
+ `,
+ },
+ });
+ itBundled("default/RequireShimSubstitutionNode", {
+ notImplemented: true,
+ files: RequireShimSubstitutionBrowser.options.files,
+ runtimeFiles: RequireShimSubstitutionBrowser.options.runtimeFiles,
+ external: ["*"],
+ platform: "node",
+ format: "esm",
+ outfile: "/out.mjs",
+ run: {
+ runtime: "node",
+ file: "/test.mjs",
+ stdout: `
+ function undefined
+ string "function"
+ object {"works":true}
+ object {"works":true}
+ number 567
+ object {"works":true}
+ object {"works":true}
+ number 567
+ string "/node_modules/some-path/index.js"
+ string "/node_modules/second-path/index.js"
+ object {"default":123}
+ object {"default":567}
+ `,
+ },
});
itBundled("default/StrictModeNestedFnDeclKeepNamesVariableInliningESBuildIssue1552", {
- // GENERATED
files: {
"/entry.js": /* js */ `
export function outer() {
@@ -5139,10 +5270,11 @@ describe("bundler", () => {
`,
},
keepNames: true,
- mode: "passthrough",
+ minifySyntax: true,
});
itBundled("default/BuiltInNodeModulePrecedence", {
// GENERATED
+ notImplemented: true,
files: {
"/entry.js": /* js */ `
console.log([
@@ -5161,7 +5293,6 @@ describe("bundler", () => {
"/node_modules/fs/promises.js": `throw 'DO NOT INCLUDE THIS'`,
},
platform: "node",
- format: "cjs",
});
itBundled("default/EntryNamesNoSlashAfterDir", {
// GENERATED
@@ -5170,59 +5301,60 @@ describe("bundler", () => {
"/src/app2/main.ts": `console.log(2)`,
"/src/app3/main.ts": `console.log(3)`,
},
- entryPointsAdvanced: [
- { input: "/src/app1/main.ts" },
- { input: "/src/app2/main.ts" },
- { input: "/src/app3/main.ts", output: "customPath" },
- ],
+ entryPoints: ["/src/app1/main.ts", "/src/app2/main.ts", "/src/app3/main.ts"],
+ outputPaths: ["/out/app1-main.js", "/out/app2-main.js", "/out/app3-main.js"],
entryNames: "[dir]-[name].[ext]",
- mode: "passthrough",
- });
- itBundled("default/EntryNamesNonPortableCharacter", {
- // GENERATED
- // TODO: I think this is impossible with the CLI. and also very unsafe with paths.
- files: {
- "/entry1-*.ts": `console.log(1)`,
- "/entry2-*.ts": `console.log(2)`,
- },
- entryPointsAdvanced: [
- // The "*" should turn into "_" for cross-platform Windows portability
- { input: "/entry1-*.ts" },
- // The "*" should be preserved since the user _really_ wants it
- { input: "/entry2-*.ts", output: "entry2-*" },
- ],
- mode: "passthrough",
- });
- itBundled("default/EntryNamesChunkNamesExtPlaceholder", {
- // GENERATED
- files: {
- "/src/entries/entry1.js": `import "../lib/shared.js"; import "./entry1.css"; console.log('entry1')`,
- "/src/entries/entry2.js": `import "../lib/shared.js"; import "./entry2.css"; console.log('entry2')`,
- "/src/entries/entry1.css": `a:after { content: "entry1" }`,
- "/src/entries/entry2.css": `a:after { content: "entry2" }`,
- "/src/lib/shared.js": `console.log('shared')`,
- },
- entryPoints: ["/src/entries/entry1.js", "/src/entries/entry2.js"],
- outbase: "/src",
- splitting: true,
- entryNames: "main/[ext]/[name]-[hash].[ext]",
});
+ // itBundled("default/EntryNamesNonPortableCharacter", {
+ // // GENERATED
+ // // TODO: I think this is impossible with the CLI. and also very unsafe with paths.
+ // files: {
+ // "/entry1-*.ts": `console.log(1)`,
+ // "/entry2-*.ts": `console.log(2)`,
+ // },
+ // entryPointsAdvanced: [
+ // // The "*" should turn into "_" for cross-platform Windows portability
+ // { input: "/entry1-*.ts" },
+ // // The "*" should be preserved since the user _really_ wants it
+ // { input: "/entry2-*.ts", output: "entry2-*" },
+ // ],
+ // mode: "passthrough",
+ // });
+ // itBundled("default/EntryNamesChunkNamesExtPlaceholder", {
+ // files: {
+ // "/src/entries/entry1.js": `import "../lib/shared.js"; import "./entry1.css"; console.log('entry1')`,
+ // "/src/entries/entry2.js": `import "../lib/shared.js"; import "./entry2.css"; console.log('entry2')`,
+ // "/src/entries/entry1.css": `a:after { content: "entry1" }`,
+ // "/src/entries/entry2.css": `a:after { content: "entry2" }`,
+ // "/src/lib/shared.js": `console.log('shared')`,
+ // },
+ // entryPoints: ["/src/entries/entry1.js", "/src/entries/entry2.js"],
+ // outbase: "/src",
+ // splitting: true,
+ // entryNames: "main/[ext]/[name]-[hash].[ext]",
+ // });
itBundled("default/MinifyIdentifiersImportPathFrequencyAnalysis", {
- // GENERATED
files: {
"/import.js": /* js */ `
import foo from "./WWWWWWWWWWXXXXXXXXXXYYYYYYYYYYZZZZZZZZZZ"
- console.log(foo, 'no identifier in this file should be named W, X, Y, or Z')
+ console.log(foo, remove('no identifier in this file should be named W, X, Y, or Z'))
`,
"/WWWWWWWWWWXXXXXXXXXXYYYYYYYYYYZZZZZZZZZZ.js": `export default 123`,
"/require.js": /* js */ `
const foo = require("./AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDD")
- console.log(foo, 'no identifier in this file should be named A, B, C, or D')
+ console.log(foo, remove('no identifier in this file should be named A, B, C, or D'))
`,
"/AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDD.js": `module.exports = 123`,
},
entryPoints: ["/import.js", "/require.js"],
minifyWhitespace: true,
+ minifyIdentifiers: true,
+ onAfterBundle(api) {
+ let importFile = api.readFile("/out/import.js").replace(/remove\(.*?\)/g, "remove()");
+ let requireFile = api.readFile("/out/require.js").replace(/remove\(.*?\)/g, "remove()");
+ assert(!["W", "X", "Y", "Z"].some(x => importFile.includes(x)));
+ assert(!["A", "B", "C", "D"].some(x => requireFile.includes(x)));
+ },
});
itBundled("default/ToESMWrapperOmission", {
// GENERATED
@@ -5260,67 +5392,19 @@ describe("bundler", () => {
`,
},
format: "cjs",
- mode: "convertformat",
+ external: ["*"],
});
itBundled("default/NamedFunctionExpressionArgumentCollision", {
- // GENERATED
files: {
"/entry.js": /* js */ `
let x = function foo(foo) {
var foo;
return foo;
}
+ console.log(x(123))
`,
},
- mode: "passthrough",
- });
- itBundled("default/NoWarnCommonJSExportsInESMPassThrough", {
- // GENERATED
- files: {
- "/cjs-in-esm.js": /* js */ `
- export let foo = 1
- exports.foo = 2
- module.exports = 3
- `,
- "/import-in-cjs.js": /* js */ `
- import { foo } from 'bar'
- exports.foo = foo
- module.exports = foo
- `,
- "/no-warnings-here.js": `console.log(module, exports)`,
- },
- entryPoints: ["/cjs-in-esm.js", "/import-in-cjs.js", "/no-warnings-here.js"],
- mode: "passthrough",
- });
- itBundled("default/WarnCommonJSExportsInESMConvert", {
- // GENERATED
- files: {
- "/cjs-in-esm.js": /* js */ `
- export let foo = 1
- exports.foo = 2
- module.exports = 3
- `,
- "/cjs-in-esm2.js": /* js */ `
- export let foo = 1
- module.exports.bar = 3
- `,
- "/import-in-cjs.js": /* js */ `
- import { foo } from 'bar'
- exports.foo = foo
- module.exports = foo
- module.exports.bar = foo
- `,
- "/no-warnings-here.js": `console.log(module, exports)`,
- },
- entryPoints: ["/cjs-in-esm.js", "/cjs-in-esm2.js", "/import-in-cjs.js", "/no-warnings-here.js"],
- mode: "convertformat",
- /* TODO FIX expectedScanLog: `cjs-in-esm.js: WARNING: The CommonJS "exports" variable is treated as a global variable in an ECMAScript module and may not work as expected
- cjs-in-esm.js: NOTE: This file is considered to be an ECMAScript module because of the "export" keyword here:
- cjs-in-esm.js: WARNING: The CommonJS "module" variable is treated as a global variable in an ECMAScript module and may not work as expected
- cjs-in-esm.js: NOTE: This file is considered to be an ECMAScript module because of the "export" keyword here:
- cjs-in-esm2.js: WARNING: The CommonJS "module" variable is treated as a global variable in an ECMAScript module and may not work as expected
- cjs-in-esm2.js: NOTE: This file is considered to be an ECMAScript module because of the "export" keyword here:
- `, */
+ minifySyntax: true,
});
itBundled("default/WarnCommonJSExportsInESMBundle", {
// GENERATED
@@ -5344,6 +5428,7 @@ describe("bundler", () => {
cjs-in-esm.js: WARNING: The CommonJS "module" variable is treated as a global variable in an ECMAScript module and may not work as expected
cjs-in-esm.js: NOTE: This file is considered to be an ECMAScript module because of the "export" keyword here:
`, */
+ external: ["bar"],
});
itBundled("default/MangleProps", {
// GENERATED
@@ -5389,7 +5474,8 @@ describe("bundler", () => {
`,
},
entryPoints: ["/entry1.js", "/entry2.js"],
- mode: "passthrough",
+ external: ["*"],
+ mangleProps: /_$/,
});
itBundled("default/ManglePropsMinify", {
// GENERATED
@@ -5437,7 +5523,7 @@ describe("bundler", () => {
entryPoints: ["/entry1.js", "/entry2.js"],
mangleProps: /_$/,
minifyIdentifiers: true,
- mode: "passthrough",
+ external: ["*"],
});
itBundled("default/ManglePropsKeywordPropertyMinify", {
// GENERATED
@@ -5451,7 +5537,7 @@ describe("bundler", () => {
mangleProps: /./,
minifyIdentifiers: true,
minifySyntax: true,
- mode: "passthrough",
+ external: ["*"],
});
itBundled("default/ManglePropsOptionalChain", {
// GENERATED
@@ -5469,7 +5555,8 @@ describe("bundler", () => {
}
`,
},
- mode: "passthrough",
+ mangleProps: /_$/,
+ external: ["*"],
});
itBundled("default/ManglePropsLoweredOptionalChain", {
// GENERATED
@@ -5488,7 +5575,7 @@ describe("bundler", () => {
`,
},
mangleProps: /_$/,
- mode: "passthrough",
+ external: ["*"],
});
itBundled("default/ReserveProps", {
// GENERATED
@@ -5501,7 +5588,7 @@ describe("bundler", () => {
`,
},
mangleProps: /_$/,
- mode: "passthrough",
+ external: ["*"],
});
itBundled("default/ManglePropsImportExport", {
// GENERATED
@@ -5516,7 +5603,8 @@ describe("bundler", () => {
`,
},
entryPoints: ["/esm.js", "/cjs.js"],
- mode: "passthrough",
+ mangleProps: /_$/,
+ external: ["*"],
});
itBundled("default/ManglePropsImportExportBundled", {
// GENERATED
@@ -5545,9 +5633,11 @@ describe("bundler", () => {
"/cjs.js": `exports.cjs_foo_ = 'foo'`,
},
entryPoints: ["/entry-esm.js", "/entry-cjs.js"],
+ mangleProps: /_$/,
});
itBundled("default/ManglePropsJSXTransform", {
// GENERATED
+ notImplemented: true,
files: {
"/entry.jsx": /* jsx */ `
let Foo = {
@@ -5566,10 +5656,10 @@ describe("bundler", () => {
`,
},
mangleProps: /_$/,
- mode: "passthrough",
});
itBundled("default/ManglePropsJSXPreserve", {
// GENERATED
+ notImplemented: true,
files: {
"/entry.jsx": /* jsx */ `
let Foo = {
@@ -5583,10 +5673,10 @@ describe("bundler", () => {
},
outfile: "/out.jsx",
mangleProps: /_$/,
- mode: "passthrough",
});
itBundled("default/ManglePropsJSXTransformNamespace", {
// GENERATED
+ notImplemented: true,
files: {
"/entry.jsx": /* jsx */ `
export default [
@@ -5596,10 +5686,8 @@ describe("bundler", () => {
]
`,
},
- mode: "passthrough",
});
itBundled("default/ManglePropsAvoidCollisions", {
- // GENERATED
files: {
"/entry.js": /* js */ `
export default {
@@ -5611,10 +5699,9 @@ describe("bundler", () => {
}
`,
},
- mode: "passthrough",
+ mangleProps: /_$/,
});
itBundled("default/ManglePropsTypeScriptFeatures", {
- // GENERATED
files: {
"/parameter-properties.ts": /* ts */ `
class Foo {
@@ -5694,10 +5781,9 @@ describe("bundler", () => {
`,
},
entryPoints: ["/parameter-properties.ts", "/namespace-exports.ts", "/enum-values.ts"],
- mode: "passthrough",
+ mangleProps: /_$/,
});
itBundled("default/ManglePropsShorthand", {
- // GENERATED
files: {
"/entry.js": /* js */ `
// This should print as "({ y }) => ({ y })" not "({ y: y }) => ({ y: y })"
@@ -5705,10 +5791,8 @@ describe("bundler", () => {
`,
},
mangleProps: /x/,
- mode: "passthrough",
});
itBundled("default/ManglePropsNoShorthand", {
- // GENERATED
files: {
"/entry.js": /* js */ `
// This should print as "({ y }) => ({ y: y })" not "({ y: y }) => ({ y: y })"
@@ -5717,10 +5801,8 @@ describe("bundler", () => {
},
mangleProps: /x/,
minifyIdentifiers: true,
- mode: "passthrough",
});
itBundled("default/ManglePropsLoweredClassFields", {
- // GENERATED
files: {
"/entry.js": /* js */ `
class Foo {
@@ -5731,10 +5813,9 @@ describe("bundler", () => {
`,
},
mangleProps: /_$/,
- mode: "passthrough",
+ unsupportedJSFeatures: ["class-field", "class-static-field"],
});
itBundled("default/ManglePropsSuperCall", {
- // GENERATED
files: {
"/entry.js": /* js */ `
class Foo {}
@@ -5745,10 +5826,9 @@ describe("bundler", () => {
}
`,
},
- mode: "passthrough",
+ mangleProps: /./,
});
itBundled("default/MangleNoQuotedProps", {
- // GENERATED
files: {
"/entry.js": /* js */ `
x['_doNotMangleThis'];
@@ -5766,7 +5846,7 @@ describe("bundler", () => {
`,
},
mangleProps: /_/,
- mode: "passthrough",
+ mangleQuoted: false,
});
itBundled("default/MangleNoQuotedPropsMinifySyntax", {
// GENERATED
@@ -5788,10 +5868,9 @@ describe("bundler", () => {
},
mangleProps: /_/,
mangleQuoted: false,
- mode: "passthrough",
+ minifySyntax: true,
});
itBundled("default/MangleQuotedProps", {
- // GENERATED
files: {
"/keep.js": /* js */ `
foo("_keepThisProperty");
@@ -5830,10 +5909,9 @@ describe("bundler", () => {
},
entryPoints: ["/keep.js", "/mangle.js"],
mangleProps: /_/,
- mode: "passthrough",
+ mangleQuoted: true,
});
itBundled("default/MangleQuotedPropsMinifySyntax", {
- // GENERATED
files: {
"/keep.js": /* js */ `
foo("_keepThisProperty");
@@ -5873,42 +5951,42 @@ describe("bundler", () => {
entryPoints: ["/keep.js", "/mangle.js"],
mangleProps: /_/,
mangleQuoted: true,
- mode: "passthrough",
- });
- itBundled("default/IndirectRequireMessage", {
- // GENERATED
- files: {
- "/array.js": `let x = [require]`,
- "/assign.js": `require = x`,
- "/ident.js": `let x = require`,
- "/dot.js": `let x = require.cache`,
- "/index.js": `let x = require[cache]`,
- },
- entryPoints: ["/array.js", "/assign.js", "/dot.js", "/ident.js", "/index.js"],
- /* TODO FIX expectedScanLog: `array.js: DEBUG: Indirect calls to "require" will not be bundled
- assign.js: DEBUG: Indirect calls to "require" will not be bundled
- ident.js: DEBUG: Indirect calls to "require" will not be bundled
- `, */
- });
- itBundled("default/AmbiguousReexportMsg", {
- // GENERATED
- files: {
- "/entry.js": /* js */ `
- export * from './a'
- export * from './b'
- export * from './c'
- `,
- "/a.js": `export let a = 1, x = 2`,
- "/b.js": `export let b = 3; export { b as x }`,
- "/c.js": `export let c = 4, x = 5`,
- },
- /* TODO FIX expectedCompileLog: `DEBUG: Re-export of "x" in "entry.js" is ambiguous and has been removed
- a.js: NOTE: One definition of "x" comes from "a.js" here:
- b.js: NOTE: Another definition of "x" comes from "b.js" here:
- `, */
+ minifySyntax: true,
});
+ // we dont check debug messages
+ // itBundled("default/IndirectRequireMessage", {
+ // // GENERATED
+ // files: {
+ // "/array.js": `let x = [require]`,
+ // "/assign.js": `require = x`,
+ // "/ident.js": `let x = require`,
+ // "/dot.js": `let x = require.cache`,
+ // "/index.js": `let x = require[cache]`,
+ // },
+ // entryPoints: ["/array.js", "/assign.js", "/dot.js", "/ident.js", "/index.js"],
+ // /* TODO FIX expectedScanLog: `array.js: DEBUG: Indirect calls to "require" will not be bundled
+ // assign.js: DEBUG: Indirect calls to "require" will not be bundled
+ // ident.js: DEBUG: Indirect calls to "require" will not be bundled
+ // `, */
+ // });
+ // itBundled("default/AmbiguousReexportMsg", {
+ // // GENERATED
+ // files: {
+ // "/entry.js": /* js */ `
+ // export * from './a'
+ // export * from './b'
+ // export * from './c'
+ // `,
+ // "/a.js": `export let a = 1, x = 2`,
+ // "/b.js": `export let b = 3; export { b as x }`,
+ // "/c.js": `export let c = 4, x = 5`,
+ // },
+ // /* TODO FIX expectedCompileLog: `DEBUG: Re-export of "x" in "entry.js" is ambiguous and has been removed
+ // a.js: NOTE: One definition of "x" comes from "a.js" here:
+ // b.js: NOTE: Another definition of "x" comes from "b.js" here:
+ // `, */
+ // });
itBundled("default/NonDeterminismESBuildIssue2537", {
- // GENERATED
files: {
"/entry.ts": /* ts */ `
export function aap(noot: boolean, wim: number) {
@@ -5933,35 +6011,40 @@ describe("bundler", () => {
}
`,
},
+ minifyIdentifiers: true,
});
- itBundled("default/MinifiedJSXPreserveWithObjectSpread", {
- // GENERATED
- files: {
- "/entry.jsx": /* jsx */ `
- const obj = {
- before,
- ...{ [key]: value },
- ...{ key: value },
- after,
- };
- <Foo
- before
- {...{ [key]: value }}
- {...{ key: value }}
- after
- />;
- <Bar
- {...{
- a,
- [b]: c,
- ...d,
- e,
- }}
- />;
- `,
- },
- minifySyntax: true,
- });
+ // itBundled("default/MinifiedJSXPreserveWithObjectSpread", {
+ // // GENERATED
+ // files: {
+ // "/entry.jsx": /* jsx */ `
+ // const obj = {
+ // before,
+ // ...{ [key]: value },
+ // ...{ key: value },
+ // after,
+ // };
+ // <Foo
+ // before
+ // {...{ [key]: value }}
+ // {...{ key: value }}
+ // after
+ // />;
+ // <Bar
+ // {...{
+ // a,
+ // [b]: c,
+ // ...d,
+ // e,
+ // }}
+ // />;
+ // `,
+ // },
+ // jsx: {
+ // // preserve: true,
+ // },
+ // // minifySyntax: true,
+ // external: ["*"],
+ // });
itBundled("default/PackageAlias", {
files: {
"/entry.js": /* js */ `
@@ -5991,22 +6074,21 @@ describe("bundler", () => {
"/node_modules/prefix-foo/index.js": `console.log(10)`,
"/node_modules/@scope/prefix-foo/index.js": `console.log(11)`,
},
- bundleErrors: {
- "/entry.js": [
- 'Could not resolve: "pkg1". Maybe you need to "bun install"?',
- 'Could not resolve: "pkg2/foo". Maybe you need to "bun install"?',
- 'Could not resolve: "@scope/pkg4". Maybe you need to "bun install"?',
- 'Could not resolve: "@scope/pkg5/foo". Maybe you need to "bun install"?',
- 'Could not resolve: "@abs-path/pkg6". Maybe you need to "bun install"?',
- 'Could not resolve: "@abs-path/pkg6/foo". Maybe you need to "bun install"?',
- 'Could not resolve: "@scope-only/pkg8". Maybe you need to "bun install"?',
- 'Could not resolve: "slash/" Maybe. you need to "bun install"?',
- 'Could not resolve: "pkg3". Maybe you need to "bun install"?',
- ],
+ alias: {
+ "pkg1": "alias1",
+ "pkg2": "alias2",
+ "pkg3": "alias3",
+ "@scope/pkg4": "alias4",
+ "@scope/pkg5": "alias5",
+ "@abs-path/pkg6": `/alias6/dir`,
+ "@abs-path/pkg7": `/alias7/dir`,
+ "@scope-only": "/alias8/dir",
+ "slash": "/alias9/some/file.js",
+ "prefix": "alias10",
+ "@scope/prefix": "alias11",
},
});
itBundled("default/PackageAliasMatchLongest", {
- // GENERATED
files: {
"/entry.js": /* js */ `
import "pkg"
@@ -6023,100 +6105,101 @@ describe("bundler", () => {
"pkg/foo/bar": "alias/pkg_foo_bar",
},
});
- itBundled("default/ErrorsForAssertTypeJSON", {
- // GENERATED
- files: {
- "/js-entry.js": /* js */ `
- import all from './foo.json' assert { type: 'json' }
- import { default as def } from './foo.json' assert { type: 'json' }
- import { unused } from './foo.json' assert { type: 'json' }
- import { used } from './foo.json' assert { type: 'json' }
- import * as ns from './foo.json' assert { type: 'json' }
- use(used, ns.prop)
- export { exported } from './foo.json' assert { type: 'json' }
- import text from './foo.text' assert { type: 'json' }
- import file from './foo.file' assert { type: 'json' }
- import copy from './foo.copy' assert { type: 'json' }
- `,
- "/ts-entry.ts": /* ts */ `
- import all from './foo.json' assert { type: 'json' }
- import { default as def } from './foo.json' assert { type: 'json' }
- import { unused } from './foo.json' assert { type: 'json' }
- import { used } from './foo.json' assert { type: 'json' }
- import * as ns from './foo.json' assert { type: 'json' }
- use(used, ns.prop)
- export { exported } from './foo.json' assert { type: 'json' }
- import text from './foo.text' assert { type: 'json' }
- import file from './foo.file' assert { type: 'json' }
- import copy from './foo.copy' assert { type: 'json' }
- `,
- "/foo.json": `{}`,
- "/foo.text": `{}`,
- "/foo.file": `{}`,
- "/foo.copy": `{}`,
- },
- entryPoints: ["/js-entry.js", "/ts-entry.ts"],
- /* TODO FIX expectedScanLog: `js-entry.js: ERROR: Cannot use non-default import "unused" with a standard JSON module
- js-entry.js: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
- NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "unused" import (which is non-standard behavior).
- js-entry.js: ERROR: Cannot use non-default import "used" with a standard JSON module
- js-entry.js: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
- NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "used" import (which is non-standard behavior).
- js-entry.js: WARNING: Non-default import "prop" is undefined with a standard JSON module
- js-entry.js: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
- NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "prop" import (which is non-standard behavior).
- js-entry.js: ERROR: Cannot use non-default import "exported" with a standard JSON module
- js-entry.js: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
- NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "exported" import (which is non-standard behavior).
- js-entry.js: ERROR: The file "foo.text" was loaded with the "text" loader
- js-entry.js: NOTE: This import assertion requires the loader to be "json" instead:
- NOTE: You need to either reconfigure esbuild to ensure that the loader for this file is "json" or you need to remove this import assertion.
- js-entry.js: ERROR: The file "foo.file" was loaded with the "file" loader
- js-entry.js: NOTE: This import assertion requires the loader to be "json" instead:
- NOTE: You need to either reconfigure esbuild to ensure that the loader for this file is "json" or you need to remove this import assertion.
- ts-entry.ts: ERROR: Cannot use non-default import "used" with a standard JSON module
- ts-entry.ts: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
- NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "used" import (which is non-standard behavior).
- ts-entry.ts: WARNING: Non-default import "prop" is undefined with a standard JSON module
- ts-entry.ts: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
- NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "prop" import (which is non-standard behavior).
- ts-entry.ts: ERROR: Cannot use non-default import "exported" with a standard JSON module
- ts-entry.ts: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
- NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "exported" import (which is non-standard behavior).
- `, */
- });
- itBundled("default/OutputForAssertTypeJSON", {
- // GENERATED
- files: {
- "/js-entry.js": /* js */ `
- import all from './foo.json' assert { type: 'json' }
- import copy from './foo.copy' assert { type: 'json' }
- import { default as def } from './foo.json' assert { type: 'json' }
- import * as ns from './foo.json' assert { type: 'json' }
- use(all, copy, def, ns.prop)
- export { default } from './foo.json' assert { type: 'json' }
- `,
- "/ts-entry.ts": /* ts */ `
- import all from './foo.json' assert { type: 'json' }
- import copy from './foo.copy' assert { type: 'json' }
- import { default as def } from './foo.json' assert { type: 'json' }
- import { unused } from './foo.json' assert { type: 'json' }
- import * as ns from './foo.json' assert { type: 'json' }
- use(all, copy, def, ns.prop)
- export { default } from './foo.json' assert { type: 'json' }
- `,
- "/foo.json": `{}`,
- "/foo.copy": `{}`,
- },
- entryPoints: ["/js-entry.js", "/ts-entry.ts"],
- /* TODO FIX expectedScanLog: `js-entry.js: WARNING: Non-default import "prop" is undefined with a standard JSON module
- js-entry.js: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
- NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "prop" import (which is non-standard behavior).
- ts-entry.ts: WARNING: Non-default import "prop" is undefined with a standard JSON module
- ts-entry.ts: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
- NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "prop" import (which is non-standard behavior).
- `, */
- });
+ // itBundled("default/ErrorsForAssertTypeJSON", {
+ // notImplemented: true,
+ // files: {
+ // "/js-entry.js": /* js */ `
+ // import all from './foo.json' assert { type: 'json' }
+ // import { default as def } from './foo.json' assert { type: 'json' }
+ // import { unused } from './foo.json' assert { type: 'json' }
+ // import { used } from './foo.json' assert { type: 'json' }
+ // import * as ns from './foo.json' assert { type: 'json' }
+ // use(used, ns.prop)
+ // export { exported } from './foo.json' assert { type: 'json' }
+ // import text from './foo.text' assert { type: 'json' }
+ // import file from './foo.file' assert { type: 'json' }
+ // import copy from './foo.copy' assert { type: 'json' }
+ // `,
+ // "/ts-entry.ts": /* ts */ `
+ // import all from './foo.json' assert { type: 'json' }
+ // import { default as def } from './foo.json' assert { type: 'json' }
+ // import { unused } from './foo.json' assert { type: 'json' }
+ // import { used } from './foo.json' assert { type: 'json' }
+ // import * as ns from './foo.json' assert { type: 'json' }
+ // use(used, ns.prop)
+ // export { exported } from './foo.json' assert { type: 'json' }
+ // import text from './foo.text' assert { type: 'json' }
+ // import file from './foo.file' assert { type: 'json' }
+ // import copy from './foo.copy' assert { type: 'json' }
+ // `,
+ // "/foo.json": `{ "used": 0, "unused": 0, "prop": 0, "exported": 0 }`,
+ // "/foo.text": `{ "used": 0, "unused": 0, "prop": 0, "exported": 0 }`,
+ // "/foo.file": `{ "used": 0, "unused": 0, "prop": 0, "exported": 0 }`,
+ // "/foo.copy": `{ "used": 0, "unused": 0, "prop": 0, "exported": 0 }`,
+ // },
+ // entryPoints: ["/js-entry.js", "/ts-entry.ts"],
+ // /* TODO FIX expectedScanLog: `js-entry.js: ERROR: Cannot use non-default import "unused" with a standard JSON module
+ // js-entry.js: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
+ // NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "unused" import (which is non-standard behavior).
+ // js-entry.js: ERROR: Cannot use non-default import "used" with a standard JSON module
+ // js-entry.js: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
+ // NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "used" import (which is non-standard behavior).
+ // js-entry.js: WARNING: Non-default import "prop" is undefined with a standard JSON module
+ // js-entry.js: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
+ // NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "prop" import (which is non-standard behavior).
+ // js-entry.js: ERROR: Cannot use non-default import "exported" with a standard JSON module
+ // js-entry.js: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
+ // NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "exported" import (which is non-standard behavior).
+ // js-entry.js: ERROR: The file "foo.text" was loaded with the "text" loader
+ // js-entry.js: NOTE: This import assertion requires the loader to be "json" instead:
+ // NOTE: You need to either reconfigure esbuild to ensure that the loader for this file is "json" or you need to remove this import assertion.
+ // js-entry.js: ERROR: The file "foo.file" was loaded with the "file" loader
+ // js-entry.js: NOTE: This import assertion requires the loader to be "json" instead:
+ // NOTE: You need to either reconfigure esbuild to ensure that the loader for this file is "json" or you need to remove this import assertion.
+ // ts-entry.ts: ERROR: Cannot use non-default import "used" with a standard JSON module
+ // ts-entry.ts: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
+ // NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "used" import (which is non-standard behavior).
+ // ts-entry.ts: WARNING: Non-default import "prop" is undefined with a standard JSON module
+ // ts-entry.ts: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
+ // NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "prop" import (which is non-standard behavior).
+ // ts-entry.ts: ERROR: Cannot use non-default import "exported" with a standard JSON module
+ // ts-entry.ts: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
+ // NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "exported" import (which is non-standard behavior).
+ // `, */
+ // });
+ // itBundled("default/OutputForAssertTypeJSON", {
+ // // GENERATED
+ // files: {
+ // "/js-entry.js": /* js */ `
+ // import all from './foo.json' assert { type: 'json' }
+ // import copy from './foo.copy' assert { type: 'json' }
+ // import { default as def } from './foo.json' assert { type: 'json' }
+ // import * as ns from './foo.json' assert { type: 'json' }
+ // use(all, copy, def, ns.prop)
+ // export { default } from './foo.json' assert { type: 'json' }
+ // `,
+ // "/ts-entry.ts": /* ts */ `
+ // import all from './foo.json' assert { type: 'json' }
+ // import copy from './foo.copy' assert { type: 'json' }
+ // import { default as def } from './foo.json' assert { type: 'json' }
+ // import { unused } from './foo.json' assert { type: 'json' }
+ // import * as ns from './foo.json' assert { type: 'json' }
+ // use(all, copy, def, ns.prop)
+ // export { default } from './foo.json' assert { type: 'json' }
+ // `,
+ // "/foo.json": `{}`,
+ // "/foo.copy": `{}`,
+ // },
+ // entryPoints: ["/js-entry.js", "/ts-entry.ts"],
+ // /* TODO FIX expectedScanLog: `js-entry.js: WARNING: Non-default import "prop" is undefined with a standard JSON module
+ // js-entry.js: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
+ // NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "prop" import (which is non-standard behavior).
+ // ts-entry.ts: WARNING: Non-default import "prop" is undefined with a standard JSON module
+ // ts-entry.ts: NOTE: This is considered an import of a standard JSON module because of the import assertion here:
+ // NOTE: You can either keep the import assertion and only use the "default" import, or you can remove the import assertion and use the "prop" import (which is non-standard behavior).
+ // `, */
+ // });
+ return;
itBundled("default/ExternalPackages", {
// GENERATED
files: {
diff --git a/test/bundler/esbuild/lower.test.ts b/test/bundler/esbuild/lower.test.ts
index d03c4a27f..df68a6f51 100644
--- a/test/bundler/esbuild/lower.test.ts
+++ b/test/bundler/esbuild/lower.test.ts
@@ -1,4 +1,4 @@
-import { RUN_UNCHECKED_TESTS, itBundled, testForFile } from "../expectBundled";
+import { itBundled, testForFile } from "../expectBundled";
var { describe, test, expect } = testForFile(import.meta.path);
// Tests ported from:
@@ -7,7 +7,7 @@ var { describe, test, expect } = testForFile(import.meta.path);
// For debug, all files are written to $TEMP/bun-bundle-tests/lower
describe("bundler", () => {
- if (!RUN_UNCHECKED_TESTS) return;
+ return;
itBundled("lower/LowerOptionalCatchNameCollisionNoBundle", {
// GENERATED
files: {
diff --git a/test/bundler/esbuild/ts.test.ts b/test/bundler/esbuild/ts.test.ts
index a3b3ce925..2eb894cfe 100644
--- a/test/bundler/esbuild/ts.test.ts
+++ b/test/bundler/esbuild/ts.test.ts
@@ -1470,7 +1470,6 @@ describe("bundler", () => {
},
});
itBundled("ts/ThisInsideFunctionTSNoBundleUseDefineForClassFields", {
- // GENERATED
files: {
"/entry.ts": /* ts */ `
function foo(x = this) { return [x, this]; }
diff --git a/test/bundler/expectBundled.ts b/test/bundler/expectBundled.ts
index e625cb500..e029787c8 100644
--- a/test/bundler/expectBundled.ts
+++ b/test/bundler/expectBundled.ts
@@ -27,7 +27,7 @@ export function testForFile(file: string): BunTestExports {
}
/** Use `esbuild` instead of `bun build` */
-const ESBUILD = process.env.BUN_BUNDLER_TEST_USE_ESBUILD;
+export const ESBUILD = process.env.BUN_BUNDLER_TEST_USE_ESBUILD;
/** Write extra files to disk and log extra info. */
const DEBUG = process.env.BUN_BUNDLER_TEST_DEBUG;
/** Set this to the id of a bundle test to run just that test */
@@ -95,6 +95,7 @@ export interface BundlerTestInput {
fragment?: string;
automaticRuntime?: boolean;
development?: boolean;
+ preserve?: boolean;
};
outbase?: string;
/** Defaults to `/out.js` */
@@ -392,7 +393,7 @@ function expectBundled(
const entryPaths = entryPoints.map(file => path.join(root, file));
if (external) {
- external = external.map(x => x.replace(/\{\{root\}\}/g, root));
+ external = external.map(x => (typeof x !== "string" ? x : x.replace(/\{\{root\}\}/g, root)));
}
outfile = useOutFile ? path.join(root, outfile ?? "/out.js") : undefined;
@@ -404,7 +405,7 @@ function expectBundled(
: entryPaths.map(file => path.join(outdir!, path.basename(file)))
).map(x => x.replace(/\.ts$/, ".js"));
- if (mode === "transform" && !outfile) {
+ if (mode === "transform" && !outfile && !ESBUILD) {
throw new Error("transform mode requires one single outfile");
}
if (cjs2esm && !outfile && !minifySyntax && !minifyWhitespace) {
@@ -475,6 +476,7 @@ function expectBundled(
minifyWhitespace && `--minify-whitespace`,
globalName && `--global-name=${globalName}`,
// inject && inject.map(x => ["--inject", path.join(root, x)]),
+ jsx.preserve && "--jsx=preserve",
jsx.automaticRuntime === false && "--jsx=classic",
jsx.factory && `--jsx-factory=${jsx.factory}`,
jsx.fragment && `--jsx-fragment=${jsx.fragment}`,
@@ -508,6 +510,7 @@ function expectBundled(
inject && inject.map(x => `--inject:${path.join(root, x)}`),
define && Object.entries(define).map(([k, v]) => `--define:${k}=${v}`),
jsx.automaticRuntime && "--jsx=automatic",
+ jsx.preserve && "--jsx=preserve",
jsx.factory && `--jsx-factory=${jsx.factory}`,
jsx.fragment && `--jsx-fragment=${jsx.fragment}`,
jsx.development && `--jsx-dev`,
@@ -579,7 +582,7 @@ function expectBundled(
}
}
- const { stdout, stderr, success } = Bun.spawnSync({
+ const { stdout, stderr, success, exitCode } = Bun.spawnSync({
cmd,
cwd: root,
stdio: ["ignore", "pipe", "pipe"],
@@ -785,6 +788,7 @@ function expectBundled(
writeFileSync(path.join(root, "run.js"), debugFile);
} else {
console.log("TODO: generate run.js, currently only works if options are wrapped in a function");
+ console.log("options:", buildConfig);
}
}