From 871343df8135ab90120725810f7bf8cdf1bf2dd2 Mon Sep 17 00:00:00 2001 From: Liu Bowen Date: Tue, 1 Jun 2021 22:52:31 +0800 Subject: [PATCH 1/5] fix(linker): add missing esm flag fix #1333 #1323 Signed-off-by: Liu Bowen --- internal/bundler/linker.go | 10 ++-- internal/bundler/snapshots/snapshots_dce.txt | 7 +++ .../bundler/snapshots/snapshots_default.txt | 46 +++++++++++++++---- .../snapshots/snapshots_importstar.txt | 27 +++++++++++ .../snapshots/snapshots_importstar_ts.txt | 7 +++ .../bundler/snapshots/snapshots_loader.txt | 1 + .../snapshots/snapshots_packagejson.txt | 2 + .../bundler/snapshots/snapshots_splitting.txt | 29 ++++++++---- internal/bundler/snapshots/snapshots_ts.txt | 5 ++ 9 files changed, 113 insertions(+), 21 deletions(-) diff --git a/internal/bundler/linker.go b/internal/bundler/linker.go index 78a0ccfd634..c1a35553cac 100644 --- a/internal/bundler/linker.go +++ b/internal/bundler/linker.go @@ -1726,10 +1726,11 @@ func (c *linkerContext) createExportsForFile(sourceIndex uint32) { } } - // Prefix this part with "var exports = {}" if this isn't a CommonJS module + // Prefix this part with "var exports = { __esModule: true }" if this isn't a CommonJS module declaredSymbols := []js_ast.DeclaredSymbol{} var nsExportStmts []js_ast.Stmt - if repr.AST.ExportsKind != js_ast.ExportsCommonJS && (!file.IsEntryPoint() || c.options.OutputFormat != config.FormatCommonJS) { + isNotCommonJSAndEntry := repr.AST.ExportsKind != js_ast.ExportsCommonJS && (!file.IsEntryPoint() || c.options.OutputFormat != config.FormatCommonJS) + if isNotCommonJSAndEntry { nsExportStmts = append(nsExportStmts, js_ast.Stmt{Data: &js_ast.SLocal{Decls: []js_ast.Decl{{ Binding: js_ast.Binding{Data: &js_ast.BIdentifier{Ref: repr.AST.ExportsRef}}, ValueOrNil: js_ast.Expr{Data: &js_ast.EObject{}}, @@ -1744,8 +1745,9 @@ func (c *linkerContext) createExportsForFile(sourceIndex uint32) { // "__markAsModule" which sets the "__esModule" property to true. This must // be done before any to "require()" or circular imports of multiple modules // that have been each converted from ESM to CommonJS may not work correctly. - if repr.AST.ExportKeyword.Len > 0 && (repr.AST.ExportsKind == js_ast.ExportsCommonJS || - (file.IsEntryPoint() && c.options.OutputFormat == config.FormatCommonJS)) { + if (repr.AST.ExportKeyword.Len > 0 && (repr.AST.ExportsKind == js_ast.ExportsCommonJS || + (file.IsEntryPoint() && c.options.OutputFormat == config.FormatCommonJS))) || + isNotCommonJSAndEntry { runtimeRepr := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr) markAsModuleRef := runtimeRepr.AST.ModuleScope.Members["__markAsModule"].Ref nsExportStmts = append(nsExportStmts, js_ast.Stmt{Data: &js_ast.SExpr{Value: js_ast.Expr{Data: &js_ast.ECall{ diff --git a/internal/bundler/snapshots/snapshots_dce.txt b/internal/bundler/snapshots/snapshots_dce.txt index 8c844e2522a..277b1b152cf 100644 --- a/internal/bundler/snapshots/snapshots_dce.txt +++ b/internal/bundler/snapshots/snapshots_dce.txt @@ -145,6 +145,7 @@ TestPackageJsonSideEffectsArrayKeepMainImplicitMain ---------- /out.js ---------- // Users/user/project/node_modules/demo-pkg/index-main.js var index_main_exports = {}; +__markAsModule(index_main_exports); __export(index_main_exports, { foo: () => foo }); @@ -191,6 +192,7 @@ TestPackageJsonSideEffectsArrayKeepModuleImplicitMain ---------- /out.js ---------- // Users/user/project/node_modules/demo-pkg/index-main.js var index_main_exports = {}; +__markAsModule(index_main_exports); __export(index_main_exports, { foo: () => foo }); @@ -258,6 +260,7 @@ var init_b = __esm({ // Users/user/project/node_modules/a/index.js var a_exports = {}; +__markAsModule(a_exports); __export(a_exports, { foo: () => foo }); @@ -345,6 +348,7 @@ TestPackageJsonSideEffectsFalseKeepBareImportAndRequireES6 ---------- /out.js ---------- // Users/user/project/node_modules/demo-pkg/index.js var demo_pkg_exports = {}; +__markAsModule(demo_pkg_exports); __export(demo_pkg_exports, { foo: () => foo }); @@ -405,6 +409,7 @@ TestPackageJsonSideEffectsFalseKeepStarImportES6 ---------- /out.js ---------- // Users/user/project/node_modules/demo-pkg/index.js var demo_pkg_exports = {}; +__markAsModule(demo_pkg_exports); __export(demo_pkg_exports, { foo: () => foo }); @@ -450,6 +455,7 @@ var init_b = __esm({ // Users/user/project/node_modules/a/index.js var a_exports = {}; +__markAsModule(a_exports); __export(a_exports, { foo: () => foo }); @@ -678,6 +684,7 @@ var init_lib = __esm({ // cjs.js var cjs_exports = {}; +__markAsModule(cjs_exports); __export(cjs_exports, { default: () => cjs_default }); diff --git a/internal/bundler/snapshots/snapshots_default.txt b/internal/bundler/snapshots/snapshots_default.txt index 6fa43a56ee6..7e782f5d341 100644 --- a/internal/bundler/snapshots/snapshots_default.txt +++ b/internal/bundler/snapshots/snapshots_default.txt @@ -244,6 +244,7 @@ TestCommonJSFromES6 ---------- /out.js ---------- // foo.js var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -257,6 +258,7 @@ var init_foo = __esm({ // bar.js var bar_exports = {}; +__markAsModule(bar_exports); __export(bar_exports, { bar: () => bar }); @@ -492,6 +494,7 @@ TestEmptyExportClauseBundleAsCommonJSIssue910 ---------- /out.js ---------- // types.mjs var types_exports = {}; +__markAsModule(types_exports); var init_types = __esm({ "types.mjs"() { } @@ -548,6 +551,7 @@ var init_a = __esm({ // b.js var b_exports = {}; +__markAsModule(b_exports); __export(b_exports, { xyz: () => xyz }); @@ -560,6 +564,7 @@ var init_b = __esm({ // commonjs.js var commonjs_exports = {}; +__markAsModule(commonjs_exports); __export(commonjs_exports, { C: () => Class, Class: () => Class, @@ -589,6 +594,7 @@ var init_commonjs = __esm({ // c.js var c_exports = {}; +__markAsModule(c_exports); __export(c_exports, { default: () => c_default2 }); @@ -603,6 +609,7 @@ var init_c = __esm({ // d.js var d_exports = {}; +__markAsModule(d_exports); __export(d_exports, { default: () => d_default }); @@ -618,6 +625,7 @@ var init_d = __esm({ // e.js var e_exports = {}; +__markAsModule(e_exports); __export(e_exports, { default: () => e_default }); @@ -630,6 +638,7 @@ var init_e = __esm({ // f.js var f_exports = {}; +__markAsModule(f_exports); __export(f_exports, { default: () => foo }); @@ -643,6 +652,7 @@ var init_f = __esm({ // g.js var g_exports = {}; +__markAsModule(g_exports); __export(g_exports, { default: () => g_default }); @@ -655,6 +665,7 @@ var init_g = __esm({ // h.js var h_exports = {}; +__markAsModule(h_exports); __export(h_exports, { default: () => foo2 }); @@ -683,6 +694,7 @@ var abc = void 0; // b.js var b_exports = {}; +__markAsModule(b_exports); __export(b_exports, { xyz: () => xyz }); @@ -715,6 +727,7 @@ TestExportFormsIIFE var globalName = (() => { // entry.js var entry_exports = {}; + __markAsModule(entry_exports); __export(entry_exports, { C: () => Class, Class: () => Class, @@ -732,6 +745,7 @@ var globalName = (() => { // b.js var b_exports = {}; + __markAsModule(b_exports); __export(b_exports, { xyz: () => xyz }); @@ -802,6 +816,7 @@ TestExportsAndModuleFormatCommonJS ---------- /out.js ---------- // foo/test.js var test_exports = {}; +__markAsModule(test_exports); __export(test_exports, { foo: () => foo }); @@ -809,6 +824,7 @@ var foo = 123; // bar/test.js var test_exports2 = {}; +__markAsModule(test_exports2); __export(test_exports2, { bar: () => bar }); @@ -822,6 +838,7 @@ TestExternalES6ConvertedToCommonJS ---------- /out.js ---------- // a.js var a_exports = {}; +__markAsModule(a_exports); __export(a_exports, { ns: () => ns }); @@ -833,6 +850,7 @@ var init_a = __esm({ // b.js var b_exports = {}; +__markAsModule(b_exports); __export(b_exports, { ns: () => ns2 }); @@ -844,6 +862,7 @@ var init_b = __esm({ // c.js var c_exports = {}; +__markAsModule(c_exports); __export(c_exports, { ns: () => ns3 }); @@ -855,6 +874,7 @@ var init_c = __esm({ // d.js var d_exports = {}; +__markAsModule(d_exports); __export(d_exports, { ns: () => ns4 }); @@ -866,6 +886,7 @@ var init_d = __esm({ // e.js var e_exports = {}; +__markAsModule(e_exports); import * as x_star from "x"; var init_e = __esm({ "e.js"() { @@ -1815,21 +1836,23 @@ import("foo");import(foo()); TestMinifiedExportsAndModuleFormatCommonJS ---------- /out.js ---------- // foo/test.js -var o = {}; -s(o, { - foo: () => p +var t = {}; +f(t); +p(t, { + foo: () => l }); -var p = 123; +var l = 123; // bar/test.js -var t = {}; -s(t, { - bar: () => l +var r = {}; +f(r); +p(r, { + bar: () => m }); -var l = 123; +var m = 123; // entry.js -console.log(exports, module.exports, o, t); +console.log(exports, module.exports, t, r); ================================================================================ TestMinifyArguments @@ -2866,6 +2889,7 @@ var require_cjs = __commonJS({ // dummy.js var dummy_exports = {}; +__markAsModule(dummy_exports); __export(dummy_exports, { dummy: () => dummy }); @@ -3132,6 +3156,7 @@ TestTopLevelAwaitAllowedImportWithoutSplitting ---------- /out.js ---------- // c.js var c_exports = {}; +__markAsModule(c_exports); var init_c = __esm({ async "c.js"() { await 0; @@ -3140,6 +3165,7 @@ var init_c = __esm({ // b.js var b_exports = {}; +__markAsModule(b_exports); var init_b = __esm({ async "b.js"() { await init_c(); @@ -3148,6 +3174,7 @@ var init_b = __esm({ // a.js var a_exports = {}; +__markAsModule(a_exports); var init_a = __esm({ async "a.js"() { await init_b(); @@ -3156,6 +3183,7 @@ var init_a = __esm({ // entry.js var entry_exports = {}; +__markAsModule(entry_exports); var init_entry = __esm({ async "entry.js"() { init_a(); diff --git a/internal/bundler/snapshots/snapshots_importstar.txt b/internal/bundler/snapshots/snapshots_importstar.txt index adeda10db8d..5f5081dfd3f 100644 --- a/internal/bundler/snapshots/snapshots_importstar.txt +++ b/internal/bundler/snapshots/snapshots_importstar.txt @@ -94,6 +94,7 @@ TestExportSelfAsNamespaceES6 ---------- /out.js ---------- // entry.js var entry_exports = {}; +__markAsModule(entry_exports); __export(entry_exports, { foo: () => foo, ns: () => entry_exports @@ -147,6 +148,7 @@ TestExportSelfIIFEWithName var someName = (() => { // entry.js var entry_exports = {}; + __markAsModule(entry_exports); __export(entry_exports, { foo: () => foo }); @@ -212,6 +214,7 @@ console.log(internal_default, internal_default); ---------- /out/internal-ns.js ---------- // internal.js var internal_exports = {}; +__markAsModule(internal_exports); __export(internal_exports, { default: () => internal_default }); @@ -223,6 +226,7 @@ console.log(internal_default, internal_exports); ---------- /out/internal-ns-default.js ---------- // internal.js var internal_exports = {}; +__markAsModule(internal_exports); __export(internal_exports, { default: () => internal_default }); @@ -234,6 +238,7 @@ console.log(internal_default, internal_exports, internal_default); ---------- /out/internal-ns-def.js ---------- // internal.js var internal_exports = {}; +__markAsModule(internal_exports); __export(internal_exports, { default: () => internal_default }); @@ -278,6 +283,7 @@ TestImportExportSelfAsNamespaceES6 ---------- /out.js ---------- // entry.js var entry_exports = {}; +__markAsModule(entry_exports); __export(entry_exports, { foo: () => foo, ns: () => entry_exports @@ -346,6 +352,7 @@ TestImportStarAndCommonJS ---------- /out.js ---------- // foo.js var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -366,6 +373,7 @@ TestImportStarCapture ---------- /out.js ---------- // foo.js var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -425,6 +433,7 @@ TestImportStarExportImportStarCapture ---------- /out.js ---------- // foo.js var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -439,6 +448,7 @@ TestImportStarExportImportStarNoCapture ---------- /out.js ---------- // foo.js var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -460,6 +470,7 @@ TestImportStarExportStarAsCapture ---------- /out.js ---------- // foo.js var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -474,6 +485,7 @@ TestImportStarExportStarAsNoCapture ---------- /out.js ---------- // foo.js var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -495,6 +507,7 @@ TestImportStarExportStarCapture ---------- /out.js ---------- // bar.js var bar_exports = {}; +__markAsModule(bar_exports); __export(bar_exports, { foo: () => foo }); @@ -521,6 +534,7 @@ TestImportStarExportStarOmitAmbiguous ---------- /out.js ---------- // common.js var common_exports = {}; +__markAsModule(common_exports); __export(common_exports, { x: () => x, z: () => z @@ -599,12 +613,14 @@ TestImportStarOfExportStarAs ---------- /out.js ---------- // foo.js var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { bar_ns: () => bar_exports }); // bar.js var bar_exports = {}; +__markAsModule(bar_exports); __export(bar_exports, { bar: () => bar }); @@ -625,6 +641,7 @@ TestIssue176 ---------- /out.js ---------- // folders/index.js var folders_exports = {}; +__markAsModule(folders_exports); __export(folders_exports, { foo: () => foo }); @@ -654,6 +671,7 @@ TestNamespaceImportMissingES6 ---------- /out.js ---------- // foo.js var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { x: () => x }); @@ -667,6 +685,7 @@ TestNamespaceImportReExportStarMissingES6 ---------- /out.js ---------- // foo.js var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { x: () => x }); @@ -726,6 +745,7 @@ TestReExportNamespaceImportMissingES6 ---------- /out.js ---------- // bar.js var bar_exports = {}; +__markAsModule(bar_exports); __export(bar_exports, { x: () => x }); @@ -739,6 +759,7 @@ TestReExportNamespaceImportUnusedMissingES6 ---------- /out.js ---------- // bar.js var bar_exports = {}; +__markAsModule(bar_exports); __export(bar_exports, { x: () => x }); @@ -752,6 +773,7 @@ TestReExportOtherFileExportSelfAsNamespaceES6 ---------- /out.js ---------- // foo.js var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo, ns: () => foo_exports @@ -767,6 +789,7 @@ TestReExportOtherFileImportExportSelfAsNamespaceES6 ---------- /out.js ---------- // foo.js var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo, ns: () => foo_exports @@ -819,6 +842,7 @@ TestReExportStarAsExternalIIFE var mod = (() => { // entry.js var entry_exports = {}; + __markAsModule(entry_exports); __export(entry_exports, { out: () => out }); @@ -831,6 +855,7 @@ TestReExportStarAsIIFENoBundle ---------- /out.js ---------- var mod = (() => { var entry_exports = {}; + __markAsModule(entry_exports); __export(entry_exports, { out: () => out }); @@ -868,6 +893,7 @@ TestReExportStarExternalIIFE var mod = (() => { // entry.js var entry_exports = {}; + __markAsModule(entry_exports); __reExport(entry_exports, __toModule(__require("foo"))); return entry_exports; })(); @@ -877,6 +903,7 @@ TestReExportStarIIFENoBundle ---------- /out.js ---------- var mod = (() => { var entry_exports = {}; + __markAsModule(entry_exports); __reExport(entry_exports, __toModule(require("foo"))); return entry_exports; })(); diff --git a/internal/bundler/snapshots/snapshots_importstar_ts.txt b/internal/bundler/snapshots/snapshots_importstar_ts.txt index 0ff0a4304e0..6d94c857b8e 100644 --- a/internal/bundler/snapshots/snapshots_importstar_ts.txt +++ b/internal/bundler/snapshots/snapshots_importstar_ts.txt @@ -2,6 +2,7 @@ TestTSImportStarAndCommonJS ---------- /out.js ---------- // foo.ts var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -22,6 +23,7 @@ TestTSImportStarCapture ---------- /out.js ---------- // foo.ts var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -73,6 +75,7 @@ TestTSImportStarExportImportStarCapture ---------- /out.js ---------- // foo.ts var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -87,6 +90,7 @@ TestTSImportStarExportImportStarNoCapture ---------- /out.js ---------- // foo.ts var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -108,6 +112,7 @@ TestTSImportStarExportStarAsCapture ---------- /out.js ---------- // foo.ts var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -122,6 +127,7 @@ TestTSImportStarExportStarAsNoCapture ---------- /out.js ---------- // foo.ts var foo_exports = {}; +__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -143,6 +149,7 @@ TestTSImportStarExportStarCapture ---------- /out.js ---------- // bar.ts var bar_exports = {}; +__markAsModule(bar_exports); __export(bar_exports, { foo: () => foo }); diff --git a/internal/bundler/snapshots/snapshots_loader.txt b/internal/bundler/snapshots/snapshots_loader.txt index 33e270f4c4c..32bdf7e9d7a 100644 --- a/internal/bundler/snapshots/snapshots_loader.txt +++ b/internal/bundler/snapshots/snapshots_loader.txt @@ -169,6 +169,7 @@ var invalid_identifier = true; // test2.json var test2_exports = {}; +__markAsModule(test2_exports); __export(test2_exports, { default: () => test2_default, "invalid-identifier": () => invalid_identifier2 diff --git a/internal/bundler/snapshots/snapshots_packagejson.txt b/internal/bundler/snapshots/snapshots_packagejson.txt index 97a9c190b8c..c9ad8786467 100644 --- a/internal/bundler/snapshots/snapshots_packagejson.txt +++ b/internal/bundler/snapshots/snapshots_packagejson.txt @@ -371,6 +371,7 @@ TestPackageJsonDualPackageHazardImportAndRequireForceModuleBeforeMain ---------- /Users/user/project/out.js ---------- // Users/user/project/node_modules/demo-pkg/module.js var module_exports = {}; +__markAsModule(module_exports); __export(module_exports, { default: () => module_default }); @@ -410,6 +411,7 @@ TestPackageJsonDualPackageHazardImportAndRequireImplicitMainForceModuleBeforeMai ---------- /Users/user/project/out.js ---------- // Users/user/project/node_modules/demo-pkg/module.js var module_exports = {}; +__markAsModule(module_exports); __export(module_exports, { default: () => module_default }); diff --git a/internal/bundler/snapshots/snapshots_splitting.txt b/internal/bundler/snapshots/snapshots_splitting.txt index d6c7fed8bfe..0c3f4b270c8 100644 --- a/internal/bundler/snapshots/snapshots_splitting.txt +++ b/internal/bundler/snapshots/snapshots_splitting.txt @@ -259,10 +259,16 @@ export { ================================================================================ TestSplittingDynamicCommonJSIntoES6 ---------- /out/entry.js ---------- +import "./chunk-VD7MAPBT.js"; + // entry.js -import("./foo-KZX24I45.js").then(({ default: { bar } }) => console.log(bar)); +import("./foo-YGPNXO73.js").then(({ default: { bar } }) => console.log(bar)); + +---------- /out/foo-YGPNXO73.js ---------- +import { + __commonJS +} from "./chunk-VD7MAPBT.js"; ----------- /out/foo-KZX24I45.js ---------- // foo.js var require_foo = __commonJS({ "foo.js"(exports) { @@ -271,6 +277,11 @@ var require_foo = __commonJS({ }); export default require_foo(); +---------- /out/chunk-VD7MAPBT.js ---------- +export { + __commonJS +}; + ================================================================================ TestSplittingDynamicES6IntoES6 ---------- /out/entry.js ---------- @@ -317,7 +328,7 @@ TestSplittingHybridESMAndCJSIssue617 import { foo, init_a -} from "./chunk-V7Q4P7WA.js"; +} from "./chunk-T3MG3LRV.js"; init_a(); export { foo @@ -327,7 +338,7 @@ export { import { a_exports, init_a -} from "./chunk-V7Q4P7WA.js"; +} from "./chunk-T3MG3LRV.js"; // b.js var bar = (init_a(), a_exports); @@ -335,9 +346,10 @@ export { bar }; ----------- /out/chunk-V7Q4P7WA.js ---------- +---------- /out/chunk-T3MG3LRV.js ---------- // a.js var a_exports = {}; +__markAsModule(a_exports); __export(a_exports, { foo: () => foo }); @@ -388,7 +400,7 @@ TestSplittingMissingLazyExport ---------- /out/a.js ---------- import { foo -} from "./chunk-QVTGQSXT.js"; +} from "./chunk-KFPHQBDL.js"; // a.js console.log(foo()); @@ -396,14 +408,15 @@ console.log(foo()); ---------- /out/b.js ---------- import { bar -} from "./chunk-QVTGQSXT.js"; +} from "./chunk-KFPHQBDL.js"; // b.js console.log(bar()); ----------- /out/chunk-QVTGQSXT.js ---------- +---------- /out/chunk-KFPHQBDL.js ---------- // empty.js var empty_exports = {}; +__markAsModule(empty_exports); // common.js function foo() { diff --git a/internal/bundler/snapshots/snapshots_ts.txt b/internal/bundler/snapshots/snapshots_ts.txt index 5c4ebf82bf5..fabfa15c8f5 100644 --- a/internal/bundler/snapshots/snapshots_ts.txt +++ b/internal/bundler/snapshots/snapshots_ts.txt @@ -2,6 +2,7 @@ TestExportTypeIssue379 ---------- /out.js ---------- // a.ts var a_exports = {}; +__markAsModule(a_exports); __export(a_exports, { foo: () => foo }); @@ -9,6 +10,7 @@ var foo = 123; // b.ts var b_exports = {}; +__markAsModule(b_exports); __export(b_exports, { foo: () => foo2 }); @@ -16,6 +18,7 @@ var foo2 = 123; // c.ts var c_exports = {}; +__markAsModule(c_exports); __export(c_exports, { foo: () => foo3 }); @@ -23,6 +26,7 @@ var foo3 = 123; // d.ts var d_exports = {}; +__markAsModule(d_exports); __export(d_exports, { foo: () => foo4 }); @@ -212,6 +216,7 @@ TestTSExportMissingES6 ---------- /out.js ---------- // foo.ts var foo_exports = {}; +__markAsModule(foo_exports); // entry.js console.log(foo_exports); From e65b08fa0edc447c0976c3d682839fbd02b42909 Mon Sep 17 00:00:00 2001 From: Liu Bowen Date: Wed, 2 Jun 2021 00:25:00 +0800 Subject: [PATCH 2/5] test: resume e2e test cases Signed-off-by: Liu Bowen --- scripts/end-to-end-tests.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/end-to-end-tests.js b/scripts/end-to-end-tests.js index 82f17f487e4..18890f974cd 100644 --- a/scripts/end-to-end-tests.js +++ b/scripts/end-to-end-tests.js @@ -648,11 +648,11 @@ 'foo.js': `module.exports = 123`, }), test(['--bundle', 'in.js', '--outfile=node.js'], { - 'in.js': `const out = require('./foo'); if (out.__esModule || out.foo !== 123) throw 'fail'`, + 'in.js': `const out = require('./foo'); if (out.foo !== 123) throw 'fail'`, 'foo.js': `export const foo = 123`, }), test(['--bundle', 'in.js', '--outfile=node.js'], { - 'in.js': `const out = require('./foo'); if (out.__esModule || out.default !== 123) throw 'fail'`, + 'in.js': `const out = require('./foo'); if (out.default !== 123) throw 'fail'`, 'foo.js': `export default 123`, }), @@ -673,13 +673,13 @@ 'in.js': `export default 123; const out = require('./in'); if (!out.__esModule || out.default !== 123) throw 'fail'`, }), test(['--bundle', 'in.js', '--outfile=node.js', '--format=esm'], { - 'in.js': `export const foo = 123; const out = require('./in'); if (out.__esModule || out.foo !== 123) throw 'fail'`, + 'in.js': `export const foo = 123; const out = require('./in'); if (out.foo !== 123) throw 'fail'`, }), test(['--bundle', 'in.js', '--outfile=node.js', '--format=esm', '--minify'], { - 'in.js': `export const foo = 123; const out = require('./in'); if (out.__esModule || out.foo !== 123) throw 'fail'`, + 'in.js': `export const foo = 123; const out = require('./in'); if (out.foo !== 123) throw 'fail'`, }), test(['--bundle', 'in.js', '--outfile=node.js', '--format=esm'], { - 'in.js': `export default 123; const out = require('./in'); if (out.__esModule || out.default !== 123) throw 'fail'`, + 'in.js': `export default 123; const out = require('./in'); if (out.default !== 123) throw 'fail'`, }), // Test bundled and non-bundled double export star From cbbe30c97b6a095dedfa60f215b22ecfeef35ac5 Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Mon, 7 Jun 2021 19:42:11 -0700 Subject: [PATCH 3/5] put back missing checks in tests --- scripts/end-to-end-tests.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/end-to-end-tests.js b/scripts/end-to-end-tests.js index 31dab9a1a80..1da2746b42a 100644 --- a/scripts/end-to-end-tests.js +++ b/scripts/end-to-end-tests.js @@ -754,19 +754,19 @@ 'foo.js': `module.exports = 123`, }), test(['--bundle', 'in.js', '--outfile=node.js'], { - 'in.js': `const out = require('./foo'); if (out.foo !== 123) throw 'fail'`, + 'in.js': `const out = require('./foo'); if (!out.__esModule || out.foo !== 123) throw 'fail'`, 'foo.js': `export const foo = 123`, }), test(['--bundle', 'in.js', '--outfile=node.js'], { - 'in.js': `const out = require('./foo'); if (out.default !== 123) throw 'fail'`, + 'in.js': `const out = require('./foo'); if (!out.__esModule || out.default !== 123) throw 'fail'`, 'foo.js': `export default 123`, }), test(['--bundle', 'in.js', '--outfile=node.js'], { - 'in.js': `const out = require('./foo'); if (out.default !== null) throw 'fail'`, + 'in.js': `const out = require('./foo'); if (!out.__esModule || out.default !== null) throw 'fail'`, 'foo.js': `export default function x() {} x = null`, }), test(['--bundle', 'in.js', '--outfile=node.js'], { - 'in.js': `const out = require('./foo'); if (out.default !== null) throw 'fail'`, + 'in.js': `const out = require('./foo'); if (!out.__esModule || out.default !== null) throw 'fail'`, 'foo.js': `export default class x {} x = null`, }), @@ -787,13 +787,13 @@ 'in.js': `export default 123; const out = require('./in'); if (!out.__esModule || out.default !== 123) throw 'fail'`, }), test(['--bundle', 'in.js', '--outfile=node.js', '--format=esm'], { - 'in.js': `export const foo = 123; const out = require('./in'); if (out.foo !== 123) throw 'fail'`, + 'in.js': `export const foo = 123; const out = require('./in'); if (!out.__esModule || out.foo !== 123) throw 'fail'`, }), test(['--bundle', 'in.js', '--outfile=node.js', '--format=esm', '--minify'], { - 'in.js': `export const foo = 123; const out = require('./in'); if (out.foo !== 123) throw 'fail'`, + 'in.js': `export const foo = 123; const out = require('./in'); if (!out.__esModule || out.foo !== 123) throw 'fail'`, }), test(['--bundle', 'in.js', '--outfile=node.js', '--format=esm'], { - 'in.js': `export default 123; const out = require('./in'); if (out.default !== 123) throw 'fail'`, + 'in.js': `export default 123; const out = require('./in'); if (!out.__esModule || out.default !== 123) throw 'fail'`, }), // Test bundled and non-bundled double export star From 134cb8b43a77e06810d996aada5daa1122d895be Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Mon, 7 Jun 2021 19:47:40 -0700 Subject: [PATCH 4/5] fix code size regression --- internal/bundler/linker.go | 27 ++++++++++---- internal/bundler/snapshots/snapshots_dce.txt | 7 ---- .../bundler/snapshots/snapshots_default.txt | 28 ++------------- .../snapshots/snapshots_importstar.txt | 36 ------------------- .../snapshots/snapshots_importstar_ts.txt | 7 ---- .../bundler/snapshots/snapshots_loader.txt | 1 - .../snapshots/snapshots_packagejson.txt | 2 -- .../bundler/snapshots/snapshots_splitting.txt | 7 ++-- internal/bundler/snapshots/snapshots_ts.txt | 4 --- internal/runtime/runtime.go | 1 + 10 files changed, 26 insertions(+), 94 deletions(-) diff --git a/internal/bundler/linker.go b/internal/bundler/linker.go index 8d6194d1350..98e6c72d36f 100644 --- a/internal/bundler/linker.go +++ b/internal/bundler/linker.go @@ -1740,11 +1740,13 @@ func (c *linkerContext) createExportsForFile(sourceIndex uint32) { } } - // Prefix this part with "var exports = { __esModule: true }" if this isn't a CommonJS module declaredSymbols := []js_ast.DeclaredSymbol{} var nsExportStmts []js_ast.Stmt - isNotCommonJSAndEntry := repr.AST.ExportsKind != js_ast.ExportsCommonJS && (!file.IsEntryPoint() || c.options.OutputFormat != config.FormatCommonJS) - if isNotCommonJSAndEntry { + + // Prefix this part with "var exports = {}" if this isn't a CommonJS module + needsExportsVariable := repr.AST.ExportsKind != js_ast.ExportsCommonJS && + (!file.IsEntryPoint() || c.options.OutputFormat != config.FormatCommonJS) + if needsExportsVariable { nsExportStmts = append(nsExportStmts, js_ast.Stmt{Data: &js_ast.SLocal{Decls: []js_ast.Decl{{ Binding: js_ast.Binding{Data: &js_ast.BIdentifier{Ref: repr.AST.ExportsRef}}, ValueOrNil: js_ast.Expr{Data: &js_ast.EObject{}}, @@ -1759,9 +1761,20 @@ func (c *linkerContext) createExportsForFile(sourceIndex uint32) { // "__markAsModule" which sets the "__esModule" property to true. This must // be done before any to "require()" or circular imports of multiple modules // that have been each converted from ESM to CommonJS may not work correctly. - if (repr.AST.ExportKeyword.Len > 0 && (repr.AST.ExportsKind == js_ast.ExportsCommonJS || - (file.IsEntryPoint() && c.options.OutputFormat == config.FormatCommonJS))) || - isNotCommonJSAndEntry { + needsMarkAsModule := + (repr.AST.ExportKeyword.Len > 0 && (repr.AST.ExportsKind == js_ast.ExportsCommonJS || + (file.IsEntryPoint() && c.options.OutputFormat == config.FormatCommonJS))) || + needsExportsVariable + + // Avoid calling "__markAsModule" if we call "__export" since the function + // "__export" already calls "__markAsModule". This is an optimization to + // reduce generated code size. + needsExportCall := len(properties) > 0 + if needsMarkAsModule && needsExportCall { + needsMarkAsModule = false + } + + if needsMarkAsModule { runtimeRepr := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr) markAsModuleRef := runtimeRepr.AST.ModuleScope.Members["__markAsModule"].Ref nsExportStmts = append(nsExportStmts, js_ast.Stmt{Data: &js_ast.SExpr{Value: js_ast.Expr{Data: &js_ast.ECall{ @@ -1785,7 +1798,7 @@ func (c *linkerContext) createExportsForFile(sourceIndex uint32) { // "__export(exports, { foo: () => foo })" exportRef := js_ast.InvalidRef - if len(properties) > 0 { + if needsExportCall { runtimeRepr := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr) exportRef = runtimeRepr.AST.ModuleScope.Members["__export"].Ref nsExportStmts = append(nsExportStmts, js_ast.Stmt{Data: &js_ast.SExpr{Value: js_ast.Expr{Data: &js_ast.ECall{ diff --git a/internal/bundler/snapshots/snapshots_dce.txt b/internal/bundler/snapshots/snapshots_dce.txt index 277b1b152cf..8c844e2522a 100644 --- a/internal/bundler/snapshots/snapshots_dce.txt +++ b/internal/bundler/snapshots/snapshots_dce.txt @@ -145,7 +145,6 @@ TestPackageJsonSideEffectsArrayKeepMainImplicitMain ---------- /out.js ---------- // Users/user/project/node_modules/demo-pkg/index-main.js var index_main_exports = {}; -__markAsModule(index_main_exports); __export(index_main_exports, { foo: () => foo }); @@ -192,7 +191,6 @@ TestPackageJsonSideEffectsArrayKeepModuleImplicitMain ---------- /out.js ---------- // Users/user/project/node_modules/demo-pkg/index-main.js var index_main_exports = {}; -__markAsModule(index_main_exports); __export(index_main_exports, { foo: () => foo }); @@ -260,7 +258,6 @@ var init_b = __esm({ // Users/user/project/node_modules/a/index.js var a_exports = {}; -__markAsModule(a_exports); __export(a_exports, { foo: () => foo }); @@ -348,7 +345,6 @@ TestPackageJsonSideEffectsFalseKeepBareImportAndRequireES6 ---------- /out.js ---------- // Users/user/project/node_modules/demo-pkg/index.js var demo_pkg_exports = {}; -__markAsModule(demo_pkg_exports); __export(demo_pkg_exports, { foo: () => foo }); @@ -409,7 +405,6 @@ TestPackageJsonSideEffectsFalseKeepStarImportES6 ---------- /out.js ---------- // Users/user/project/node_modules/demo-pkg/index.js var demo_pkg_exports = {}; -__markAsModule(demo_pkg_exports); __export(demo_pkg_exports, { foo: () => foo }); @@ -455,7 +450,6 @@ var init_b = __esm({ // Users/user/project/node_modules/a/index.js var a_exports = {}; -__markAsModule(a_exports); __export(a_exports, { foo: () => foo }); @@ -684,7 +678,6 @@ var init_lib = __esm({ // cjs.js var cjs_exports = {}; -__markAsModule(cjs_exports); __export(cjs_exports, { default: () => cjs_default }); diff --git a/internal/bundler/snapshots/snapshots_default.txt b/internal/bundler/snapshots/snapshots_default.txt index af2adfaf168..963f8c1ecfa 100644 --- a/internal/bundler/snapshots/snapshots_default.txt +++ b/internal/bundler/snapshots/snapshots_default.txt @@ -244,7 +244,6 @@ TestCommonJSFromES6 ---------- /out.js ---------- // foo.js var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -258,7 +257,6 @@ var init_foo = __esm({ // bar.js var bar_exports = {}; -__markAsModule(bar_exports); __export(bar_exports, { bar: () => bar }); @@ -551,7 +549,6 @@ var init_a = __esm({ // b.js var b_exports = {}; -__markAsModule(b_exports); __export(b_exports, { xyz: () => xyz }); @@ -564,7 +561,6 @@ var init_b = __esm({ // commonjs.js var commonjs_exports = {}; -__markAsModule(commonjs_exports); __export(commonjs_exports, { C: () => Class, Class: () => Class, @@ -594,7 +590,6 @@ var init_commonjs = __esm({ // c.js var c_exports = {}; -__markAsModule(c_exports); __export(c_exports, { default: () => c_default }); @@ -608,7 +603,6 @@ var init_c = __esm({ // d.js var d_exports = {}; -__markAsModule(d_exports); __export(d_exports, { default: () => Foo }); @@ -623,7 +617,6 @@ var init_d = __esm({ // e.js var e_exports = {}; -__markAsModule(e_exports); __export(e_exports, { default: () => e_default }); @@ -636,7 +629,6 @@ var init_e = __esm({ // f.js var f_exports = {}; -__markAsModule(f_exports); __export(f_exports, { default: () => foo }); @@ -650,7 +642,6 @@ var init_f = __esm({ // g.js var g_exports = {}; -__markAsModule(g_exports); __export(g_exports, { default: () => g_default }); @@ -663,7 +654,6 @@ var init_g = __esm({ // h.js var h_exports = {}; -__markAsModule(h_exports); __export(h_exports, { default: () => foo2 }); @@ -692,7 +682,6 @@ var abc = void 0; // b.js var b_exports = {}; -__markAsModule(b_exports); __export(b_exports, { xyz: () => xyz }); @@ -725,7 +714,6 @@ TestExportFormsIIFE var globalName = (() => { // entry.js var entry_exports = {}; - __markAsModule(entry_exports); __export(entry_exports, { C: () => Class, Class: () => Class, @@ -743,7 +731,6 @@ var globalName = (() => { // b.js var b_exports = {}; - __markAsModule(b_exports); __export(b_exports, { xyz: () => xyz }); @@ -814,7 +801,6 @@ TestExportsAndModuleFormatCommonJS ---------- /out.js ---------- // foo/test.js var test_exports = {}; -__markAsModule(test_exports); __export(test_exports, { foo: () => foo }); @@ -822,7 +808,6 @@ var foo = 123; // bar/test.js var test_exports2 = {}; -__markAsModule(test_exports2); __export(test_exports2, { bar: () => bar }); @@ -836,7 +821,6 @@ TestExternalES6ConvertedToCommonJS ---------- /out.js ---------- // a.js var a_exports = {}; -__markAsModule(a_exports); __export(a_exports, { ns: () => ns }); @@ -848,7 +832,6 @@ var init_a = __esm({ // b.js var b_exports = {}; -__markAsModule(b_exports); __export(b_exports, { ns: () => ns2 }); @@ -860,7 +843,6 @@ var init_b = __esm({ // c.js var c_exports = {}; -__markAsModule(c_exports); __export(c_exports, { ns: () => ns3 }); @@ -872,7 +854,6 @@ var init_c = __esm({ // d.js var d_exports = {}; -__markAsModule(d_exports); __export(d_exports, { ns: () => ns4 }); @@ -1835,16 +1816,14 @@ TestMinifiedExportsAndModuleFormatCommonJS ---------- /out.js ---------- // foo/test.js var t = {}; -f(t); -p(t, { +f(t, { foo: () => l }); var l = 123; // bar/test.js var r = {}; -f(r); -p(r, { +f(r, { bar: () => m }); var m = 123; @@ -2116,7 +2095,6 @@ export { TestReExportDefaultExternalCommonJS ---------- /out.js ---------- // entry.js -__markAsModule(exports); __export(exports, { bar: () => import_bar.default, foo: () => import_foo.default @@ -2161,7 +2139,6 @@ export { default as bar } from "./bar"; ================================================================================ TestReExportDefaultNoBundleCommonJS ---------- /out.js ---------- -__markAsModule(exports); __export(exports, { bar: () => import_bar.default, foo: () => import_foo.default @@ -2887,7 +2864,6 @@ var require_cjs = __commonJS({ // dummy.js var dummy_exports = {}; -__markAsModule(dummy_exports); __export(dummy_exports, { dummy: () => dummy }); diff --git a/internal/bundler/snapshots/snapshots_importstar.txt b/internal/bundler/snapshots/snapshots_importstar.txt index 34465b2650c..59281fe0faf 100644 --- a/internal/bundler/snapshots/snapshots_importstar.txt +++ b/internal/bundler/snapshots/snapshots_importstar.txt @@ -8,7 +8,6 @@ var require_foo = __commonJS({ }); // entry.js -__markAsModule(exports); __export(exports, { ns: () => ns }); @@ -25,7 +24,6 @@ var require_foo = __commonJS({ }); // entry.js -__markAsModule(exports); __export(exports, { bar: () => import_foo.bar }); @@ -42,7 +40,6 @@ var require_foo = __commonJS({ }); // entry.js -__markAsModule(exports); __export(exports, { y: () => import_foo.x }); @@ -54,7 +51,6 @@ var import_foo = __toModule(require_foo()); TestExportSelfAndImportSelfCommonJS ---------- /out.js ---------- // entry.js -__markAsModule(exports); __export(exports, { foo: () => foo }); @@ -65,7 +61,6 @@ console.log(exports); TestExportSelfAndRequireSelfCommonJS ---------- /out.js ---------- // entry.js -__markAsModule(exports); __export(exports, { foo: () => foo }); @@ -82,7 +77,6 @@ init_entry(); TestExportSelfAsNamespaceCommonJS ---------- /out.js ---------- // entry.js -__markAsModule(exports); __export(exports, { foo: () => foo, ns: () => exports @@ -94,7 +88,6 @@ TestExportSelfAsNamespaceES6 ---------- /out.js ---------- // entry.js var entry_exports = {}; -__markAsModule(entry_exports); __export(entry_exports, { foo: () => foo, ns: () => entry_exports @@ -109,7 +102,6 @@ export { TestExportSelfCommonJS ---------- /out.js ---------- // entry.js -__markAsModule(exports); __export(exports, { foo: () => foo }); @@ -148,7 +140,6 @@ TestExportSelfIIFEWithName var someName = (() => { // entry.js var entry_exports = {}; - __markAsModule(entry_exports); __export(entry_exports, { foo: () => foo }); @@ -160,7 +151,6 @@ var someName = (() => { TestExportStarDefaultExportCommonJS ---------- /out.js ---------- // entry.js -__markAsModule(exports); __export(exports, { foo: () => foo }); @@ -214,7 +204,6 @@ console.log(internal_default, internal_default); ---------- /out/internal-ns.js ---------- // internal.js var internal_exports = {}; -__markAsModule(internal_exports); __export(internal_exports, { default: () => internal_default }); @@ -226,7 +215,6 @@ console.log(internal_default, internal_exports); ---------- /out/internal-ns-default.js ---------- // internal.js var internal_exports = {}; -__markAsModule(internal_exports); __export(internal_exports, { default: () => internal_default }); @@ -238,7 +226,6 @@ console.log(internal_default, internal_exports, internal_default); ---------- /out/internal-ns-def.js ---------- // internal.js var internal_exports = {}; -__markAsModule(internal_exports); __export(internal_exports, { default: () => internal_default }); @@ -272,7 +259,6 @@ var require_foo = __commonJS({ }); // entry.js -__markAsModule(exports); __export(exports, { ns: () => ns }); @@ -283,7 +269,6 @@ TestImportExportSelfAsNamespaceES6 ---------- /out.js ---------- // entry.js var entry_exports = {}; -__markAsModule(entry_exports); __export(entry_exports, { foo: () => foo, ns: () => entry_exports @@ -352,7 +337,6 @@ TestImportStarAndCommonJS ---------- /out.js ---------- // foo.js var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -373,7 +357,6 @@ TestImportStarCapture ---------- /out.js ---------- // foo.js var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -433,7 +416,6 @@ TestImportStarExportImportStarCapture ---------- /out.js ---------- // foo.js var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -448,7 +430,6 @@ TestImportStarExportImportStarNoCapture ---------- /out.js ---------- // foo.js var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -470,7 +451,6 @@ TestImportStarExportStarAsCapture ---------- /out.js ---------- // foo.js var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -485,7 +465,6 @@ TestImportStarExportStarAsNoCapture ---------- /out.js ---------- // foo.js var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -507,7 +486,6 @@ TestImportStarExportStarCapture ---------- /out.js ---------- // bar.js var bar_exports = {}; -__markAsModule(bar_exports); __export(bar_exports, { foo: () => foo }); @@ -534,7 +512,6 @@ TestImportStarExportStarOmitAmbiguous ---------- /out.js ---------- // common.js var common_exports = {}; -__markAsModule(common_exports); __export(common_exports, { x: () => x, z: () => z @@ -613,14 +590,12 @@ TestImportStarOfExportStarAs ---------- /out.js ---------- // foo.js var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { bar_ns: () => bar_exports }); // bar.js var bar_exports = {}; -__markAsModule(bar_exports); __export(bar_exports, { bar: () => bar }); @@ -641,7 +616,6 @@ TestIssue176 ---------- /out.js ---------- // folders/index.js var folders_exports = {}; -__markAsModule(folders_exports); __export(folders_exports, { foo: () => foo }); @@ -671,7 +645,6 @@ TestNamespaceImportMissingES6 ---------- /out.js ---------- // foo.js var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { x: () => x }); @@ -685,7 +658,6 @@ TestNamespaceImportReExportStarMissingES6 ---------- /out.js ---------- // foo.js var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { x: () => x }); @@ -745,7 +717,6 @@ TestReExportNamespaceImportMissingES6 ---------- /out.js ---------- // bar.js var bar_exports = {}; -__markAsModule(bar_exports); __export(bar_exports, { x: () => x }); @@ -759,7 +730,6 @@ TestReExportNamespaceImportUnusedMissingES6 ---------- /out.js ---------- // bar.js var bar_exports = {}; -__markAsModule(bar_exports); __export(bar_exports, { x: () => x }); @@ -773,7 +743,6 @@ TestReExportOtherFileExportSelfAsNamespaceES6 ---------- /out.js ---------- // foo.js var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo, ns: () => foo_exports @@ -789,7 +758,6 @@ TestReExportOtherFileImportExportSelfAsNamespaceES6 ---------- /out.js ---------- // foo.js var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo, ns: () => foo_exports @@ -803,7 +771,6 @@ export { ================================================================================ TestReExportStarAsCommonJSNoBundle ---------- /out.js ---------- -__markAsModule(exports); __export(exports, { out: () => out }); @@ -821,7 +788,6 @@ export { TestReExportStarAsExternalCommonJS ---------- /out.js ---------- // entry.js -__markAsModule(exports); __export(exports, { out: () => out }); @@ -842,7 +808,6 @@ TestReExportStarAsExternalIIFE var mod = (() => { // entry.js var entry_exports = {}; - __markAsModule(entry_exports); __export(entry_exports, { out: () => out }); @@ -855,7 +820,6 @@ TestReExportStarAsIIFENoBundle ---------- /out.js ---------- var mod = (() => { var entry_exports = {}; - __markAsModule(entry_exports); __export(entry_exports, { out: () => out }); diff --git a/internal/bundler/snapshots/snapshots_importstar_ts.txt b/internal/bundler/snapshots/snapshots_importstar_ts.txt index 6d94c857b8e..0ff0a4304e0 100644 --- a/internal/bundler/snapshots/snapshots_importstar_ts.txt +++ b/internal/bundler/snapshots/snapshots_importstar_ts.txt @@ -2,7 +2,6 @@ TestTSImportStarAndCommonJS ---------- /out.js ---------- // foo.ts var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -23,7 +22,6 @@ TestTSImportStarCapture ---------- /out.js ---------- // foo.ts var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -75,7 +73,6 @@ TestTSImportStarExportImportStarCapture ---------- /out.js ---------- // foo.ts var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -90,7 +87,6 @@ TestTSImportStarExportImportStarNoCapture ---------- /out.js ---------- // foo.ts var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -112,7 +108,6 @@ TestTSImportStarExportStarAsCapture ---------- /out.js ---------- // foo.ts var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -127,7 +122,6 @@ TestTSImportStarExportStarAsNoCapture ---------- /out.js ---------- // foo.ts var foo_exports = {}; -__markAsModule(foo_exports); __export(foo_exports, { foo: () => foo }); @@ -149,7 +143,6 @@ TestTSImportStarExportStarCapture ---------- /out.js ---------- // bar.ts var bar_exports = {}; -__markAsModule(bar_exports); __export(bar_exports, { foo: () => foo }); diff --git a/internal/bundler/snapshots/snapshots_loader.txt b/internal/bundler/snapshots/snapshots_loader.txt index 32bdf7e9d7a..33e270f4c4c 100644 --- a/internal/bundler/snapshots/snapshots_loader.txt +++ b/internal/bundler/snapshots/snapshots_loader.txt @@ -169,7 +169,6 @@ var invalid_identifier = true; // test2.json var test2_exports = {}; -__markAsModule(test2_exports); __export(test2_exports, { default: () => test2_default, "invalid-identifier": () => invalid_identifier2 diff --git a/internal/bundler/snapshots/snapshots_packagejson.txt b/internal/bundler/snapshots/snapshots_packagejson.txt index c9ad8786467..97a9c190b8c 100644 --- a/internal/bundler/snapshots/snapshots_packagejson.txt +++ b/internal/bundler/snapshots/snapshots_packagejson.txt @@ -371,7 +371,6 @@ TestPackageJsonDualPackageHazardImportAndRequireForceModuleBeforeMain ---------- /Users/user/project/out.js ---------- // Users/user/project/node_modules/demo-pkg/module.js var module_exports = {}; -__markAsModule(module_exports); __export(module_exports, { default: () => module_default }); @@ -411,7 +410,6 @@ TestPackageJsonDualPackageHazardImportAndRequireImplicitMainForceModuleBeforeMai ---------- /Users/user/project/out.js ---------- // Users/user/project/node_modules/demo-pkg/module.js var module_exports = {}; -__markAsModule(module_exports); __export(module_exports, { default: () => module_default }); diff --git a/internal/bundler/snapshots/snapshots_splitting.txt b/internal/bundler/snapshots/snapshots_splitting.txt index c02dcaa4bfd..e23f392ef9e 100644 --- a/internal/bundler/snapshots/snapshots_splitting.txt +++ b/internal/bundler/snapshots/snapshots_splitting.txt @@ -328,7 +328,7 @@ TestSplittingHybridESMAndCJSIssue617 import { foo, init_a -} from "./chunk-E2H5IDUU.js"; +} from "./chunk-NCWNCRTK.js"; init_a(); export { foo @@ -338,7 +338,7 @@ export { import { a_exports, init_a -} from "./chunk-E2H5IDUU.js"; +} from "./chunk-NCWNCRTK.js"; // b.js var bar = (init_a(), a_exports); @@ -346,10 +346,9 @@ export { bar }; ----------- /out/chunk-E2H5IDUU.js ---------- +---------- /out/chunk-NCWNCRTK.js ---------- // a.js var a_exports = {}; -__markAsModule(a_exports); __export(a_exports, { foo: () => foo }); diff --git a/internal/bundler/snapshots/snapshots_ts.txt b/internal/bundler/snapshots/snapshots_ts.txt index cd02fece99a..972830cbc3b 100644 --- a/internal/bundler/snapshots/snapshots_ts.txt +++ b/internal/bundler/snapshots/snapshots_ts.txt @@ -2,7 +2,6 @@ TestExportTypeIssue379 ---------- /out.js ---------- // a.ts var a_exports = {}; -__markAsModule(a_exports); __export(a_exports, { foo: () => foo }); @@ -10,7 +9,6 @@ var foo = 123; // b.ts var b_exports = {}; -__markAsModule(b_exports); __export(b_exports, { foo: () => foo2 }); @@ -18,7 +16,6 @@ var foo2 = 123; // c.ts var c_exports = {}; -__markAsModule(c_exports); __export(c_exports, { foo: () => foo3 }); @@ -26,7 +23,6 @@ var foo3 = 123; // d.ts var d_exports = {}; -__markAsModule(d_exports); __export(d_exports, { foo: () => foo4 }); diff --git a/internal/runtime/runtime.go b/internal/runtime/runtime.go index 30965a7b9e6..8f5dddc793b 100644 --- a/internal/runtime/runtime.go +++ b/internal/runtime/runtime.go @@ -169,6 +169,7 @@ func code(isES6 bool) string { // Used to implement ES6 exports to CommonJS export var __export = (target, all) => { + __markAsModule(target) for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }) } From 0cf56c243e1c4b5e4fb25099fa70c52f7ea96db8 Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Mon, 7 Jun 2021 22:42:45 -0700 Subject: [PATCH 5/5] release notes, forbid "__esModule" export --- CHANGELOG.md | 24 ++++++++++++++++++++++++ internal/js_parser/js_parser.go | 3 +++ internal/js_parser/js_parser_test.go | 7 +++++++ scripts/end-to-end-tests.js | 18 ++++++++++++++++++ 4 files changed, 52 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90a575451a1..b75133f78d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,30 @@ Due to an oversight, the `--metafile` setting didn't work when `--watch` was also specified. This only affected the command-line interface. With this release, the `--metafile` setting should now work in this case. +* Add a hidden `__esModule` property to modules in ESM format ([#1338](https://github.com/evanw/esbuild/pull/1338)) + + Module namespace objects from ESM files will now have a hidden `__esModule` property. This improves compatibility with code that has been converted from ESM syntax to CommonJS by Babel or TypeScript. For example: + + ```js + // Input TypeScript code + import x from "y" + console.log(x) + + // Output JavaScript code from the TypeScript compiler + var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + Object.defineProperty(exports, "__esModule", { value: true }); + const y_1 = __importDefault(require("y")); + console.log(y_1.default); + ``` + + If the object returned by `require("y")` doesn't have an `__esModule` property, then `y_1` will be the object `{ "default": require("y") }`. If the file `"y"` is in ESM format and has a default export of, say, the value `null`, that means `y_1` will now be `{ "default": { "default": null } }` and you will need to use `y_1.default.default` to access the default value. Adding an automatically-generated `__esModule` property when converting files in ESM format to CommonJS is required to make this code work correctly (i.e. for the value to be accessible via just `y_1.default` instead). + + With this release, code in ESM format will now have an automatically-generated `__esModule` property to satisfy this convention. The property is non-enumerable so it shouldn't show up when iterating over the properties of the object. As a result, the export name `__esModule` is now reserved for use with esbuild. It's now an error to create an export with the name `__esModule`. + + This fix was contributed by [@lbwa](https://github.com/lbwa). + ## 0.12.6 * Improve template literal lowering transformation conformance ([#1327](https://github.com/evanw/esbuild/issues/1327)) diff --git a/internal/js_parser/js_parser.go b/internal/js_parser/js_parser.go index a7d52b3c954..42ee843fd9c 100644 --- a/internal/js_parser/js_parser.go +++ b/internal/js_parser/js_parser.go @@ -12586,6 +12586,9 @@ func (p *parser) recordExport(loc logger.Loc, alias string, ref js_ast.Ref) { fmt.Sprintf("Multiple exports with the same name %q", alias), []logger.MsgData{logger.RangeData(&p.tracker, js_lexer.RangeOfIdentifier(p.source, name.AliasLoc), fmt.Sprintf("%q was originally exported here", alias))}) + } else if alias == "__esModule" { + p.log.AddRangeError(&p.tracker, js_lexer.RangeOfIdentifier(p.source, loc), + "The export name \"__esModule\" is reserved and cannot be used (it's needed as an export marker when converting ES module syntax to CommonJS)") } else { p.namedExports[alias] = js_ast.NamedExport{AliasLoc: loc, Ref: ref} } diff --git a/internal/js_parser/js_parser_test.go b/internal/js_parser/js_parser_test.go index ddc6866f893..1a9c05e2408 100644 --- a/internal/js_parser/js_parser_test.go +++ b/internal/js_parser/js_parser_test.go @@ -2484,6 +2484,13 @@ func TestExport(t *testing.T) { ": error: This export alias is invalid because it contains the unpaired Unicode surrogate U+DC00\n") expectParseErrorTarget(t, 2020, "export * as '' from 'foo'", ": error: Using a string as a module namespace identifier name is not supported in the configured target environment\n") + + // Exports with the name "__esModule" are forbidden + esModuleError := ": error: The export name \"__esModule\" is reserved and cannot be used " + + "(it's needed as an export marker when converting ES module syntax to CommonJS)\n" + expectParseError(t, "export var __esModule", esModuleError) + expectParseError(t, "export {__esModule}; var __esModule", esModuleError) + expectParseError(t, "export {__esModule} from 'foo'", esModuleError) } func TestExportDuplicates(t *testing.T) { diff --git a/scripts/end-to-end-tests.js b/scripts/end-to-end-tests.js index 1da2746b42a..44c6ca86b10 100644 --- a/scripts/end-to-end-tests.js +++ b/scripts/end-to-end-tests.js @@ -769,6 +769,24 @@ 'in.js': `const out = require('./foo'); if (!out.__esModule || out.default !== null) throw 'fail'`, 'foo.js': `export default class x {} x = null`, }), + test(['--bundle', 'in.js', '--outfile=node.js'], { + 'in.js': ` + // This is the JavaScript generated by "tsc" for the following TypeScript: + // + // import fn from './foo' + // if (typeof fn !== 'function') throw 'fail' + // + "use strict"; + var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + Object.defineProperty(exports, "__esModule", { value: true }); + const foo_1 = __importDefault(require("./foo")); + if (typeof foo_1.default !== 'function') + throw 'fail'; + `, + 'foo.js': `export default function fn() {}`, + }), // Self export test(['--bundle', 'in.js', '--outfile=node.js'], {