From b23bee397b3e55d13b2c6c0e302caafdc3288bd9 Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Sun, 6 Sep 2020 00:57:22 -0700 Subject: [PATCH] fix #109: allow "--format" without "--bundle" --- CHANGELOG.md | 46 +++ internal/bundler/bundler.go | 8 +- internal/bundler/bundler_dce_test.go | 52 +-- internal/bundler/bundler_default_test.go | 297 ++++++++++------- internal/bundler/bundler_importstar_test.go | 108 +++---- .../bundler/bundler_importstar_ts_test.go | 38 +-- internal/bundler/bundler_loader_test.go | 80 ++++- internal/bundler/bundler_lower_test.go | 50 +-- internal/bundler/bundler_splitting_test.go | 34 +- internal/bundler/bundler_ts_test.go | 48 +-- internal/bundler/bundler_tsconfig_test.go | 30 +- internal/bundler/linker.go | 17 +- .../bundler/snapshots/snapshots_default.txt | 14 + .../bundler/snapshots/snapshots_loader.txt | 30 ++ internal/config/config.go | 25 +- internal/parser/parser.go | 101 +++--- internal/parser/parser_lower.go | 15 +- lib/common.ts | 4 +- lib/types.ts | 4 +- pkg/api/api.go | 10 +- pkg/api/api_impl.go | 20 +- pkg/cli/cli_impl.go | 28 +- scripts/end-to-end-tests.js | 304 +++++++++++++++++- scripts/js-api-tests.js | 10 + 24 files changed, 951 insertions(+), 422 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8965a36ea6..937ca190bc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,52 @@ ## Unreleased +* Allow `--format` when bundling is disabled ([#109](https://github.com/evanw/esbuild/issues/109)) + + This change means esbuild can be used to convert ES6 import and export syntax to CommonJS syntax. The following code: + + ```js + import foo from 'foo' + export const bar = foo + ``` + + will be transformed into the following code with `--format=cjs` (the code for `__export` and `__toModule` was omitted for brevity): + + ```js + __export(exports, { + bar: () => bar + }); + const foo = __toModule(require("foo")); + const bar = foo.default; + ``` + + This also applies to non-JavaScript loaders too. The following JSON: + + ```json + {"foo": true, "bar": false} + ``` + + is normally converted to the following code with `--loader=json`: + + ```js + module.exports = {foo: true, bar: false}; + ``` + + but will be transformed into the following code instead with `--loader=json --format=esm`: + + ```js + var foo = true; + var bar = false; + var stdin_default = {foo, bar}; + export { + bar, + stdin_default as default, + foo + }; + ``` + + Note that converting CommonJS `require()` calls to ES6 imports is not currently supported. Code containing a reference to `require` in these situations will generate a warning. + * Remove trailing `()` from `new` when minifying Now `new Foo()` will be printed as `new Foo` when minifying (as long as it's safe to do so), resulting in slightly shorter minified code. diff --git a/internal/bundler/bundler.go b/internal/bundler/bundler.go index c09045be26a..7f0ef1abcb3 100644 --- a/internal/bundler/bundler.go +++ b/internal/bundler/bundler.go @@ -256,7 +256,7 @@ func parseFile(args parseArgs) { // Run the resolver on the parse thread so it's not run on the main thread. // That way the main thread isn't blocked if the resolver takes a while. - if args.options.IsBundling { + if args.options.Mode == config.ModeBundle { result.resolveResults = make([]*resolver.ResolveResult, len(result.file.ast.ImportRecords)) if len(result.file.ast.ImportRecords) > 0 { @@ -536,7 +536,7 @@ func ScanBundle(log logging.Log, fs fs.FS, res resolver.Resolver, entryPaths []s } // Don't try to resolve paths if we're not bundling - if options.IsBundling { + if options.Mode == config.ModeBundle { for _, part := range result.file.ast.Parts { for _, importRecordIndex := range part.ImportRecordIndices { record := &result.file.ast.ImportRecords[importRecordIndex] @@ -647,7 +647,7 @@ func (b *Bundle) Compile(log logging.Log, options config.Options) []OutputFile { } // The format can't be "preserve" while bundling - if options.IsBundling && options.OutputFormat == config.FormatPreserve { + if options.Mode == config.ModeBundle && options.OutputFormat == config.FormatPreserve { options.OutputFormat = config.FormatESModule } @@ -928,7 +928,7 @@ func (cache *runtimeCache) parseRuntime(options *config.Options) (source logging // Always do tree shaking for the runtime because we never want to // include unnecessary runtime code - IsBundling: true, + Mode: config.ModeBundle, }) if log.HasErrors() { panic("Internal error: failed to parse runtime") diff --git a/internal/bundler/bundler_dce_test.go b/internal/bundler/bundler_dce_test.go index 956ac48fe1d..dbf2b6b9d59 100644 --- a/internal/bundler/bundler_dce_test.go +++ b/internal/bundler/bundler_dce_test.go @@ -29,7 +29,7 @@ func TestPackageJsonSideEffectsFalseKeepNamedImportES6(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -54,7 +54,7 @@ func TestPackageJsonSideEffectsFalseKeepNamedImportCommonJS(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -79,7 +79,7 @@ func TestPackageJsonSideEffectsFalseKeepStarImportES6(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -104,7 +104,7 @@ func TestPackageJsonSideEffectsFalseKeepStarImportCommonJS(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -129,7 +129,7 @@ func TestPackageJsonSideEffectsTrueKeepES6(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -154,7 +154,7 @@ func TestPackageJsonSideEffectsTrueKeepCommonJS(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -180,7 +180,7 @@ func TestPackageJsonSideEffectsFalseKeepBareImportAndRequireES6(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -206,7 +206,7 @@ func TestPackageJsonSideEffectsFalseKeepBareImportAndRequireCommonJS(t *testing. }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -231,7 +231,7 @@ func TestPackageJsonSideEffectsFalseRemoveBareImportES6(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -256,7 +256,7 @@ func TestPackageJsonSideEffectsFalseRemoveBareImportCommonJS(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -281,7 +281,7 @@ func TestPackageJsonSideEffectsFalseRemoveNamedImportES6(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -306,7 +306,7 @@ func TestPackageJsonSideEffectsFalseRemoveNamedImportCommonJS(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -331,7 +331,7 @@ func TestPackageJsonSideEffectsFalseRemoveStarImportES6(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -356,7 +356,7 @@ func TestPackageJsonSideEffectsFalseRemoveStarImportCommonJS(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -381,7 +381,7 @@ func TestPackageJsonSideEffectsArrayRemove(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -406,7 +406,7 @@ func TestPackageJsonSideEffectsArrayKeep(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -431,7 +431,7 @@ func TestPackageJsonSideEffectsNestedDirectoryRemove(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -455,7 +455,7 @@ func TestPackageJsonSideEffectsKeepExportDefaultExpr(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -472,7 +472,7 @@ func TestJSONLoaderRemoveUnused(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -489,7 +489,7 @@ func TestTextLoaderRemoveUnused(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -506,7 +506,7 @@ func TestBase64LoaderRemoveUnused(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJS, @@ -527,7 +527,7 @@ func TestDataURLLoaderRemoveUnused(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJS, @@ -548,7 +548,7 @@ func TestFileLoaderRemoveUnused(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJS, @@ -570,7 +570,7 @@ func TestRemoveUnusedImportMeta(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -633,7 +633,7 @@ func TestRemoveUnusedPureCommentCalls(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -657,7 +657,7 @@ func TestTreeShakingReactElements(t *testing.T) { }, entryPaths: []string{"/entry.jsx"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) diff --git a/internal/bundler/bundler_default_test.go b/internal/bundler/bundler_default_test.go index b4eb48e7008..0fdb3b68e26 100644 --- a/internal/bundler/bundler_default_test.go +++ b/internal/bundler/bundler_default_test.go @@ -25,7 +25,7 @@ func TestSimpleES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -46,7 +46,7 @@ func TestSimpleCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -73,7 +73,7 @@ func TestNestedCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -94,7 +94,7 @@ func TestNewExpressionCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -121,7 +121,7 @@ func TestCommonJSFromES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -148,7 +148,7 @@ func TestES6FromCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -174,7 +174,7 @@ func TestNestedES6FromCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -199,7 +199,7 @@ func TestExportFormsES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatESModule, AbsOutputFile: "/out.js", }, @@ -225,7 +225,7 @@ func TestExportFormsIIFE(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatIIFE, ModuleName: "moduleName", AbsOutputFile: "/out.js", @@ -262,7 +262,6 @@ func TestExportFormsWithMinifyIdentifiersAndNoBundle(t *testing.T) { "/e.js", }, options: config.Options{ - IsBundling: false, MinifyIdentifiers: true, AbsOutputDir: "/out", }, @@ -289,7 +288,6 @@ func TestImportFormsWithNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -315,7 +313,6 @@ func TestImportFormsWithMinifyIdentifiersAndNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, MinifyIdentifiers: true, AbsOutputFile: "/out.js", }, @@ -356,7 +353,7 @@ func TestExportFormsCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -380,7 +377,7 @@ func TestReExportDefaultCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -401,7 +398,7 @@ func TestExportChain(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -419,7 +416,7 @@ func TestExportInfiniteCycle1(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedCompileLog: `/entry.js: error: Detected cycle while resolving import "a" @@ -444,7 +441,7 @@ func TestExportInfiniteCycle2(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedCompileLog: `/entry.js: error: Detected cycle while resolving import "a" @@ -468,7 +465,7 @@ func TestJSXImportsCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.jsx"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, JSX: config.JSXOptions{ Factory: []string{"elem"}, Fragment: []string{"frag"}, @@ -492,7 +489,7 @@ func TestJSXImportsES6(t *testing.T) { }, entryPaths: []string{"/entry.jsx"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, JSX: config.JSXOptions{ Factory: []string{"elem"}, Fragment: []string{"frag"}, @@ -511,7 +508,7 @@ func TestJSXSyntaxInJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedScanLog: `/entry.js: error: Unexpected "<" @@ -534,7 +531,7 @@ func TestNodeModules(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -560,7 +557,7 @@ func TestPackageJsonMain(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -587,7 +584,7 @@ func TestPackageJsonSyntaxErrorComment(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, expectedScanLog: "/Users/user/project/node_modules/demo-pkg/package.json: error: JSON does not support comments\n", @@ -615,7 +612,7 @@ func TestPackageJsonSyntaxErrorTrailingComma(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, expectedScanLog: "/Users/user/project/node_modules/demo-pkg/package.json: error: JSON does not support trailing commas\n", @@ -648,7 +645,7 @@ func TestPackageJsonModule(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -674,7 +671,7 @@ func TestPackageJsonBrowserString(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -717,7 +714,7 @@ func TestPackageJsonBrowserMapRelativeToRelative(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -753,7 +750,7 @@ func TestPackageJsonBrowserMapRelativeToModule(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -786,7 +783,7 @@ func TestPackageJsonBrowserMapRelativeDisabled(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -825,7 +822,7 @@ func TestPackageJsonBrowserMapModuleToRelative(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -864,7 +861,7 @@ func TestPackageJsonBrowserMapModuleToModule(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -898,7 +895,7 @@ func TestPackageJsonBrowserMapModuleDisabled(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -927,7 +924,7 @@ func TestPackageJsonBrowserMapNativeModuleDisabled(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -961,7 +958,7 @@ func TestPackageJsonBrowserMapAvoidMissing(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -999,7 +996,7 @@ func TestPackageJsonBrowserOverModule(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -1045,7 +1042,7 @@ func TestPackageJsonBrowserWithModule(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -1063,7 +1060,7 @@ func TestRequireChildDirCommonJS(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1082,7 +1079,7 @@ func TestRequireChildDirES6(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1100,7 +1097,7 @@ func TestRequireParentDirCommonJS(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/dir/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1119,7 +1116,7 @@ func TestRequireParentDirES6(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/dir/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1138,7 +1135,7 @@ func TestImportMissingES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedCompileLog: `/entry.js: error: No matching export for import "default" @@ -1159,7 +1156,7 @@ func TestImportMissingUnusedES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedCompileLog: `/entry.js: error: No matching export for import "default" @@ -1181,7 +1178,7 @@ func TestImportMissingCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1201,7 +1198,7 @@ func TestImportMissingNeitherES6NorCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedCompileLog: `/entry.js: warning: Import "default" will always be undefined @@ -1227,7 +1224,7 @@ func TestExportMissingES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedCompileLog: `/foo.js: error: No matching export for import "nope" @@ -1248,7 +1245,7 @@ func TestDotImport(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1267,7 +1264,7 @@ func TestRequireWithTemplate(t *testing.T) { }, entryPaths: []string{"/a.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1286,7 +1283,7 @@ func TestDynamicImportWithTemplateIIFE(t *testing.T) { }, entryPaths: []string{"/a.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatIIFE, AbsOutputFile: "/out.js", }, @@ -1305,7 +1302,7 @@ func TestRequireAndDynamicImportInvalidTemplate(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedScanLog: `/entry.js: warning: This call to "require" will not be bundled because the argument is not a string literal @@ -1326,7 +1323,7 @@ func TestRequireBadArgumentCount(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedScanLog: `/entry.js: warning: This call to "require" will not be bundled because it has 0 arguments @@ -1351,7 +1348,7 @@ func TestRequireJson(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1367,7 +1364,7 @@ func TestRequireTxt(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1383,7 +1380,7 @@ func TestRequireBadExtension(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedScanLog: `/entry.js: error: File extension not supported: /test @@ -1401,7 +1398,7 @@ func TestFalseRequire(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1417,7 +1414,7 @@ func TestRequireWithoutCall(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedScanLog: `/entry.js: warning: Indirect calls to "require" will not be bundled @@ -1437,7 +1434,7 @@ func TestNestedRequireWithoutCall(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedScanLog: `/entry.js: warning: Indirect calls to "require" will not be bundled @@ -1461,7 +1458,7 @@ func TestRequireWithCallInsideTry(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1482,7 +1479,7 @@ func TestRequireWithoutCallInsideTry(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1502,7 +1499,7 @@ func TestSourceMap(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, SourceMap: config.SourceMapLinkedWithComment, AbsOutputFile: "/Users/user/project/out.js", }, @@ -1531,7 +1528,7 @@ func TestNestedScopeBug(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1550,7 +1547,7 @@ func TestHashbangBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1565,7 +1562,6 @@ func TestHashbangNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -1586,7 +1582,7 @@ func TestTypeofRequireBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1607,7 +1603,6 @@ func TestTypeofRequireNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -1634,7 +1629,7 @@ func TestTypeofRequireBadPatterns(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedScanLog: `/entry.js: warning: Indirect calls to "require" will not be bundled @@ -1658,7 +1653,7 @@ func TestRequireFSBrowser(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", Platform: config.PlatformBrowser, }, @@ -1676,7 +1671,7 @@ func TestRequireFSNode(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", Platform: config.PlatformNode, @@ -1693,7 +1688,7 @@ func TestRequireFSNodeMinify(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, RemoveWhitespace: true, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", @@ -1715,7 +1710,7 @@ func TestImportFSBrowser(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", Platform: config.PlatformBrowser, }, @@ -1737,7 +1732,7 @@ func TestImportFSNodeCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", Platform: config.PlatformNode, @@ -1758,7 +1753,7 @@ func TestImportFSNodeES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatESModule, AbsOutputFile: "/out.js", Platform: config.PlatformNode, @@ -1776,7 +1771,7 @@ func TestExportFSBrowser(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", Platform: config.PlatformBrowser, }, @@ -1795,7 +1790,7 @@ func TestExportFSNode(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", Platform: config.PlatformNode, }, @@ -1816,7 +1811,7 @@ func TestReExportFSNode(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", Platform: config.PlatformNode, }, @@ -1836,7 +1831,7 @@ func TestExportFSNodeInCommonJSModule(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", Platform: config.PlatformNode, }, @@ -1852,7 +1847,7 @@ func TestExportWildcardFSNodeES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatESModule, AbsOutputFile: "/out.js", Platform: config.PlatformNode, @@ -1869,7 +1864,7 @@ func TestExportWildcardFSNodeCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", Platform: config.PlatformNode, @@ -1893,7 +1888,7 @@ func TestMinifiedBundleES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, MangleSyntax: true, RemoveWhitespace: true, MinifyIdentifiers: true, @@ -1920,7 +1915,7 @@ func TestMinifiedBundleCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, MangleSyntax: true, RemoveWhitespace: true, MinifyIdentifiers: true, @@ -1938,7 +1933,7 @@ func TestMinifiedBundleEndingWithImportantSemicolon(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, RemoveWhitespace: true, OutputFormat: config.FormatIIFE, AbsOutputFile: "/out.js", @@ -1956,7 +1951,6 @@ func TestRuntimeNameCollisionNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -1978,7 +1972,7 @@ func TestTopLevelReturn(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1996,7 +1990,7 @@ func TestThisOutsideFunction(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -2021,7 +2015,7 @@ func TestThisInsideFunction(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -2110,7 +2104,7 @@ func TestThisWithES6Syntax(t *testing.T) { "/entry.js", }, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -2134,7 +2128,7 @@ func TestArrowFnScope(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, MinifyIdentifiers: true, AbsOutputFile: "/out.js", }, @@ -2151,7 +2145,6 @@ func TestSwitchScopeNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, MinifyIdentifiers: true, AbsOutputFile: "/out.js", }, @@ -2174,7 +2167,6 @@ func TestArgumentDefaultValueScopeNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, MinifyIdentifiers: true, AbsOutputFile: "/out.js", }, @@ -2228,7 +2220,6 @@ func TestArgumentsSpecialCaseNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, MinifyIdentifiers: true, AbsOutputFile: "/out.js", }, @@ -2262,7 +2253,6 @@ func TestWithStatementTaintingNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, MinifyIdentifiers: true, AbsOutputFile: "/out.js", }, @@ -2308,7 +2298,6 @@ func TestDirectEvalTaintingNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, MinifyIdentifiers: true, AbsOutputFile: "/out.js", }, @@ -2336,7 +2325,7 @@ func TestImportReExportES6Issue149(t *testing.T) { }, entryPaths: []string{"/app.jsx"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, JSX: config.JSXOptions{ Factory: []string{"h"}, }, @@ -2362,7 +2351,7 @@ func TestExternalModuleExclusionPackage(t *testing.T) { }, entryPaths: []string{"/index.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExternalModules: config.ExternalModules{ NodeModules: map[string]bool{ @@ -2395,7 +2384,7 @@ func TestExternalModuleExclusionScopedPackage(t *testing.T) { }, entryPaths: []string{"/index.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExternalModules: config.ExternalModules{ NodeModules: map[string]bool{ @@ -2427,7 +2416,7 @@ func TestScopedExternalModuleExclusion(t *testing.T) { }, entryPaths: []string{"/index.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExternalModules: config.ExternalModules{ NodeModules: map[string]bool{ @@ -2453,7 +2442,7 @@ func TestExternalModuleExclusionRelativePath(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/index.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputDir: "/Users/user/project/out", ExternalModules: config.ExternalModules{ AbsPaths: map[string]bool{ @@ -2523,7 +2512,7 @@ func TestManyEntryPoints(t *testing.T) { "/e30.js", "/e31.js", "/e32.js", "/e33.js", "/e34.js", "/e35.js", "/e36.js", "/e37.js", "/e38.js", "/e39.js", }, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputDir: "/out", }, }) @@ -2557,7 +2546,6 @@ func TestRenamePrivateIdentifiersNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -2591,7 +2579,6 @@ func TestMinifyPrivateIdentifiersNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, MinifyIdentifiers: true, AbsOutputFile: "/out.js", }, @@ -2624,7 +2611,6 @@ func TestRenameLabelsNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -2657,7 +2643,6 @@ func TestMinifySiblingLabelsNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, MinifyIdentifiers: true, AbsOutputFile: "/out.js", }, @@ -2698,7 +2683,6 @@ func TestMinifyNestedLabelsNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, RemoveWhitespace: true, MinifyIdentifiers: true, AbsOutputFile: "/out.js", @@ -2723,7 +2707,7 @@ func TestExportsAndModuleFormatCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", Platform: config.PlatformNode, @@ -2750,7 +2734,7 @@ func TestMinifiedExportsAndModuleFormatCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, MinifyIdentifiers: true, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", @@ -2775,7 +2759,6 @@ func TestUseStrictDirectiveMinifyNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, MangleSyntax: true, RemoveWhitespace: true, AbsOutputFile: "/out.js", @@ -2792,7 +2775,7 @@ func TestNoOverwriteInputFileError(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputDir: "/", }, expectedCompileLog: "error: Refusing to overwrite input file: /entry.js\n", @@ -2808,7 +2791,7 @@ func TestDuplicateEntryPointError(t *testing.T) { }, entryPaths: []string{"/entry.js", "/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputDir: "/out.js", }, expectedScanLog: "error: Duplicate entry point \"/entry.js\"\n", @@ -2824,7 +2807,7 @@ func TestMultipleEntryPointsSameNameCollision(t *testing.T) { }, entryPaths: []string{"/a/entry.js", "/b/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputDir: "/out/", }, }) @@ -2842,7 +2825,7 @@ func TestReExportCommonJSAsES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -2864,7 +2847,7 @@ func TestReExportDefaultInternal(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -2883,7 +2866,7 @@ func TestReExportDefaultExternal(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExternalModules: config.ExternalModules{ NodeModules: map[string]bool{ @@ -2905,7 +2888,6 @@ func TestReExportDefaultNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -2920,7 +2902,7 @@ func TestImportMetaCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", }, @@ -2936,7 +2918,7 @@ func TestImportMetaES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatESModule, AbsOutputFile: "/out.js", }, @@ -2952,7 +2934,6 @@ func TestImportMetaNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -2972,7 +2953,7 @@ func TestDeduplicateCommentsInBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, RemoveWhitespace: true, AbsOutputFile: "/out.js", }, @@ -2989,7 +2970,7 @@ func TestIIFE_ES5(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, UnsupportedFeatures: es(5), OutputFormat: config.FormatIIFE, AbsOutputFile: "/out.js", @@ -3006,7 +2987,7 @@ func TestOutputExtensionRemappingFile(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputExtensions: map[string]string{".js": ".notjs"}, AbsOutputFile: "/out.js", }, @@ -3022,7 +3003,7 @@ func TestOutputExtensionRemappingDir(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputExtensions: map[string]string{".js": ".notjs"}, AbsOutputDir: "/out", }, @@ -3039,7 +3020,7 @@ func TestTopLevelAwait(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedScanLog: `/entry.js: error: Top-level await is currently not supported when bundling @@ -3048,6 +3029,78 @@ func TestTopLevelAwait(t *testing.T) { }) } +func TestTopLevelAwaitNoBundle(t *testing.T) { + default_suite.expectBundled(t, bundled{ + files: map[string]string{ + "/entry.js": ` + await foo; + for await (foo of bar) ; + `, + }, + entryPaths: []string{"/entry.js"}, + options: config.Options{ + AbsOutputFile: "/out.js", + }, + }) +} + +func TestTopLevelAwaitNoBundleES6(t *testing.T) { + default_suite.expectBundled(t, bundled{ + files: map[string]string{ + "/entry.js": ` + await foo; + for await (foo of bar) ; + `, + }, + entryPaths: []string{"/entry.js"}, + options: config.Options{ + OutputFormat: config.FormatESModule, + Mode: config.ModeConvertFormat, + AbsOutputFile: "/out.js", + }, + }) +} + +func TestTopLevelAwaitNoBundleCommonJS(t *testing.T) { + default_suite.expectBundled(t, bundled{ + files: map[string]string{ + "/entry.js": ` + await foo; + for await (foo of bar) ; + `, + }, + entryPaths: []string{"/entry.js"}, + options: config.Options{ + OutputFormat: config.FormatCommonJS, + Mode: config.ModeConvertFormat, + AbsOutputFile: "/out.js", + }, + expectedScanLog: `/entry.js: error: Top-level await is currently not supported with the "cjs" output format +/entry.js: error: Top-level await is currently not supported with the "cjs" output format +`, + }) +} + +func TestTopLevelAwaitNoBundleIIFE(t *testing.T) { + default_suite.expectBundled(t, bundled{ + files: map[string]string{ + "/entry.js": ` + await foo; + for await (foo of bar) ; + `, + }, + entryPaths: []string{"/entry.js"}, + options: config.Options{ + OutputFormat: config.FormatIIFE, + Mode: config.ModeConvertFormat, + AbsOutputFile: "/out.js", + }, + expectedScanLog: `/entry.js: error: Top-level await is currently not supported with the "iife" output format +/entry.js: error: Top-level await is currently not supported with the "iife" output format +`, + }) +} + func TestAssignToImport(t *testing.T) { default_suite.expectBundled(t, bundled{ files: map[string]string{ @@ -3073,7 +3126,7 @@ func TestAssignToImport(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedScanLog: `/bad0.js: error: Cannot assign to import "x" @@ -3110,7 +3163,7 @@ func TestMinifyArguments(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, MinifyIdentifiers: true, AbsOutputFile: "/out.js", }, diff --git a/internal/bundler/bundler_importstar_test.go b/internal/bundler/bundler_importstar_test.go index 69593932bcd..c88ed7c9247 100644 --- a/internal/bundler/bundler_importstar_test.go +++ b/internal/bundler/bundler_importstar_test.go @@ -24,7 +24,7 @@ func TestImportStarUnused(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -44,7 +44,7 @@ func TestImportStarCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -64,7 +64,7 @@ func TestImportStarNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -88,7 +88,7 @@ func TestImportStarExportImportStarUnused(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -112,7 +112,7 @@ func TestImportStarExportImportStarNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -136,7 +136,7 @@ func TestImportStarExportImportStarCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -159,7 +159,7 @@ func TestImportStarExportStarAsUnused(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -182,7 +182,7 @@ func TestImportStarExportStarAsNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -205,7 +205,7 @@ func TestImportStarExportStarAsCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -228,7 +228,7 @@ func TestImportStarExportStarUnused(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -251,7 +251,7 @@ func TestImportStarExportStarNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -274,7 +274,7 @@ func TestImportStarExportStarCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -294,7 +294,7 @@ func TestImportStarCommonJSUnused(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -314,7 +314,7 @@ func TestImportStarCommonJSCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -334,7 +334,7 @@ func TestImportStarCommonJSNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -354,7 +354,7 @@ func TestImportStarAndCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -371,7 +371,6 @@ func TestImportStarNoBundleUnused(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -388,7 +387,6 @@ func TestImportStarNoBundleCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -405,7 +403,6 @@ func TestImportStarNoBundleNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -422,7 +419,6 @@ func TestImportStarMangleNoBundleUnused(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, MangleSyntax: true, AbsOutputFile: "/out.js", }, @@ -440,7 +436,6 @@ func TestImportStarMangleNoBundleCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, MangleSyntax: true, AbsOutputFile: "/out.js", }, @@ -458,7 +453,6 @@ func TestImportStarMangleNoBundleNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, MangleSyntax: true, AbsOutputFile: "/out.js", }, @@ -487,7 +481,7 @@ func TestImportStarExportStarOmitAmbiguous(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -515,7 +509,7 @@ func TestImportExportStarAmbiguousError(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedCompileLog: "/entry.js: error: Ambiguous import \"y\" has multiple matching exports\n", @@ -538,7 +532,7 @@ func TestImportStarOfExportStarAs(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -565,7 +559,7 @@ func TestImportOfExportStar(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -595,7 +589,7 @@ func TestImportOfExportStarOfImport(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -611,7 +605,7 @@ func TestExportSelfIIFE(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatIIFE, AbsOutputFile: "/out.js", }, @@ -628,7 +622,7 @@ func TestExportSelfES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatESModule, AbsOutputFile: "/out.js", }, @@ -645,7 +639,7 @@ func TestExportSelfCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", }, @@ -662,7 +656,7 @@ func TestExportSelfCommonJSMinified(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, MinifyIdentifiers: true, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", @@ -681,7 +675,7 @@ func TestImportSelfCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", }, @@ -698,7 +692,7 @@ func TestExportSelfAsNamespaceES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatESModule, AbsOutputFile: "/out.js", }, @@ -716,7 +710,7 @@ func TestImportExportSelfAsNamespaceES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatESModule, AbsOutputFile: "/out.js", }, @@ -736,7 +730,7 @@ func TestReExportOtherFileExportSelfAsNamespaceES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatESModule, AbsOutputFile: "/out.js", }, @@ -757,7 +751,7 @@ func TestReExportOtherFileImportExportSelfAsNamespaceES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatESModule, AbsOutputFile: "/out.js", }, @@ -777,7 +771,7 @@ func TestOtherFileExportSelfAsNamespaceUnusedES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatESModule, AbsOutputFile: "/out.js", }, @@ -798,7 +792,7 @@ func TestOtherFileImportExportSelfAsNamespaceUnusedES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatESModule, AbsOutputFile: "/out.js", }, @@ -815,7 +809,7 @@ func TestExportSelfAsNamespaceCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", }, @@ -832,7 +826,7 @@ func TestExportSelfAndRequireSelfCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", }, @@ -850,7 +844,7 @@ func TestExportSelfAndImportSelfCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", }, @@ -869,7 +863,7 @@ func TestExportOtherAsNamespaceCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", }, @@ -889,7 +883,7 @@ func TestImportExportOtherAsNamespaceCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", }, @@ -909,7 +903,7 @@ func TestNamespaceImportMissingES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -927,7 +921,7 @@ func TestExportOtherCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", }, @@ -949,7 +943,7 @@ func TestExportOtherNestedCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", }, @@ -969,7 +963,7 @@ func TestNamespaceImportUnusedMissingES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -988,7 +982,7 @@ func TestNamespaceImportMissingCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1007,7 +1001,7 @@ func TestNamespaceImportUnusedMissingCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1029,7 +1023,7 @@ func TestReExportNamespaceImportMissingES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1051,7 +1045,7 @@ func TestReExportNamespaceImportUnusedMissingES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1073,7 +1067,7 @@ func TestNamespaceImportReExportMissingES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedCompileLog: `/foo.js: error: No matching export for import "foo" @@ -1098,7 +1092,7 @@ func TestNamespaceImportReExportUnusedMissingES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedCompileLog: `/foo.js: error: No matching export for import "foo" @@ -1123,7 +1117,7 @@ func TestNamespaceImportReExportStarMissingES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1145,7 +1139,7 @@ func TestNamespaceImportReExportStarUnusedMissingES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -1164,7 +1158,7 @@ func TestExportStarDefaultExportCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, OutputFormat: config.FormatCommonJS, AbsOutputFile: "/out.js", }, @@ -1190,7 +1184,7 @@ func TestIssue176(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) diff --git a/internal/bundler/bundler_importstar_ts_test.go b/internal/bundler/bundler_importstar_ts_test.go index ebc2c4abd55..d37ea49f76a 100644 --- a/internal/bundler/bundler_importstar_ts_test.go +++ b/internal/bundler/bundler_importstar_ts_test.go @@ -24,7 +24,7 @@ func TestTSImportStarUnused(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -44,7 +44,7 @@ func TestTSImportStarCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -64,7 +64,7 @@ func TestTSImportStarNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -88,7 +88,7 @@ func TestTSImportStarExportImportStarUnused(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -112,7 +112,7 @@ func TestTSImportStarExportImportStarNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -136,7 +136,7 @@ func TestTSImportStarExportImportStarCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -159,7 +159,7 @@ func TestTSImportStarExportStarAsUnused(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -182,7 +182,7 @@ func TestTSImportStarExportStarAsNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -205,7 +205,7 @@ func TestTSImportStarExportStarAsCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -228,7 +228,7 @@ func TestTSImportStarExportStarUnused(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -251,7 +251,7 @@ func TestTSImportStarExportStarNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -274,7 +274,7 @@ func TestTSImportStarExportStarCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -294,7 +294,7 @@ func TestTSImportStarCommonJSUnused(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -314,7 +314,7 @@ func TestTSImportStarCommonJSCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -334,7 +334,7 @@ func TestTSImportStarCommonJSNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -354,7 +354,7 @@ func TestTSImportStarAndCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -371,7 +371,6 @@ func TestTSImportStarNoBundleUnused(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -388,7 +387,6 @@ func TestTSImportStarNoBundleCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -405,7 +403,6 @@ func TestTSImportStarNoBundleNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -422,7 +419,6 @@ func TestTSImportStarMangleNoBundleUnused(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, MangleSyntax: true, AbsOutputFile: "/out.js", }, @@ -440,7 +436,6 @@ func TestTSImportStarMangleNoBundleCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, MangleSyntax: true, AbsOutputFile: "/out.js", }, @@ -458,7 +453,6 @@ func TestTSImportStarMangleNoBundleNoCapture(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, MangleSyntax: true, AbsOutputFile: "/out.js", }, diff --git a/internal/bundler/bundler_loader_test.go b/internal/bundler/bundler_loader_test.go index 7f3dd46e00a..7f8f7b632a0 100644 --- a/internal/bundler/bundler_loader_test.go +++ b/internal/bundler/bundler_loader_test.go @@ -20,7 +20,7 @@ func TestLoaderFile(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputDir: "/out/", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJS, @@ -46,7 +46,7 @@ func TestLoaderFileMultipleNoCollision(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/dist/out.js", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJS, @@ -65,7 +65,7 @@ func TestJSXSyntaxInJSWithJSXLoader(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJSX, @@ -84,7 +84,7 @@ func TestRequireCustomExtensionString(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJS, @@ -104,7 +104,7 @@ func TestRequireCustomExtensionBase64(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJS, @@ -124,7 +124,7 @@ func TestRequireCustomExtensionDataURL(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJS, @@ -145,7 +145,7 @@ func TestRequireCustomExtensionPreferLongest(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJS, @@ -166,7 +166,7 @@ func TestAutoDetectMimeTypeFromExtension(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJS, @@ -195,7 +195,7 @@ func TestLoaderJSONCommonJSAndES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -214,7 +214,7 @@ func TestLoaderTextCommonJSAndES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -233,7 +233,7 @@ func TestLoaderBase64CommonJSAndES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJS, @@ -256,7 +256,7 @@ func TestLoaderDataURLCommonJSAndES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJS, @@ -279,7 +279,7 @@ func TestLoaderFileCommonJSAndES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", ExtensionToLoader: map[string]config.Loader{ ".js": config.LoaderJS, @@ -288,3 +288,57 @@ func TestLoaderFileCommonJSAndES6(t *testing.T) { }, }) } + +func TestLoaderJSONNoBundle(t *testing.T) { + loader_suite.expectBundled(t, bundled{ + files: map[string]string{ + "/test.json": `{"test": 123}`, + }, + entryPaths: []string{"/test.json"}, + options: config.Options{ + AbsOutputFile: "/out.js", + }, + }) +} + +func TestLoaderJSONNoBundleES6(t *testing.T) { + loader_suite.expectBundled(t, bundled{ + files: map[string]string{ + "/test.json": `{"test": 123}`, + }, + entryPaths: []string{"/test.json"}, + options: config.Options{ + Mode: config.ModeConvertFormat, + OutputFormat: config.FormatESModule, + AbsOutputFile: "/out.js", + }, + }) +} + +func TestLoaderJSONNoBundleCommonJS(t *testing.T) { + loader_suite.expectBundled(t, bundled{ + files: map[string]string{ + "/test.json": `{"test": 123}`, + }, + entryPaths: []string{"/test.json"}, + options: config.Options{ + Mode: config.ModeConvertFormat, + OutputFormat: config.FormatCommonJS, + AbsOutputFile: "/out.js", + }, + }) +} + +func TestLoaderJSONNoBundleIIFE(t *testing.T) { + loader_suite.expectBundled(t, bundled{ + files: map[string]string{ + "/test.json": `{"test": 123}`, + }, + entryPaths: []string{"/test.json"}, + options: config.Options{ + Mode: config.ModeConvertFormat, + OutputFormat: config.FormatIIFE, + AbsOutputFile: "/out.js", + }, + }) +} diff --git a/internal/bundler/bundler_lower_test.go b/internal/bundler/bundler_lower_test.go index eece7c25ab8..ce8409adb9c 100644 --- a/internal/bundler/bundler_lower_test.go +++ b/internal/bundler/bundler_lower_test.go @@ -25,7 +25,6 @@ func TestLowerOptionalCatchNameCollisionNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2018), AbsOutputFile: "/out.js", }, @@ -54,7 +53,6 @@ func TestLowerObjectSpreadNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.jsx"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2017), AbsOutputFile: "/out.js", }, @@ -98,7 +96,6 @@ func TestLowerExponentiationOperatorNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2015), AbsOutputFile: "/out.js", }, @@ -141,7 +138,6 @@ func TestLowerPrivateFieldAssignments2015NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2015), AbsOutputFile: "/out.js", }, @@ -183,7 +179,6 @@ func TestLowerPrivateFieldAssignments2019NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2019), AbsOutputFile: "/out.js", }, @@ -225,7 +220,6 @@ func TestLowerPrivateFieldAssignments2020NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2020), AbsOutputFile: "/out.js", }, @@ -267,7 +261,6 @@ func TestLowerPrivateFieldAssignmentsNextNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -289,7 +282,6 @@ func TestLowerPrivateFieldOptionalChain2019NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2019), AbsOutputFile: "/out.js", }, @@ -312,7 +304,6 @@ func TestLowerPrivateFieldOptionalChain2020NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2020), AbsOutputFile: "/out.js", }, @@ -335,7 +326,6 @@ func TestLowerPrivateFieldOptionalChainNextNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -357,7 +347,6 @@ func TestTSLowerPrivateFieldOptionalChain2015NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2015), AbsOutputFile: "/out.js", }, @@ -383,7 +372,6 @@ func TestTSLowerPrivateStaticMembers2015NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2015), AbsOutputFile: "/out.js", }, @@ -404,7 +392,7 @@ func TestTSLowerPrivateFieldAndMethodAvoidNameCollision2015(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, UnsupportedFeatures: es(2015), AbsOutputFile: "/out.js", }, @@ -455,7 +443,7 @@ func TestLowerPrivateGetterSetter2015(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, UnsupportedFeatures: es(2015), AbsOutputFile: "/out.js", }, @@ -506,7 +494,7 @@ func TestLowerPrivateGetterSetter2019(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, UnsupportedFeatures: es(2019), AbsOutputFile: "/out.js", }, @@ -557,7 +545,7 @@ func TestLowerPrivateGetterSetter2020(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, UnsupportedFeatures: es(2020), AbsOutputFile: "/out.js", }, @@ -608,7 +596,7 @@ func TestLowerPrivateGetterSetterNext(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -649,7 +637,7 @@ func TestLowerPrivateMethod2019(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, UnsupportedFeatures: es(2019), AbsOutputFile: "/out.js", }, @@ -691,7 +679,7 @@ func TestLowerPrivateMethod2020(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, UnsupportedFeatures: es(2020), AbsOutputFile: "/out.js", }, @@ -733,7 +721,7 @@ func TestLowerPrivateMethodNext(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -757,7 +745,6 @@ func TestLowerPrivateClassExpr2020NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2020), AbsOutputFile: "/out.js", }, @@ -781,7 +768,7 @@ func TestLowerPrivateMethodWithModifiers2020(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, UnsupportedFeatures: es(2020), AbsOutputFile: "/out.js", }, @@ -815,7 +802,6 @@ func TestLowerAsync2016NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2016), AbsOutputFile: "/out.js", }, @@ -849,7 +835,6 @@ func TestLowerAsync2017NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2017), AbsOutputFile: "/out.js", }, @@ -865,7 +850,7 @@ func TestLowerAsyncThis2016CommonJS(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, UnsupportedFeatures: es(2016), AbsOutputFile: "/out.js", }, @@ -881,7 +866,7 @@ func TestLowerAsyncThis2016ES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, UnsupportedFeatures: es(2016), AbsOutputFile: "/out.js", }, @@ -906,7 +891,6 @@ func TestLowerClassFieldStrict2020NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2020), Strict: config.StrictOptions{ ClassFields: true, @@ -934,7 +918,6 @@ func TestLowerClassField2020NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2020), AbsOutputFile: "/out.js", }, @@ -959,7 +942,6 @@ func TestLowerClassFieldStrictNextNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, Strict: config.StrictOptions{ ClassFields: true, }, @@ -986,7 +968,6 @@ func TestLowerClassFieldNextNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -1010,7 +991,6 @@ func TestTSLowerClassFieldStrict2020NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2020), Strict: config.StrictOptions{ ClassFields: true, @@ -1038,7 +1018,6 @@ func TestTSLowerClassField2020NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2020), AbsOutputFile: "/out.js", }, @@ -1063,7 +1042,6 @@ func TestTSLowerClassPrivateFieldStrictNextNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, Strict: config.StrictOptions{ ClassFields: true, }, @@ -1090,7 +1068,6 @@ func TestTSLowerClassPrivateFieldNextNoBundle(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, AbsOutputFile: "/out.js", }, }) @@ -1131,7 +1108,7 @@ func TestLowerClassFieldStrictTsconfigJson2020(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, UnsupportedFeatures: es(2020), AbsOutputFile: "/out.js", }, @@ -1173,7 +1150,6 @@ func TestTSLowerObjectRest2017NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2017), AbsOutputFile: "/out.js", }, @@ -1215,7 +1191,6 @@ func TestTSLowerObjectRest2018NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2018), AbsOutputFile: "/out.js", }, @@ -1242,7 +1217,6 @@ func TestClassSuperThisIssue242NoBundle(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: false, UnsupportedFeatures: es(2019), AbsOutputFile: "/out.js", }, diff --git a/internal/bundler/bundler_splitting_test.go b/internal/bundler/bundler_splitting_test.go index e4b66f5a502..ab23c760876 100644 --- a/internal/bundler/bundler_splitting_test.go +++ b/internal/bundler/bundler_splitting_test.go @@ -25,7 +25,7 @@ func TestSplittingSharedES6IntoES6(t *testing.T) { }, entryPaths: []string{"/a.js", "/b.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -48,7 +48,7 @@ func TestSplittingSharedCommonJSIntoES6(t *testing.T) { }, entryPaths: []string{"/a.js", "/b.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -68,7 +68,7 @@ func TestSplittingDynamicES6IntoES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -88,7 +88,7 @@ func TestSplittingDynamicCommonJSIntoES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -109,7 +109,7 @@ func TestSplittingDynamicAndNotDynamicES6IntoES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -130,7 +130,7 @@ func TestSplittingDynamicAndNotDynamicCommonJSIntoES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -159,7 +159,7 @@ func TestSplittingAssignToLocal(t *testing.T) { }, entryPaths: []string{"/a.js", "/b.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -186,7 +186,7 @@ func TestSplittingSideEffectsWithoutDependencies(t *testing.T) { }, entryPaths: []string{"/a.js", "/b.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -214,7 +214,7 @@ func TestSplittingNestedDirectories(t *testing.T) { "/Users/user/project/src/pages/pageB/page.js", }, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/Users/user/project/out", @@ -236,7 +236,7 @@ func TestSplittingCircularReferenceIssue251(t *testing.T) { }, entryPaths: []string{"/a.js", "/b.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -267,7 +267,7 @@ func TestSplittingMissingLazyExport(t *testing.T) { }, entryPaths: []string{"/a.js", "/b.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -287,7 +287,7 @@ func TestSplittingReExportIssue273(t *testing.T) { }, entryPaths: []string{"/a.js", "/b.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -307,7 +307,7 @@ func TestSplittingDynamicImportIssue272(t *testing.T) { }, entryPaths: []string{"/a.js", "/b.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -330,7 +330,7 @@ func TestSplittingDynamicImportOutsideSourceTreeIssue264(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/entry1.js", "/Users/user/project/src/entry2.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -366,7 +366,7 @@ func TestSplittingCrossChunkAssignmentDependencies(t *testing.T) { }, entryPaths: []string{"/a.js", "/b.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -413,7 +413,7 @@ func TestSplittingCrossChunkAssignmentDependenciesRecursive(t *testing.T) { }, entryPaths: []string{"/a.js", "/b.js", "/c.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, OutputFormat: config.FormatESModule, AbsOutputDir: "/out", @@ -445,7 +445,7 @@ func TestSplittingDuplicateChunkCollision(t *testing.T) { }, entryPaths: []string{"/a.js", "/b.js", "/c.js", "/d.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, CodeSplitting: true, RemoveWhitespace: true, OutputFormat: config.FormatESModule, diff --git a/internal/bundler/bundler_ts_test.go b/internal/bundler/bundler_ts_test.go index 4ff4cd74c74..acaa9d7af86 100644 --- a/internal/bundler/bundler_ts_test.go +++ b/internal/bundler/bundler_ts_test.go @@ -24,7 +24,7 @@ func TestTSDeclareConst(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -44,7 +44,7 @@ func TestTSDeclareLet(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -64,7 +64,7 @@ func TestTSDeclareVar(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -84,7 +84,7 @@ func TestTSDeclareClass(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -104,7 +104,7 @@ func TestTSDeclareFunction(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -124,7 +124,7 @@ func TestTSDeclareNamespace(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -144,7 +144,7 @@ func TestTSDeclareEnum(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -164,7 +164,7 @@ func TestTSDeclareConstEnum(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -184,7 +184,7 @@ func TestTSImportEmptyNamespace(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -203,7 +203,7 @@ func TestTSImportMissingES6(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedCompileLog: `/entry.ts: error: No matching export for import "default" @@ -224,7 +224,7 @@ func TestTSImportMissingUnusedES6(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -246,7 +246,7 @@ func TestTSExportMissingES6(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -263,7 +263,7 @@ func TestTSImportMissingFile(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedScanLog: "/entry.ts: error: Could not resolve \"./doesNotExist.ts\"\n", @@ -282,7 +282,7 @@ func TestTSImportTypeOnlyFile(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -302,7 +302,7 @@ func TestTSExportEquals(t *testing.T) { }, entryPaths: []string{"/a.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -327,7 +327,7 @@ func TestTSExportNamespace(t *testing.T) { }, entryPaths: []string{"/a.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -422,7 +422,7 @@ func TestTSImportVsLocalCollisionAllTypes(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -446,7 +446,7 @@ func TestTSImportVsLocalCollisionMixed(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -467,7 +467,7 @@ func TestTSMinifiedBundleES6(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, MangleSyntax: true, RemoveWhitespace: true, MinifyIdentifiers: true, @@ -494,7 +494,7 @@ func TestTSMinifiedBundleCommonJS(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, MangleSyntax: true, RemoveWhitespace: true, MinifyIdentifiers: true, @@ -626,7 +626,7 @@ func TestTypeScriptDecorators(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -754,7 +754,7 @@ func TestTSExportDefaultTypeIssue316(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -792,7 +792,7 @@ func TestTSImplicitExtensions(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -816,7 +816,7 @@ func TestTSImplicitExtensionsMissing(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedScanLog: `/entry.ts: error: Could not resolve "./mjs.mjs" diff --git a/internal/bundler/bundler_tsconfig_test.go b/internal/bundler/bundler_tsconfig_test.go index ef327e767d2..cde24df7b07 100644 --- a/internal/bundler/bundler_tsconfig_test.go +++ b/internal/bundler/bundler_tsconfig_test.go @@ -123,7 +123,7 @@ func TestTsConfigPaths(t *testing.T) { }, entryPaths: []string{"/Users/user/project/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -146,7 +146,7 @@ func TestTsConfigJSX(t *testing.T) { }, entryPaths: []string{"/Users/user/project/entry.tsx"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -195,7 +195,7 @@ func TestTsConfigNestedJSX(t *testing.T) { }, entryPaths: []string{"/Users/user/project/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -223,7 +223,7 @@ func TestTsconfigJsonBaseUrl(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/app/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -251,7 +251,7 @@ func TestJsconfigJsonBaseUrl(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/app/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -280,7 +280,7 @@ func TestTsconfigJsonCommentAllowed(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/app/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -308,7 +308,7 @@ func TestTsconfigJsonTrailingCommaAllowed(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/app/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -339,7 +339,7 @@ func TestTsconfigJsonExtends(t *testing.T) { }, entryPaths: []string{"/entry.jsx"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -375,7 +375,7 @@ func TestTsconfigJsonExtendsThreeLevels(t *testing.T) { }, entryPaths: []string{"/entry.jsx"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, }) @@ -400,7 +400,7 @@ func TestTsconfigJsonExtendsLoop(t *testing.T) { }, entryPaths: []string{"/entry.js"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", }, expectedScanLog: "/base.json: warning: Base config file \"./tsconfig\" forms cycle\n", @@ -428,7 +428,7 @@ func TestTsconfigJsonExtendsPackage(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/app/entry.jsx"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) @@ -469,7 +469,7 @@ func TestTsconfigJsonOverrideMissing(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/app/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", TsConfigOverride: "/Users/user/project/other/config-for-ts.json", }, @@ -514,7 +514,7 @@ func TestTsconfigJsonOverrideNodeModules(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/app/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", TsConfigOverride: "/Users/user/project/other/config-for-ts.json", }, @@ -528,7 +528,7 @@ func TestTsconfigJsonOverrideInvalid(t *testing.T) { }, entryPaths: []string{"/entry.ts"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/out.js", TsConfigOverride: "/this/file/doesn't/exist/tsconfig.json", }, @@ -558,7 +558,7 @@ func TestTsconfigJsonNodeModulesImplicitFile(t *testing.T) { }, entryPaths: []string{"/Users/user/project/src/app/entry.tsx"}, options: config.Options{ - IsBundling: true, + Mode: config.ModeBundle, AbsOutputFile: "/Users/user/project/out.js", }, }) diff --git a/internal/bundler/linker.go b/internal/bundler/linker.go index 4e29cfca8e2..cea827d5cf9 100644 --- a/internal/bundler/linker.go +++ b/internal/bundler/linker.go @@ -370,8 +370,9 @@ func newLinkerContext( // Also associate some default metadata with the file c.fileMeta[sourceIndex] = fileMeta{ - distanceFromEntryPoint: ^uint32(0), - cjsStyleExports: file.ast.HasCommonJSFeatures() || (file.ast.HasLazyExport && !c.options.IsBundling), + distanceFromEntryPoint: ^uint32(0), + cjsStyleExports: file.ast.HasCommonJSFeatures() || (file.ast.HasLazyExport && (c.options.Mode == config.ModePassThrough || + (c.options.Mode == config.ModeConvertFormat && !c.options.OutputFormat.KeepES6ImportExportSyntax()))), partMeta: make([]partMeta, len(file.ast.Parts)), resolvedExports: resolvedExports, isProbablyTypeScriptType: make(map[ast.Ref]bool), @@ -503,7 +504,7 @@ func (c *linkerContext) link() []OutputFile { c.markPartsReachableFromEntryPoints() c.handleCrossChunkAssignments() - if !c.options.IsBundling { + if c.options.Mode == config.ModePassThrough { for _, entryPoint := range c.entryPoints { c.markExportsAsUnbound(entryPoint) } @@ -2060,7 +2061,7 @@ func (c *linkerContext) includeFile(sourceIndex uint32, entryPointBit uint, dist // Include all parts in this file with side effects, or just include // everything if tree-shaking is disabled. Note that we still want to // perform tree-shaking on the runtime even if tree-shaking is disabled. - if !canBeRemovedIfUnused || (!part.ForceTreeShaking && !c.options.IsBundling && sourceIndex != runtime.SourceIndex) { + if !canBeRemovedIfUnused || (!part.ForceTreeShaking && c.options.Mode != config.ModeBundle && sourceIndex != runtime.SourceIndex) { c.includePart(sourceIndex, uint32(partIndex), entryPointBit, distanceFromEntryPoint) } } @@ -2420,7 +2421,7 @@ func (c *linkerContext) shouldRemoveImportExportStmt( } func (c *linkerContext) convertStmtsForChunk(sourceIndex uint32, stmtList *stmtList, partStmts []ast.Stmt) { - shouldStripExports := c.options.IsBundling || sourceIndex == runtime.SourceIndex + shouldStripExports := c.options.Mode != config.ModePassThrough || sourceIndex == runtime.SourceIndex shouldExtractES6StmtsForCJSWrap := c.fileMeta[sourceIndex].cjsWrap for _, stmt := range partStmts { @@ -2783,7 +2784,7 @@ func (c *linkerContext) generateCodeForFileInChunk( OutputFormat: c.options.OutputFormat, RemoveWhitespace: c.options.RemoveWhitespace, ToModuleRef: toModuleRef, - ExtractComments: c.options.IsBundling && c.options.RemoveWhitespace, + ExtractComments: c.options.Mode == config.ModeBundle && c.options.RemoveWhitespace, UnsupportedFeatures: c.options.UnsupportedFeatures, SourceForSourceMap: sourceForSourceMap, InputSourceMap: file.ast.SourceMap, @@ -2817,7 +2818,7 @@ func (c *linkerContext) renameSymbolsInChunk(chunk *chunkInfo, filesInOrder []ui reservedNames := renamer.ComputeReservedNames(moduleScopes, c.symbols) // These are used to implement bundling, and need to be free for use - if c.options.IsBundling { + if c.options.Mode != config.ModePassThrough { reservedNames["require"] = 1 reservedNames["Promise"] = 1 } @@ -3104,7 +3105,7 @@ func (c *linkerContext) generateChunk(chunk *chunkInfo) func([]ast.ImportRecord) } // Don't add a file name comment for the runtime - if c.options.IsBundling && !c.options.RemoveWhitespace && !isRuntime { + if c.options.Mode == config.ModeBundle && !c.options.RemoveWhitespace && !isRuntime { if newlineBeforeComment { prevOffset.advanceString("\n") j.AddString("\n") diff --git a/internal/bundler/snapshots/snapshots_default.txt b/internal/bundler/snapshots/snapshots_default.txt index d2cafb79902..ce746714e01 100644 --- a/internal/bundler/snapshots/snapshots_default.txt +++ b/internal/bundler/snapshots/snapshots_default.txt @@ -2066,6 +2066,20 @@ const es6_ns_export_namespace = __toModule(require_es6_ns_export_namespace()); const es6_ns_export_class = __toModule(require_es6_ns_export_class()); const es6_ns_export_abstract_class = __toModule(require_es6_ns_export_abstract_class()); +================================================================================ +TestTopLevelAwaitNoBundle +---------- /out.js ---------- +await foo; +for await (foo of bar) + ; + +================================================================================ +TestTopLevelAwaitNoBundleES6 +---------- /out.js ---------- +await foo; +for await (foo of bar) + ; + ================================================================================ TestTopLevelReturn ---------- /out.js ---------- diff --git a/internal/bundler/snapshots/snapshots_loader.txt b/internal/bundler/snapshots/snapshots_loader.txt index 1fbdf974f77..a6f5354070f 100644 --- a/internal/bundler/snapshots/snapshots_loader.txt +++ b/internal/bundler/snapshots/snapshots_loader.txt @@ -115,6 +115,36 @@ var if2 = "test keyword imports"; const x_json = require_x(); console.log(x_json, y_default, small, if2); +================================================================================ +TestLoaderJSONNoBundle +---------- /out.js ---------- +module.exports = {test: 123}; + +================================================================================ +TestLoaderJSONNoBundleCommonJS +---------- /out.js ---------- +module.exports = {test: 123}; + +================================================================================ +TestLoaderJSONNoBundleES6 +---------- /out.js ---------- +var test = 123; +var test_default = {test}; +export { + test_default as default, + test +}; + +================================================================================ +TestLoaderJSONNoBundleIIFE +---------- /out.js ---------- +(() => { + var require_test = __commonJS((exports, module) => { + module.exports = {test: 123}; + }); + require_test(); +})(); + ================================================================================ TestLoaderTextCommonJSAndES6 ---------- /out.js ---------- diff --git a/internal/config/config.go b/internal/config/config.go index 6ca4719d271..f650bc1b6ea 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -130,6 +130,18 @@ func (f Format) KeepES6ImportExportSyntax() bool { return f == FormatPreserve || f == FormatESModule } +func (f Format) String() string { + switch f { + case FormatIIFE: + return "iife" + case FormatCommonJS: + return "cjs" + case FormatESModule: + return "esm" + } + return "" +} + type StdinInfo struct { Loader Loader Contents string @@ -142,11 +154,16 @@ type ExternalModules struct { AbsPaths map[string]bool } -type Options struct { - // true: imports are scanned and bundled along with the file - // false: imports are left alone and the file is passed through as-is - IsBundling bool +type Mode uint8 +const ( + ModePassThrough Mode = iota + ModeConvertFormat + ModeBundle +) + +type Options struct { + Mode Mode RemoveWhitespace bool MinifyIdentifiers bool MangleSyntax bool diff --git a/internal/parser/parser.go b/internal/parser/parser.go index f671c42786a..a12c0c5cc38 100644 --- a/internal/parser/parser.go +++ b/internal/parser/parser.go @@ -7493,7 +7493,7 @@ func (p *parser) maybeRewriteDot(loc ast.Loc, assignTarget ast.AssignTarget, dot p.isImportItem[item.Ref] = true symbol := &p.symbols[item.Ref.InnerIndex] - if !p.IsBundling { + if p.Mode == config.ModePassThrough { // Make sure the printer prints this as a property access symbol.NamespaceAlias = &ast.NamespaceAlias{ NamespaceRef: id.Ref, @@ -7515,7 +7515,7 @@ func (p *parser) maybeRewriteDot(loc ast.Loc, assignTarget ast.AssignTarget, dot // imported module end up in the same module group and the namespace // symbol has never been captured, then we don't need to generate // any code for the namespace at all. - if p.IsBundling { + if p.Mode != config.ModePassThrough { p.ignoreUsage(id.Ref) } @@ -7709,7 +7709,7 @@ func (p *parser) visitExpr(expr ast.Expr) ast.Expr { } func (p *parser) valueForThis(loc ast.Loc) (ast.Expr, bool) { - if p.IsBundling && !p.isThisCaptured { + if p.Mode != config.ModePassThrough && !p.isThisCaptured { if p.hasES6ImportSyntax || p.hasES6ExportSyntax { // In an ES6 module, "this" is supposed to be undefined. Instead of // doing this at runtime using "fn.call(undefined)", we do it at @@ -8388,7 +8388,7 @@ func (p *parser) visitExprInOut(expr ast.Expr, in exprIn) (ast.Expr, exprOut) { // though this is a run-time error, we make it a compile-time error when // bundling because scope hoisting means these will no longer be run-time // errors. - if p.IsBundling && in.assignTarget != ast.AssignTargetNone { + if p.Mode == config.ModeBundle && in.assignTarget != ast.AssignTargetNone { if id, ok := e.Target.Data.(*ast.EIdentifier); ok && p.symbols[id.Ref.InnerIndex].Kind == ast.SymbolImport { if str, ok := e.Index.Data.(*ast.EString); ok && lexer.IsIdentifierUTF16(str.Value) { r := p.source.RangeOfString(e.Index.Loc) @@ -8439,10 +8439,12 @@ func (p *parser) visitExprInOut(expr ast.Expr, in exprIn) (ast.Expr, exprOut) { } // "typeof require" => "'function'" - if id, ok := e.Value.Data.(*ast.EIdentifier); ok && id.Ref == p.requireRef { - p.ignoreUsage(p.requireRef) - p.typeofRequire = &ast.EString{Value: lexer.StringToUTF16("function")} - return ast.Expr{Loc: expr.Loc, Data: p.typeofRequire}, exprOut{} + if p.Mode == config.ModeBundle { + if id, ok := e.Value.Data.(*ast.EIdentifier); ok && id.Ref == p.requireRef { + p.ignoreUsage(p.requireRef) + p.typeofRequire = &ast.EString{Value: lexer.StringToUTF16("function")} + return ast.Expr{Loc: expr.Loc, Data: p.typeofRequire}, exprOut{} + } } if typeof, ok := typeofWithoutSideEffects(e.Value.Data); ok { @@ -8765,7 +8767,7 @@ func (p *parser) visitExprInOut(expr ast.Expr, in exprIn) (ast.Expr, exprOut) { p.importRecordsForCurrentPart = append(p.importRecordsForCurrentPart, importRecordIndex) e.ImportRecordIndex = &importRecordIndex - } else if p.IsBundling { + } else if p.Mode == config.ModeBundle { r := lexer.RangeOfIdentifier(p.source, expr.Loc) p.log.AddRangeWarning(&p.source, r, "This dynamic import will not be bundled because the argument is not a string literal") @@ -8863,36 +8865,43 @@ func (p *parser) visitExprInOut(expr ast.Expr, in exprIn) (ast.Expr, exprOut) { } // Track calls to require() so we can use them while bundling - if id, ok := e.Target.Data.(*ast.EIdentifier); ok && id.Ref == p.requireRef && p.IsBundling { - // There must be one argument - if len(e.Args) != 1 { - r := lexer.RangeOfIdentifier(p.source, e.Target.Loc) - p.log.AddRangeWarning(&p.source, r, fmt.Sprintf( - "This call to \"require\" will not be bundled because it has %d arguments", len(e.Args))) - } else { - arg := e.Args[0] - - // The argument must be a string - if str, ok := arg.Data.(*ast.EString); ok { - // Ignore calls to require() if the control flow is provably dead here. - // We don't want to spend time scanning the required files if they will - // never be used. - if p.isControlFlowDead { - return ast.Expr{Loc: expr.Loc, Data: &ast.ENull{}}, exprOut{} - } + if p.Mode != config.ModePassThrough { + if id, ok := e.Target.Data.(*ast.EIdentifier); ok && id.Ref == p.requireRef { + if p.Mode == config.ModeBundle { + // There must be one argument + if len(e.Args) != 1 { + r := lexer.RangeOfIdentifier(p.source, e.Target.Loc) + p.log.AddRangeWarning(&p.source, r, fmt.Sprintf( + "This call to \"require\" will not be bundled because it has %d arguments", len(e.Args))) + } else { + arg := e.Args[0] + + // The argument must be a string + if str, ok := arg.Data.(*ast.EString); ok { + // Ignore calls to require() if the control flow is provably dead here. + // We don't want to spend time scanning the required files if they will + // never be used. + if p.isControlFlowDead { + return ast.Expr{Loc: expr.Loc, Data: &ast.ENull{}}, exprOut{} + } - importRecordIndex := p.addImportRecord(ast.ImportRequire, arg.Loc, lexer.UTF16ToString(str.Value)) - p.importRecords[importRecordIndex].IsInsideTryBody = p.fnOptsVisit.tryBodyCount != 0 - p.importRecordsForCurrentPart = append(p.importRecordsForCurrentPart, importRecordIndex) + importRecordIndex := p.addImportRecord(ast.ImportRequire, arg.Loc, lexer.UTF16ToString(str.Value)) + p.importRecords[importRecordIndex].IsInsideTryBody = p.fnOptsVisit.tryBodyCount != 0 + p.importRecordsForCurrentPart = append(p.importRecordsForCurrentPart, importRecordIndex) - // Create a new expression to represent the operation - p.ignoreUsage(p.requireRef) - return ast.Expr{Loc: expr.Loc, Data: &ast.ERequire{ImportRecordIndex: importRecordIndex}}, exprOut{} - } + // Create a new expression to represent the operation + p.ignoreUsage(p.requireRef) + return ast.Expr{Loc: expr.Loc, Data: &ast.ERequire{ImportRecordIndex: importRecordIndex}}, exprOut{} + } - r := lexer.RangeOfIdentifier(p.source, e.Target.Loc) - p.log.AddRangeWarning(&p.source, r, - "This call to \"require\" will not be bundled because the argument is not a string literal") + r := lexer.RangeOfIdentifier(p.source, e.Target.Loc) + p.log.AddRangeWarning(&p.source, r, + "This call to \"require\" will not be bundled because the argument is not a string literal") + } + } else if p.OutputFormat == config.FormatESModule { + r := lexer.RangeOfIdentifier(p.source, e.Target.Loc) + p.log.AddRangeWarning(&p.source, r, "Converting \"require\" to \"esm\" is currently not supported") + } } } @@ -8975,7 +8984,7 @@ func (p *parser) valueForDefine(loc ast.Loc, assignTarget ast.AssignTarget, defi func (p *parser) handleIdentifier(loc ast.Loc, assignTarget ast.AssignTarget, e *ast.EIdentifier) ast.Expr { ref := e.Ref - if p.IsBundling && assignTarget != ast.AssignTargetNone { + if p.Mode == config.ModeBundle && assignTarget != ast.AssignTargetNone { if p.symbols[ref.InnerIndex].Kind == ast.SymbolImport { // Create an error for assigning to an import namespace r := lexer.RangeOfIdentifier(p.source, loc) @@ -9066,7 +9075,7 @@ func (p *parser) visitFn(fn *ast.Fn, scopeLoc ast.Loc) { p.argumentsRef = oldArgumentsRef } -func (p *parser) scanForImportsAndExports(stmts []ast.Stmt, isBundling bool) []ast.Stmt { +func (p *parser) scanForImportsAndExports(stmts []ast.Stmt) []ast.Stmt { stmtsEnd := 0 for _, stmt := range stmts { @@ -9161,7 +9170,7 @@ func (p *parser) scanForImportsAndExports(stmts []ast.Stmt, isBundling bool) []a } } - if isBundling { + if p.Mode != config.ModePassThrough { if s.StarNameLoc != nil { // If we're bundling a star import, add any import items we generated // for this namespace while parsing as explicit import items instead. @@ -9251,7 +9260,7 @@ func (p *parser) scanForImportsAndExports(stmts []ast.Stmt, isBundling bool) []a p.importRecordsForCurrentPart = append(p.importRecordsForCurrentPart, s.ImportRecordIndex) // Only track import paths if we want dependencies - if isBundling { + if p.Mode == config.ModeBundle { if s.Alias != nil { // "export * as ns from 'path'" p.namedImports[s.NamespaceRef] = ast.NamedImport{ @@ -9270,7 +9279,7 @@ func (p *parser) scanForImportsAndExports(stmts []ast.Stmt, isBundling bool) []a p.importRecordsForCurrentPart = append(p.importRecordsForCurrentPart, s.ImportRecordIndex) // Only track import paths if we want dependencies - if isBundling { + if p.Mode == config.ModeBundle { for _, item := range s.Items { // Note that the imported alias is not item.Alias, which is the // exported alias. This is somewhat confusing because each @@ -9813,7 +9822,7 @@ func Parse(log logging.Log, source logging.Source, options config.Options) (resu // Strip off a leading "use strict" directive when not bundling directive := "" - if !options.IsBundling && len(stmts) > 0 { + if p.Mode != config.ModeBundle && len(stmts) > 0 { if s, ok := stmts[0].Data.(*ast.SDirective); ok { directive = lexer.UTF16ToString(s.Value) stmts = stmts[1:] @@ -9840,7 +9849,7 @@ func Parse(log logging.Log, source logging.Source, options config.Options) (resu // correctly while handling arrow functions because of the grammar // ambiguities. parts := []ast.Part{} - if !p.IsBundling { + if p.Mode != config.ModeBundle { // When not bundling, everything comes in a single part parts = p.appendPart(parts, stmts) } else { @@ -9918,7 +9927,7 @@ func (p *parser) prepareForVisitPass(options *config.Options) { p.moduleScope = p.currentScope p.hoistSymbols(p.moduleScope) - if options.IsBundling { + if p.Mode != config.ModePassThrough { p.exportsRef = p.declareCommonJSSymbol(ast.SymbolHoisted, "exports") p.requireRef = p.declareCommonJSSymbol(ast.SymbolUnbound, "require") p.moduleRef = p.declareCommonJSSymbol(ast.SymbolHoisted, "module") @@ -9929,7 +9938,7 @@ func (p *parser) prepareForVisitPass(options *config.Options) { } // Convert "import.meta" to a variable if it's not supported in the output format - if p.hasImportMeta && (p.UnsupportedFeatures.Has(compat.ImportMeta) || (options.IsBundling && !p.OutputFormat.KeepES6ImportExportSyntax())) { + if p.hasImportMeta && (p.UnsupportedFeatures.Has(compat.ImportMeta) || (p.Mode != config.ModePassThrough && !p.OutputFormat.KeepES6ImportExportSyntax())) { p.importMetaRef = p.newSymbol(ast.SymbolOther, "import_meta") p.moduleScope.Generated = append(p.moduleScope.Generated, p.importMetaRef) } else { @@ -10079,7 +10088,7 @@ func (p *parser) toAST(source logging.Source, parts []ast.Part, hashbang string, for _, part := range parts { p.importRecordsForCurrentPart = nil p.declaredSymbols = nil - part.Stmts = p.scanForImportsAndExports(part.Stmts, p.IsBundling) + part.Stmts = p.scanForImportsAndExports(part.Stmts) part.ImportRecordIndices = append(part.ImportRecordIndices, p.importRecordsForCurrentPart...) part.DeclaredSymbols = append(part.DeclaredSymbols, p.declaredSymbols...) if len(part.Stmts) > 0 { diff --git a/internal/parser/parser_lower.go b/internal/parser/parser_lower.go index 18557c6f1aa..905f8aabf1f 100644 --- a/internal/parser/parser_lower.go +++ b/internal/parser/parser_lower.go @@ -9,6 +9,7 @@ import ( "github.com/evanw/esbuild/internal/ast" "github.com/evanw/esbuild/internal/compat" + "github.com/evanw/esbuild/internal/config" "github.com/evanw/esbuild/internal/lexer" ) @@ -16,10 +17,16 @@ func (p *parser) markSyntaxFeature(feature compat.Feature, r ast.Range) (didGene didGenerateError = true if !p.UnsupportedFeatures.Has(feature) { - if feature == compat.TopLevelAwait && p.IsBundling { - p.log.AddRangeError(&p.source, r, - "Top-level await is currently not supported when bundling") - return + if feature == compat.TopLevelAwait { + if p.Mode == config.ModeBundle { + p.log.AddRangeError(&p.source, r, "Top-level await is currently not supported when bundling") + return + } + if p.Mode == config.ModeConvertFormat && !p.OutputFormat.KeepES6ImportExportSyntax() { + p.log.AddRangeError(&p.source, r, fmt.Sprintf( + "Top-level await is currently not supported with the %q output format", p.OutputFormat.String())) + return + } } didGenerateError = false diff --git a/lib/common.ts b/lib/common.ts index f6a38e44cf9..dde93c51f6a 100644 --- a/lib/common.ts +++ b/lib/common.ts @@ -12,6 +12,8 @@ function pushCommonFlags(flags: string[], options: types.CommonOptions, isTTY: b if (options.target instanceof Array) flags.push(`--target=${Array.from(options.target).map(validateTarget).join(',')}`) else flags.push(`--target=${validateTarget(options.target)}`) } + if (options.format) flags.push(`--format=${options.format}`); + if (options.globalName) flags.push(`--global-name=${options.globalName}`); if (options.strict === true) flags.push(`--strict`); else if (options.strict) for (let key of options.strict) flags.push(`--strict:${key}`); @@ -43,14 +45,12 @@ function flagsForBuildOptions(options: types.BuildOptions, isTTY: boolean): [str pushCommonFlags(flags, options, isTTY, 'info'); if (options.sourcemap) flags.push(`--sourcemap${options.sourcemap === true ? '' : `=${options.sourcemap}`}`); - if (options.globalName) flags.push(`--global-name=${options.globalName}`); if (options.bundle) flags.push('--bundle'); if (options.splitting) flags.push('--splitting'); if (options.metafile) flags.push(`--metafile=${options.metafile}`); if (options.outfile) flags.push(`--outfile=${options.outfile}`); if (options.outdir) flags.push(`--outdir=${options.outdir}`); if (options.platform) flags.push(`--platform=${options.platform}`); - if (options.format) flags.push(`--format=${options.format}`); if (options.tsconfig) flags.push(`--tsconfig=${options.tsconfig}`); if (options.resolveExtensions) flags.push(`--resolve-extensions=${options.resolveExtensions.join(',')}`); if (options.external) for (let name of options.external) flags.push(`--external:${name}`); diff --git a/lib/types.ts b/lib/types.ts index beadc810b01..418aa38e437 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -6,6 +6,8 @@ export type Strict = 'nullish-coalescing' | 'optional-chaining' | 'class-fields' export interface CommonOptions { sourcemap?: boolean | 'inline' | 'external'; + format?: Format; + globalName?: string; target?: string | string[]; strict?: boolean | Strict[]; @@ -25,14 +27,12 @@ export interface CommonOptions { } export interface BuildOptions extends CommonOptions { - globalName?: string; bundle?: boolean; splitting?: boolean; outfile?: string; metafile?: string; outdir?: string; platform?: Platform; - format?: Format; color?: boolean; external?: string[]; loader?: { [ext: string]: Loader }; diff --git a/pkg/api/api.go b/pkg/api/api.go index 1759826b467..21ca57db8da 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -256,10 +256,12 @@ type TransformOptions struct { ErrorLimit int LogLevel LogLevel - Sourcemap SourceMap - Target Target - Engines []Engine - Strict StrictOptions + Sourcemap SourceMap + Target Target + Format Format + GlobalName string + Engines []Engine + Strict StrictOptions MinifyWhitespace bool MinifyIdentifiers bool diff --git a/pkg/api/api_impl.go b/pkg/api/api_impl.go index 8318131a9f8..5ead9f91044 100644 --- a/pkg/api/api_impl.go +++ b/pkg/api/api_impl.go @@ -421,7 +421,6 @@ func buildImpl(buildOpts BuildOptions) BuildResult { RemoveWhitespace: buildOpts.MinifyWhitespace, MinifyIdentifiers: buildOpts.MinifyIdentifiers, ModuleName: buildOpts.GlobalName, - IsBundling: buildOpts.Bundle, CodeSplitting: buildOpts.Splitting, OutputFormat: validateFormat(buildOpts.Format), AbsOutputFile: validatePath(log, realFS, buildOpts.Outfile), @@ -481,11 +480,8 @@ func buildImpl(buildOpts BuildOptions) BuildResult { options.AbsOutputDir = realFS.Cwd() } - if !options.IsBundling { + if !buildOpts.Bundle { // Disallow bundle-only options when not bundling - if options.OutputFormat != config.FormatPreserve { - log.AddError(nil, ast.Loc{}, "Cannot use \"format\" without \"bundle\"") - } if len(options.ExternalModules.NodeModules) > 0 || len(options.ExternalModules.AbsPaths) > 0 { log.AddError(nil, ast.Loc{}, "Cannot use \"external\" without \"bundle\"") } @@ -499,6 +495,13 @@ func buildImpl(buildOpts BuildOptions) BuildResult { } } + // Set the output mode using other settings + if buildOpts.Bundle { + options.Mode = config.ModeBundle + } else if options.OutputFormat != config.FormatPreserve { + options.Mode = config.ModeConvertFormat + } + // Code splitting is experimental and currently only enabled for ES6 modules if options.CodeSplitting && options.OutputFormat != config.FormatESModule { log.AddError(nil, ast.Loc{}, "Splitting currently only works with the \"esm\" format") @@ -600,6 +603,8 @@ func transformImpl(input string, transformOpts TransformOptions) TransformResult }, Defines: validateDefines(log, transformOpts.Defines, transformOpts.PureFunctions), SourceMap: validateSourceMap(transformOpts.Sourcemap), + OutputFormat: validateFormat(transformOpts.Format), + ModuleName: transformOpts.GlobalName, MangleSyntax: transformOpts.MinifySyntax, RemoveWhitespace: transformOpts.MinifyWhitespace, MinifyIdentifiers: transformOpts.MinifyIdentifiers, @@ -619,6 +624,11 @@ func transformImpl(input string, transformOpts TransformOptions) TransformResult "Must use \"sourcefile\" with \"sourcemap\" to set the original file name") } + // Set the output mode using other settings + if options.OutputFormat != config.FormatPreserve { + options.Mode = config.ModeConvertFormat + } + var results []bundler.OutputFile // Stop now if there were errors diff --git a/pkg/cli/cli_impl.go b/pkg/cli/cli_impl.go index 0e5db689054..218f1d90b3f 100644 --- a/pkg/cli/cli_impl.go +++ b/pkg/cli/cli_impl.go @@ -106,8 +106,12 @@ func parseOptionsImpl(osArgs []string, buildOpts *api.BuildOptions, transformOpt case strings.HasPrefix(arg, "--resolve-extensions=") && buildOpts != nil: buildOpts.ResolveExtensions = strings.Split(arg[len("--resolve-extensions="):], ",") - case strings.HasPrefix(arg, "--global-name=") && buildOpts != nil: - buildOpts.GlobalName = arg[len("--global-name="):] + case strings.HasPrefix(arg, "--global-name="): + if buildOpts != nil { + buildOpts.GlobalName = arg[len("--global-name="):] + } else { + transformOpts.GlobalName = arg[len("--global-name="):] + } case strings.HasPrefix(arg, "--metafile=") && buildOpts != nil: buildOpts.Metafile = arg[len("--metafile="):] @@ -238,15 +242,27 @@ func parseOptionsImpl(osArgs []string, buildOpts *api.BuildOptions, transformOpt return fmt.Errorf("Invalid platform: %q (valid: browser, node)", value) } - case strings.HasPrefix(arg, "--format=") && buildOpts != nil: + case strings.HasPrefix(arg, "--format="): value := arg[len("--format="):] switch value { case "iife": - buildOpts.Format = api.FormatIIFE + if buildOpts != nil { + buildOpts.Format = api.FormatIIFE + } else { + transformOpts.Format = api.FormatIIFE + } case "cjs": - buildOpts.Format = api.FormatCommonJS + if buildOpts != nil { + buildOpts.Format = api.FormatCommonJS + } else { + transformOpts.Format = api.FormatCommonJS + } case "esm": - buildOpts.Format = api.FormatESModule + if buildOpts != nil { + buildOpts.Format = api.FormatESModule + } else { + transformOpts.Format = api.FormatESModule + } default: return fmt.Errorf("Invalid format: %q (valid: iife, cjs, esm)", value) } diff --git a/scripts/end-to-end-tests.js b/scripts/end-to-end-tests.js index 8b942578583..876eb348794 100644 --- a/scripts/end-to-end-tests.js +++ b/scripts/end-to-end-tests.js @@ -324,6 +324,299 @@ }), ) + // Test for format conversion without bundling + tests.push( + // ESM => ESM + test(['in.js', '--outfile=node.js', '--format=esm'], { + 'in.js': ` + import {exists} from 'fs' + if (!exists) throw 'fail' + `, + }), + test(['in.js', '--outfile=node.js', '--format=esm'], { + 'in.js': ` + import fs from 'fs' + if (!fs.exists) throw 'fail' + `, + }), + test(['in.js', '--outfile=node.js', '--format=esm'], { + 'in.js': ` + import * as fs from 'fs' + if (!fs.exists) throw 'fail' + `, + }), + test(['in.js', '--outfile=node.js', '--format=esm'], { + 'in.js': ` + let fn = async () => { + let fs = await import('fs') + if (!fs.exists) throw 'fail' + } + export {fn as async} + `, + }, { async: true }), + test(['in.js', '--outfile=out.js', '--format=esm'], { + 'in.js': ` + export let foo = 'abc' + export default function() { + return 123 + } + `, + 'node.js': ` + import * as out from './out.js' + if (out.foo !== 'abc' || out.default() !== 123) throw 'fail' + `, + }), + + // ESM => CJS + test(['in.js', '--outfile=node.js', '--format=cjs'], { + 'in.js': ` + import {exists} from 'fs' + if (!exists) throw 'fail' + `, + }), + test(['in.js', '--outfile=node.js', '--format=cjs'], { + 'in.js': ` + import fs from 'fs' + if (!fs.exists) throw 'fail' + `, + }), + test(['in.js', '--outfile=node.js', '--format=cjs'], { + 'in.js': ` + import * as fs from 'fs' + if (!fs.exists) throw 'fail' + `, + }), + test(['in.js', '--outfile=node.js', '--format=cjs'], { + 'in.js': ` + let fn = async () => { + let fs = await import('fs') + if (!fs.exists) throw 'fail' + } + export {fn as async} + `, + }, { async: true }), + test(['in.js', '--outfile=out.js', '--format=cjs'], { + 'in.js': ` + export let foo = 'abc' + export default function() { + return 123 + } + `, + 'node.js': ` + const out = require('./out.js') + if (out.foo !== 'abc' || out.default() !== 123) throw 'fail' + `, + }), + + // ESM => IIFE + test(['in.js', '--outfile=node.js', '--format=iife'], { + 'in.js': ` + import {exists} from 'fs' + if (!exists) throw 'fail' + `, + }), + test(['in.js', '--outfile=node.js', '--format=iife'], { + 'in.js': ` + import fs from 'fs' + if (!fs.exists) throw 'fail' + `, + }), + test(['in.js', '--outfile=node.js', '--format=iife'], { + 'in.js': ` + import * as fs from 'fs' + if (!fs.exists) throw 'fail' + `, + }), + test(['in.js', '--outfile=out.js', '--format=iife', '--global-name=test'], { + 'in.js': ` + let fn = async () => { + let fs = await import('fs') + if (!fs.exists) throw 'fail' + } + export {fn as async} + `, + 'node.js': ` + const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8') + const out = new Function('require', code + '; return test')(require) + exports.async = out.async + `, + }, { async: true }), + test(['in.js', '--outfile=out.js', '--format=iife', '--global-name=test'], { + 'in.js': ` + export let foo = 'abc' + export default function() { + return 123 + } + `, + 'node.js': ` + const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8') + const out = new Function(code + '; return test')() + if (out.foo !== 'abc' || out.default() !== 123) throw 'fail' + `, + }), + + // JSON + test(['in.json', '--outfile=out.js', '--format=esm'], { + 'in.json': `{"foo": 123}`, + 'node.js': ` + import def from './out.js' + import {foo} from './out.js' + if (foo !== 123 || def.foo !== 123) throw 'fail' + `, + }), + test(['in.json', '--outfile=out.js', '--format=cjs'], { + 'in.json': `{"foo": 123}`, + 'node.js': ` + const out = require('./out.js') + if (out.foo !== 123) throw 'fail' + `, + }), + test(['in.json', '--outfile=out.js', '--format=iife', '--global-name=test'], { + 'in.json': `{"foo": 123}`, + 'node.js': ` + const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8') + const out = new Function(code + '; return test')() + if (out.foo !== 123) throw 'fail' + `, + }), + + // CJS => CJS + test(['in.js', '--outfile=node.js', '--format=cjs'], { + 'in.js': ` + const {exists} = require('fs') + if (!exists) throw 'fail' + `, + }), + test(['in.js', '--outfile=node.js', '--format=cjs'], { + 'in.js': ` + const fs = require('fs') + if (!fs.exists) throw 'fail' + `, + }), + test(['in.js', '--outfile=out.js', '--format=cjs'], { + 'in.js': ` + module.exports = 123 + `, + 'node.js': ` + const out = require('./out.js') + if (out !== 123) throw 'fail' + `, + }), + test(['in.js', '--outfile=out.js', '--format=cjs'], { + 'in.js': ` + exports.foo = 123 + `, + 'node.js': ` + const out = require('./out.js') + if (out.foo !== 123) throw 'fail' + `, + }), + + // CJS => IIFE + test(['in.js', '--outfile=out.js', '--format=iife'], { + 'in.js': ` + const {exists} = require('fs') + if (!exists) throw 'fail' + `, + 'node.js': ` + const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8') + new Function('require', code)(require) + `, + }), + test(['in.js', '--outfile=out.js', '--format=iife'], { + 'in.js': ` + const fs = require('fs') + if (!fs.exists) throw 'fail' + `, + 'node.js': ` + const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8') + new Function('require', code)(require) + `, + }), + test(['in.js', '--outfile=out.js', '--format=iife', '--global-name=test'], { + 'in.js': ` + module.exports = 123 + `, + 'node.js': ` + const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8') + const out = new Function(code + '; return test')() + if (out !== 123) throw 'fail' + `, + }), + test(['in.js', '--outfile=out.js', '--format=iife', '--global-name=test'], { + 'in.js': ` + exports.foo = 123 + `, + 'node.js': ` + const code = require('fs').readFileSync(__dirname + '/out.js', 'utf8') + const out = new Function(code + '; return test')() + if (out.foo !== 123) throw 'fail' + `, + }), + + // CJS => ESM + test(['in.js', '--outfile=out.js', '--format=esm'], { + 'in.js': ` + const {exists} = require('fs') + if (!exists) throw 'fail' + `, + 'node.js': ` + let fn = async () => { + let error + await import('./out.js').catch(x => error = x) + if (!error || error.message !== 'require is not defined') throw 'fail' + } + export {fn as async} + `, + }, { + async: true, + expectedStderr: `in.js:2:25: warning: Converting "require" to "esm" is currently not supported + const {exists} = require('fs') + ~~~~~~~ +1 warning +`, + }), + test(['in.js', '--outfile=out.js', '--format=esm'], { + 'in.js': ` + const fs = require('fs') + if (!fs.exists) throw 'fail' + `, + 'node.js': ` + let fn = async () => { + let error + await import('./out.js').catch(x => error = x) + if (!error || error.message !== 'require is not defined') throw 'fail' + } + export {fn as async} + `, + }, { + async: true, + expectedStderr: `in.js:2:19: warning: Converting "require" to "esm" is currently not supported + const fs = require('fs') + ~~~~~~~ +1 warning +`, + }), + test(['in.js', '--outfile=out.js', '--format=esm'], { + 'in.js': ` + module.exports = 123 + `, + 'node.js': ` + import out from './out.js' + if (out !== 123) throw 'fail' + `, + }), + test(['in.js', '--outfile=out.js', '--format=esm'], { + 'in.js': ` + exports.foo = 123 + `, + 'node.js': ` + import out from './out.js' + if (out.foo !== 123) throw 'fail' + `, + }), + ) + // Tests for "arguments" scope issues tests.push( test(['in.js', '--outfile=node.js', '--minify'], { @@ -995,9 +1288,10 @@ in.js:24:30: warning: Writing to getter-only property "#getter" will throw function test(args, files, options) { return async () => { const hasBundle = args.includes('--bundle') + const hasIIFE = args.includes('--format=iife') const hasCJS = args.includes('--format=cjs') const hasESM = args.includes('--format=esm') - const formats = hasCJS || !hasBundle ? ['cjs'] : hasESM ? ['esm'] : ['cjs', 'esm'] + const formats = hasIIFE ? ['iife'] : hasESM ? ['esm'] : hasCJS || !hasBundle ? ['cjs'] : ['cjs', 'esm'] const expectedStderr = options && options.expectedStderr || ''; // If the test doesn't specify a format, test both formats @@ -1031,6 +1325,7 @@ in.js:24:30: warning: Writing to getter-only property "#getter" will throw let testExports switch (format) { case 'cjs': + case 'iife': await writeFileAsync(path.join(thisTestDir, 'package.json'), '{"type": "commonjs"}') testExports = (await import(url.pathToFileURL(`${nodePath}.js`))).default break @@ -1049,14 +1344,17 @@ in.js:24:30: warning: Writing to getter-only property "#getter" will throw } // Clean up test output - rimraf.sync(thisTestDir, { disableGlob: true }) + rimraf.sync(thisTestDir, { disableGlob: true }); } catch (e) { if (e && e.stderr !== void 0) { try { assert.strictEqual(e.stderr, expectedStderr); - return true; + + // Clean up test output + rimraf.sync(thisTestDir, { disableGlob: true }); + continue; } catch (e2) { e = e2; } diff --git a/scripts/js-api-tests.js b/scripts/js-api-tests.js index b3ddecaa972..2a661aad845 100644 --- a/scripts/js-api-tests.js +++ b/scripts/js-api-tests.js @@ -494,11 +494,21 @@ let transformTests = { assert.strictEqual(js, `module.exports = {x: "y"};\n`) }, + async jsonESM({ service }) { + const { js } = await service.transform(`{ "x": "y" }`, { loader: 'json', format: 'esm' }) + assert.strictEqual(js, `var x = "y";\nvar stdin_default = {x};\nexport {\n stdin_default as default,\n x\n};\n`) + }, + async text({ service }) { const { js } = await service.transform(`This is some text`, { loader: 'text' }) assert.strictEqual(js, `module.exports = "This is some text";\n`) }, + async textESM({ service }) { + const { js } = await service.transform(`This is some text`, { loader: 'text', format: 'esm' }) + assert.strictEqual(js, `var stdin_default = "This is some text";\nexport {\n stdin_default as default\n};\n`) + }, + async base64({ service }) { const { js } = await service.transform(`\x00\x01\x02`, { loader: 'base64' }) assert.strictEqual(js, `module.exports = "AAEC";\n`)