diff --git a/CHANGELOG.md b/CHANGELOG.md index 02889f9cb1f..758b5ad09c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,45 @@ # Changelog +## Unreleased + +* Adjust esbuild's handling of `default` exports and the `__esModule` marker ([#532](https://github.com/evanw/esbuild/issues/532), [#1591](https://github.com/evanw/esbuild/issues/1591), [#1719](https://github.com/evanw/esbuild/issues/1719)) + + This change requires some background for context. Here's the history to the best of my understanding: + + When the ECMAScript module `import`/`export` syntax was being developed, the CommonJS module format (used in Node.js) was already widely in use. Because of this the export name called `default` was given special a syntax. Instead of writing `import { default as foo } from 'bar'` you can just write `import foo from 'bar'`. The idea was that when ECMAScript modules (a.k.a. ES modules) were introduced, you could import existing CommonJS modules using the new import syntax for compatibility. Since CommonJS module exports are dynamic while ES module exports are static, it's not generally possible to determine a CommonJS module's export names at module instantiation time since the code hasn't been evaluated yet. So the value of `module.exports` is just exported as the `default` export and the special `default` import syntax gives you easy access to `module.exports` (i.e. `const foo = require('bar')` is the same as `import foo from 'bar'`). + + However, it took a while for ES module syntax to be supported natively by JavaScript runtimes, and people still wanted to start using ES module syntax in the meantime. The [Babel](https://babeljs.io/) JavaScript compiler let you do this. You could transform each ES module file into a CommonJS module file that behaved the same. However, this transformation has a problem: emulating the `import` syntax accurately as described above means that `export default 0` and `import foo from 'bar'` will no longer line up when transformed to CommonJS. The code `export default 0` turns into `module.exports.default = 0` and the code `import foo from 'bar'` turns into `const foo = require('bar')`, meaning `foo` is `0` before the transformation but `foo` is `{ default: 0 }` after the transformation. + + To fix this, Babel sets the property `__esModule` to true as a signal to itself when it converts an ES module to a CommonJS module. Then, when importing a `default` export, it can know to use the value of `module.exports.default` instead of `module.exports` to make sure the behavior of the CommonJS modules correctly matches the behavior of the original ES modules. This fix has been widely adopted across the ecosystem and has made it into other tools such as TypeScript and even esbuild. + + However, when Node.js finally released their ES module implementation, they went with the original implementation where the `default` export is always `module.exports`, which broke compatibility with the existing ecosystem of ES modules that had been cross-compiled into CommonJS modules by Babel. You now have to either add or remove an additional `.default` property depending on whether your code needs to run in a Node environment or in a Babel environment, which created an interoperability headache. In addition, JavaScript tools such as esbuild now need to guess whether you want Node-style or Babel-style `default` imports. There's no way for a tool to know with certainty which one a given file is expecting and if your tool guesses wrong, your code will break. + + This release changes esbuild's heuristics around `default` exports and the `__esModule` marker to attempt to improve compatibility with Webpack and Node, which is what most packages are tuned for. The behavior changes are as follows: + + Old behavior: + + * If an `import` statement is used to load a CommonJS file and a) `module.exports` is an object, b) `module.exports.__esModule` is truthy, and c) the property `default` exists in `module.exports`, then esbuild would set the `default` export to `module.exports.default` (like Babel). Otherwise the `default` export was set to `module.exports` (like Node). + + * If a `require` call is used to load an ES module file, the returned module namespace object had the `__esModule` property set to true. This behaved as if the ES module had been converted to CommonJS via a Babel-compatible transformation. + + * The `__esModule` marker could inconsistently appear on module namespace objects (i.e. `import * as`) when writing pure ESM code. Specifically, if a module namespace object was materialized then the `__esModule` marker was present, but if it was optimized away then the `__esModule` marker was absent. + + * It was not allowed to create an ES module export named `__esModule`. This avoided generating code that might break due to the inconsistency mentioned above, and also avoided issues with duplicate definitions of `__esModule`. + + New behavior: + + * If an `import` statement is used to load a CommonJS file and a) `module.exports` is an object, b) `module.exports.__esModule` is truthy, and c) the file name does not end in either `.mjs` or `.mts` and the `package.json` file does not contain `"type": "module"`, then esbuild will set the `default` export to `module.exports.default` (like Babel). Otherwise the `default` export is set to `module.exports` (like Node). + + Note that this means the `default` export may now be undefined in situations where it previously wasn't undefined. This matches Webpack's behavior so it should hopefully be more compatible. + + Also note that this means import behavior now depends on the file extension and on the contents of `package.json`. This also matches Webpack's behavior to hopefully improve compatibility. + + * If a `require` call is used to load an ES module file, the returned module namespace object has the `__esModule` property set to `true`. This behaves as if the ES module had been converted to CommonJS via a Babel-compatible transformation. + + * If an `import` statement or `import()` expression is used to load an ES module, the `__esModule` marker should now never be present on the module namespace object. This frees up the `__esModule` export name for use with ES modules. + + * It's now allowed to use `__esModule` as a normal export name in an ES module. This property will be accessible to other ES modules but will not be accessible to code that loads the ES module using `require`, where they will observe the property set to `true` instead. + ## 0.14.3 * Pass the current esbuild instance to JS plugins ([#1790](https://github.com/evanw/esbuild/issues/1790)) diff --git a/internal/ast/ast.go b/internal/ast/ast.go index 77776cf6c80..f9094686c57 100644 --- a/internal/ast/ast.go +++ b/internal/ast/ast.go @@ -86,8 +86,11 @@ type ImportRecord struct { // calling the "__reExport()" helper function CallsRunTimeReExportFn bool - // Tell the printer to wrap this call to "require()" in "__toModule(...)" - WrapWithToModule bool + // Tell the printer to wrap this call to "require()" in "__toESM(...)" + WrapWithToESM bool + + // Tell the printer to wrap this ESM exports object in "__toCJS(...)" + WrapWithToCJS bool // Tell the printer to use the runtime "__require()" instead of "require()" CallRuntimeRequire bool diff --git a/internal/bundler/linker.go b/internal/bundler/linker.go index 8ab2797cb3e..31b102fccad 100644 --- a/internal/bundler/linker.go +++ b/internal/bundler/linker.go @@ -1264,16 +1264,18 @@ func (c *linkerContext) scanImportsAndExports() { c.matchImportsWithExportsForFile(uint32(sourceIndex)) } - // If we're exporting as CommonJS and this file doesn't need a wrapper, + // If we're exporting as CommonJS and this file was originally CommonJS, // then we'll be using the actual CommonJS "exports" and/or "module" // symbols. In that case make sure to mark them as such so they don't // get minified. - if (c.options.OutputFormat == config.FormatPreserve || c.options.OutputFormat == config.FormatCommonJS) && - repr.Meta.Wrap != graph.WrapCJS && file.IsEntryPoint() { + if file.IsEntryPoint() && repr.AST.ExportsKind == js_ast.ExportsCommonJS && repr.Meta.Wrap == graph.WrapNone && + (c.options.OutputFormat == config.FormatPreserve || c.options.OutputFormat == config.FormatCommonJS) { exportsRef := js_ast.FollowSymbols(c.graph.Symbols, repr.AST.ExportsRef) moduleRef := js_ast.FollowSymbols(c.graph.Symbols, repr.AST.ModuleRef) c.graph.Symbols.Get(exportsRef).Kind = js_ast.SymbolUnbound c.graph.Symbols.Get(moduleRef).Kind = js_ast.SymbolUnbound + } else if repr.Meta.ForceIncludeExportsForEntryPoint || repr.AST.ExportsKind != js_ast.ExportsCommonJS { + repr.Meta.NeedsExportsVariable = true } // Create the wrapper part for wrapped files. This is needed by a later step. @@ -1374,8 +1376,7 @@ func (c *linkerContext) scanImportsAndExports() { // actual CommonJS files from being renamed. This is purely about // aesthetics and is not about correctness. This is done here because by // this point, we know the CommonJS status will not change further. - if repr.Meta.Wrap != graph.WrapCJS && repr.AST.ExportsKind != js_ast.ExportsCommonJS && (!file.IsEntryPoint() || - c.options.OutputFormat != config.FormatCommonJS) { + if repr.Meta.Wrap != graph.WrapCJS && repr.AST.ExportsKind != js_ast.ExportsCommonJS { name := file.InputFile.Source.IdentifierName c.graph.Symbols.Get(repr.AST.ExportsRef).OriginalName = name + "_exports" c.graph.Symbols.Get(repr.AST.ModuleRef).OriginalName = name + "_module" @@ -1384,16 +1385,10 @@ func (c *linkerContext) scanImportsAndExports() { // Include the "__export" symbol from the runtime if it was used in the // previous step. The previous step can't do this because it's running in // parallel and can't safely mutate the "importsToBind" map of another file. - if repr.Meta.NeedsExportSymbolFromRuntime || repr.Meta.NeedsMarkAsModuleSymbolFromRuntime { + if repr.Meta.NeedsExportSymbolFromRuntime { runtimeRepr := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr) - if repr.Meta.NeedsExportSymbolFromRuntime { - exportRef := runtimeRepr.AST.ModuleScope.Members["__export"].Ref - c.graph.GenerateSymbolImportAndUse(sourceIndex, js_ast.NSExportPartIndex, exportRef, 1, runtime.SourceIndex) - } - if repr.Meta.NeedsMarkAsModuleSymbolFromRuntime { - markAsModuleRef := runtimeRepr.AST.ModuleScope.Members["__markAsModule"].Ref - c.graph.GenerateSymbolImportAndUse(sourceIndex, js_ast.NSExportPartIndex, markAsModuleRef, 1, runtime.SourceIndex) - } + exportRef := runtimeRepr.AST.ModuleScope.Members["__export"].Ref + c.graph.GenerateSymbolImportAndUse(sourceIndex, js_ast.NSExportPartIndex, exportRef, 1, runtime.SourceIndex) } for importRef, importData := range repr.Meta.ImportsToBind { @@ -1469,11 +1464,17 @@ func (c *linkerContext) scanImportsAndExports() { CanBeRemovedIfUnused: false, }) repr.Meta.EntryPointPartIndex = ast.MakeIndex32(entryPointPartIndex) + + // Pull in the "__toCommonJS" symbol if we need it due to being an entry point + if repr.Meta.ForceIncludeExportsForEntryPoint { + c.graph.GenerateRuntimeSymbolImportAndUse(sourceIndex, entryPointPartIndex, "__toCommonJS", 1) + } } // Encode import-specific constraints in the dependency graph for partIndex, part := range repr.AST.Parts { - toModuleUses := uint32(0) + toESMUses := uint32(0) + toCommonJSUses := uint32(0) runtimeRequireUses := uint32(0) // Imports of wrapped files must depend on the wrapper @@ -1492,11 +1493,11 @@ func (c *linkerContext) scanImportsAndExports() { runtimeRequireUses++ } - // It needs the "__toModule" wrapper if it wasn't originally a + // It needs the "__toESM" wrapper if it wasn't originally a // CommonJS import (i.e. it wasn't a "require()" call). if record.Kind != ast.ImportRequire { - record.WrapWithToModule = true - toModuleUses++ + record.WrapWithToESM = true + toESMUses++ } } continue @@ -1511,10 +1512,10 @@ func (c *linkerContext) scanImportsAndExports() { c.graph.GenerateSymbolImportAndUse(sourceIndex, uint32(partIndex), wrapperRef, 1, otherSourceIndex) // This is an ES6 import of a CommonJS module, so it needs the - // "__toModule" wrapper as long as it's not a bare "require()" + // "__toESM" wrapper as long as it's not a bare "require()" if record.Kind != ast.ImportRequire && otherRepr.AST.ExportsKind == js_ast.ExportsCommonJS { - record.WrapWithToModule = true - toModuleUses++ + record.WrapWithToESM = true + toESMUses++ } // If this is an ESM wrapper, also depend on the exports object @@ -1524,6 +1525,20 @@ func (c *linkerContext) scanImportsAndExports() { // those just cause us to reference the exports directly. if otherRepr.Meta.Wrap == graph.WrapESM && record.Kind != ast.ImportStmt { c.graph.GenerateSymbolImportAndUse(sourceIndex, uint32(partIndex), otherRepr.AST.ExportsRef, 1, otherSourceIndex) + + // If this is a "require()" call, then we should add the + // "__esModule" marker to behave as if the module was converted + // from ESM to CommonJS. This is done via a wrapper instead of + // by modifying the exports object itself because the same ES + // module may be simultaneously imported and required, and the + // importing code should not see "__esModule" while the requiring + // code should see "__esModule". This is an extremely complex + // and subtle set of bundler interop issues. See for example + // https://github.com/evanw/esbuild/issues/1591. + if record.Kind == ast.ImportRequire { + record.WrapWithToCJS = true + toCommonJSUses++ + } } } else if record.Kind == ast.ImportStmt && otherRepr.AST.ExportsKind == js_ast.ExportsESMWithDynamicFallback { // This is an import of a module that has a dynamic export fallback @@ -1536,8 +1551,12 @@ func (c *linkerContext) scanImportsAndExports() { } // If there's an ES6 import of a non-ES6 module, then we're going to need the - // "__toModule" symbol from the runtime to wrap the result of "require()" - c.graph.GenerateRuntimeSymbolImportAndUse(sourceIndex, uint32(partIndex), "__toModule", toModuleUses) + // "__toESM" symbol from the runtime to wrap the result of "require()" + c.graph.GenerateRuntimeSymbolImportAndUse(sourceIndex, uint32(partIndex), "__toESM", toESMUses) + + // If there's a CommonJS require of an ES6 module, then we're going to need the + // "__toCommonJS" symbol from the runtime to wrap the exports object + c.graph.GenerateRuntimeSymbolImportAndUse(sourceIndex, uint32(partIndex), "__toCommonJS", toCommonJSUses) // If there are unbundled calls to "require()" and we're not generating // code for node, then substitute a "__require" wrapper for "require". @@ -1742,10 +1761,8 @@ func (c *linkerContext) createExportsForFile(sourceIndex uint32) { declaredSymbols := []js_ast.DeclaredSymbol{} var nsExportStmts []js_ast.Stmt - // 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 { + // Prefix this part with "var exports = {}" if this isn't a CommonJS entry point + if repr.Meta.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{}}, @@ -1756,48 +1773,9 @@ func (c *linkerContext) createExportsForFile(sourceIndex uint32) { }) } - // If this file was originally ESM but is now in CommonJS, add a call to - // "__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. - 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{ - Target: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: markAsModuleRef}}, - Args: []js_ast.Expr{{Data: &js_ast.EIdentifier{Ref: repr.AST.ExportsRef}}}, - }}}}) - - // Make sure this file depends on the "__markAsModule" symbol - for _, partIndex := range runtimeRepr.TopLevelSymbolToParts(markAsModuleRef) { - nsExportDependencies = append(nsExportDependencies, js_ast.Dependency{ - SourceIndex: runtime.SourceIndex, - PartIndex: partIndex, - }) - } - - // Pull in the "__markAsModule" symbol later. Also make sure the "exports" - // variable is marked as used because we used it above. - repr.Meta.NeedsMarkAsModuleSymbolFromRuntime = true - repr.AST.UsesExportsRef = true - } - // "__export(exports, { foo: () => foo })" exportRef := js_ast.InvalidRef - if needsExportCall { + if len(properties) > 0 { 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{ @@ -3582,7 +3560,8 @@ func (c *linkerContext) generateCodeForFileInChunkJS( partRange partRange, entryBits helpers.BitSet, chunkAbsDir string, - toModuleRef js_ast.Ref, + toCommonJSRef js_ast.Ref, + toESMRef js_ast.Ref, runtimeRequireRef js_ast.Ref, result *compileResultJS, dataForSourceMaps []dataForSourceMap, @@ -3796,7 +3775,8 @@ func (c *linkerContext) generateCodeForFileInChunkJS( RemoveWhitespace: c.options.RemoveWhitespace, MangleSyntax: c.options.MangleSyntax, ASCIIOnly: c.options.ASCIIOnly, - ToModuleRef: toModuleRef, + ToCommonJSRef: toCommonJSRef, + ToESMRef: toESMRef, RuntimeRequireRef: runtimeRequireRef, LegalComments: c.options.LegalComments, UnsupportedFeatures: c.options.UnsupportedJSFeatures, @@ -3818,7 +3798,8 @@ func (c *linkerContext) generateCodeForFileInChunkJS( func (c *linkerContext) generateEntryPointTailJS( r renamer.Renamer, - toModuleRef js_ast.Ref, + toCommonJSRef js_ast.Ref, + toESMRef js_ast.Ref, sourceIndex uint32, ) (result compileResultJS) { file := &c.graph.Files[sourceIndex] @@ -3855,10 +3836,14 @@ func (c *linkerContext) generateEntryPointTailJS( Target: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: repr.AST.WrapperRef}}, }}}}) } - if repr.Meta.ForceIncludeExportsForEntryPoint && len(c.options.GlobalName) > 0 { - // "return exports;" + + if repr.Meta.ForceIncludeExportsForEntryPoint { + // "return __toCommonJS(exports);" stmts = append(stmts, js_ast.Stmt{Data: &js_ast.SReturn{ - ValueOrNil: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: repr.AST.ExportsRef}}, + ValueOrNil: js_ast.Expr{Data: &js_ast.ECall{ + Target: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: toCommonJSRef}}, + Args: []js_ast.Expr{{Data: &js_ast.EIdentifier{Ref: repr.AST.ExportsRef}}}, + }}, }}) } } @@ -3875,11 +3860,32 @@ func (c *linkerContext) generateEntryPointTailJS( Target: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: repr.AST.WrapperRef}}, }}, )) - } else if repr.Meta.Wrap == graph.WrapESM { - // "init_foo();" - stmts = append(stmts, js_ast.Stmt{Data: &js_ast.SExpr{Value: js_ast.Expr{Data: &js_ast.ECall{ - Target: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: repr.AST.WrapperRef}}, - }}}}) + } else { + if repr.Meta.Wrap == graph.WrapESM { + // "init_foo();" + stmts = append(stmts, js_ast.Stmt{Data: &js_ast.SExpr{Value: js_ast.Expr{Data: &js_ast.ECall{ + Target: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: repr.AST.WrapperRef}}, + }}}}) + } + + // Decorate "module.exports" with the "__esModule" flag to indicate that + // we used to be an ES module. This is done by wrapping the exports object + // instead of by mutating the exports object because other modules in the + // bundle (including the entry point module) may do "import * as" to get + // access to the exports object and should NOT see the "__esModule" flag. + if repr.Meta.ForceIncludeExportsForEntryPoint { + // "module.exports = __toCommonJS(exports);" + stmts = append(stmts, js_ast.AssignStmt( + js_ast.Expr{Data: &js_ast.EDot{ + Target: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: c.unboundModuleRef}}, + Name: "exports", + }}, + js_ast.Expr{Data: &js_ast.ECall{ + Target: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: toCommonJSRef}}, + Args: []js_ast.Expr{{Data: &js_ast.EIdentifier{Ref: repr.AST.ExportsRef}}}, + }}, + )) + } } // If we are generating CommonJS for node, encode the known export names in @@ -3944,7 +3950,7 @@ func (c *linkerContext) generateEntryPointTailJS( Left: js_ast.Expr{Data: &js_ast.ENumber{Value: 0}}, Right: js_ast.Assign( js_ast.Expr{Data: &js_ast.EDot{ - Target: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: repr.AST.ModuleRef}}, + Target: js_ast.Expr{Data: &js_ast.EIdentifier{Ref: c.unboundModuleRef}}, Name: "exports", }}, js_ast.Expr{Data: &js_ast.EObject{Properties: moduleExports}}, @@ -4032,7 +4038,7 @@ func (c *linkerContext) generateEntryPointTailJS( // }); // // // entry_point.js - // var cjs_format = __toModule(require_cjs_format()); + // var cjs_format = __toESM(require_cjs_format()); // var export_foo = cjs_format.foo; // export { // export_foo as foo @@ -4105,7 +4111,8 @@ func (c *linkerContext) generateEntryPointTailJS( RemoveWhitespace: c.options.RemoveWhitespace, MangleSyntax: c.options.MangleSyntax, ASCIIOnly: c.options.ASCIIOnly, - ToModuleRef: toModuleRef, + ToCommonJSRef: toCommonJSRef, + ToESMRef: toESMRef, LegalComments: c.options.LegalComments, UnsupportedFeatures: c.options.UnsupportedJSFeatures, RequireOrImportMetaForSource: c.requireOrImportMetaForSource, @@ -4364,7 +4371,8 @@ func (c *linkerContext) generateChunkJS(chunks []chunkInfo, chunkIndex int, chun chunkRepr := chunk.chunkRepr.(*chunkReprJS) compileResults := make([]compileResultJS, 0, len(chunkRepr.partsInChunkInOrder)) runtimeMembers := c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr).AST.ModuleScope.Members - toModuleRef := js_ast.FollowSymbols(c.graph.Symbols, runtimeMembers["__toModule"].Ref) + toCommonJSRef := js_ast.FollowSymbols(c.graph.Symbols, runtimeMembers["__toCommonJS"].Ref) + toESMRef := js_ast.FollowSymbols(c.graph.Symbols, runtimeMembers["__toESM"].Ref) runtimeRequireRef := js_ast.FollowSymbols(c.graph.Symbols, runtimeMembers["__require"].Ref) r := c.renameSymbolsInChunk(chunk, chunkRepr.filesInChunkInOrder, timer) dataForSourceMaps := c.dataForSourceMaps() @@ -4397,7 +4405,8 @@ func (c *linkerContext) generateChunkJS(chunks []chunkInfo, chunkIndex int, chun partRange, chunk.entryBits, chunkAbsDir, - toModuleRef, + toCommonJSRef, + toESMRef, runtimeRequireRef, compileResult, dataForSourceMaps, @@ -4440,7 +4449,8 @@ func (c *linkerContext) generateChunkJS(chunks []chunkInfo, chunkIndex int, chun if chunk.isEntryPoint { entryPointTail = c.generateEntryPointTailJS( r, - toModuleRef, + toCommonJSRef, + toESMRef, chunk.sourceIndex, ) } diff --git a/internal/bundler/snapshots/snapshots_dce.txt b/internal/bundler/snapshots/snapshots_dce.txt index e82e5a7149d..dec9b9fe68a 100644 --- a/internal/bundler/snapshots/snapshots_dce.txt +++ b/internal/bundler/snapshots/snapshots_dce.txt @@ -251,7 +251,7 @@ var require_foo = __commonJS({ }); // Users/user/project/node_modules/pkg/index.js -var import_foo = __toModule(require_foo()); +var import_foo = __toESM(require_foo()); // Users/user/project/entry.js console.log(import_foo.default); @@ -509,7 +509,7 @@ var require_demo_pkg = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_demo_pkg()); +var import_demo_pkg = __toESM(require_demo_pkg()); console.log(import_demo_pkg.foo); ================================================================================ @@ -534,7 +534,7 @@ var require_demo_pkg = __commonJS({ }); // Users/user/project/src/entry.js -var ns = __toModule(require_demo_pkg()); +var ns = __toESM(require_demo_pkg()); console.log(ns); ================================================================================ @@ -662,7 +662,7 @@ var require_demo_pkg = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_demo_pkg()); +var import_demo_pkg = __toESM(require_demo_pkg()); console.log("unused import"); ================================================================================ @@ -848,7 +848,7 @@ var init_cjs = __esm({ // entry.js init_lib(); -console.log(keep1(), (init_cjs(), cjs_exports)); +console.log(keep1(), (init_cjs(), __toCommonJS(cjs_exports))); ================================================================================ TestTreeShakingNoBundleCJS diff --git a/internal/bundler/snapshots/snapshots_default.txt b/internal/bundler/snapshots/snapshots_default.txt index 6713a451e78..22a07c8d213 100644 --- a/internal/bundler/snapshots/snapshots_default.txt +++ b/internal/bundler/snapshots/snapshots_default.txt @@ -301,9 +301,9 @@ var init_bar = __esm({ }); // entry.js -var { foo: foo2 } = (init_foo(), foo_exports); +var { foo: foo2 } = (init_foo(), __toCommonJS(foo_exports)); console.log(foo2(), bar2()); -var { bar: bar2 } = (init_bar(), bar_exports); +var { bar: bar2 } = (init_bar(), __toCommonJS(bar_exports)); ================================================================================ TestConditionalImport @@ -316,7 +316,7 @@ var require_import = __commonJS({ }); // a.js -x ? import("a") : y ? Promise.resolve().then(() => __toModule(require_import())) : import("c"); +x ? import("a") : y ? Promise.resolve().then(() => __toESM(require_import())) : import("c"); ---------- /out/b.js ---------- // import.js @@ -327,7 +327,7 @@ var require_import = __commonJS({ }); // b.js -x ? y ? import("a") : Promise.resolve().then(() => __toModule(require_import())) : import(c); +x ? y ? import("a") : Promise.resolve().then(() => __toESM(require_import())) : import(c); ================================================================================ TestConditionalRequire @@ -465,7 +465,7 @@ var require_index = __commonJS({ }); // entry.js -var import__ = __toModule(require_index()); +var import__ = __toESM(require_index()); console.log(import__.x); ================================================================================ @@ -501,8 +501,8 @@ TestDynamicImportWithTemplateIIFE }); // a.js - Promise.resolve().then(() => __toModule(require_b())).then((ns) => console.log(ns)); - Promise.resolve().then(() => __toModule(require_b())).then((ns) => console.log(ns)); + Promise.resolve().then(() => __toESM(require_b())).then((ns) => console.log(ns)); + Promise.resolve().then(() => __toESM(require_b())).then((ns) => console.log(ns)); })(); ================================================================================ @@ -527,8 +527,8 @@ var require_bar = __commonJS({ }); // entry.js -var import_foo = __toModule(require_foo()); -var import_bar = __toModule(require_bar()); +var import_foo = __toESM(require_foo()); +var import_bar = __toESM(require_bar()); console.log((0, import_foo.foo)(), (0, import_bar.bar)()); ================================================================================ @@ -536,14 +536,13 @@ TestEmptyExportClauseBundleAsCommonJSIssue910 ---------- /out.js ---------- // types.mjs var types_exports = {}; -__markAsModule(types_exports); var init_types = __esm({ "types.mjs"() { } }); // entry.js -console.log((init_types(), types_exports)); +console.log((init_types(), __toCommonJS(types_exports))); ================================================================================ TestEntryNamesNoSlashAfterDir @@ -808,7 +807,7 @@ var globalName = (() => { } var Class = class { }; - return entry_exports; + return __toCommonJS(entry_exports); })(); ================================================================================ @@ -850,8 +849,9 @@ export default class o { TestExportWildcardFSNodeCommonJS ---------- /out.js ---------- // entry.js -__markAsModule(exports); -__reExport(exports, __toModule(require("fs"))); +var entry_exports = {}; +__reExport(entry_exports, __toESM(require("fs"))); +module.exports = __toCommonJS(entry_exports); ================================================================================ TestExportWildcardFSNodeES6 @@ -928,7 +928,6 @@ var init_d = __esm({ // e.js var e_exports = {}; -__markAsModule(e_exports); import * as x_star from "x"; var init_e = __esm({ "e.js"() { @@ -1031,10 +1030,10 @@ console.log(file_default, file_default2); TestImportFSNodeCommonJS ---------- /out.js ---------- // entry.js -var import_fs = __toModule(require("fs")); -var fs = __toModule(require("fs")); -var import_fs2 = __toModule(require("fs")); -var import_fs3 = __toModule(require("fs")); +var import_fs = __toESM(require("fs")); +var fs = __toESM(require("fs")); +var import_fs2 = __toESM(require("fs")); +var import_fs3 = __toESM(require("fs")); console.log(fs, import_fs3.readFileSync, import_fs2.default); ================================================================================ @@ -1112,7 +1111,7 @@ var require_foo = __commonJS({ }); // entry.js -var import_foo = __toModule(require_foo()); +var import_foo = __toESM(require_foo()); console.log((0, import_foo.default)(import_foo.x, import_foo.y)); ================================================================================ @@ -1126,7 +1125,7 @@ var require_foo = __commonJS({ }); // named.js -var import_foo = __toModule(require_foo()); +var import_foo = __toESM(require_foo()); console.log((0, import_foo.default)(void 0, void 0)); ---------- /out/star.js ---------- @@ -1138,7 +1137,7 @@ var require_foo = __commonJS({ }); // star.js -var ns = __toModule(require_foo()); +var ns = __toESM(require_foo()); console.log(ns.default(void 0, void 0)); ---------- /out/star-capture.js ---------- @@ -1150,7 +1149,7 @@ var require_foo = __commonJS({ }); // star-capture.js -var ns = __toModule(require_foo()); +var ns = __toESM(require_foo()); console.log(ns); ---------- /out/bare.js ---------- @@ -1177,23 +1176,23 @@ var require_foo = __commonJS({ }); // import.js -console.log(Promise.resolve().then(() => __toModule(require_foo()))); +console.log(Promise.resolve().then(() => __toESM(require_foo()))); ================================================================================ TestImportNamespaceThisValue ---------- /out/a.js ---------- // a.js -var ns = __toModule(require("external")); +var ns = __toESM(require("external")); console.log(ns[foo](), new ns[foo]()); ---------- /out/b.js ---------- // b.js -var ns = __toModule(require("external")); +var ns = __toESM(require("external")); console.log(ns.foo(), new ns.foo()); ---------- /out/c.js ---------- // c.js -var import_external = __toModule(require("external")); +var import_external = __toESM(require("external")); console.log((0, import_external.default)(), (0, import_external.foo)()); console.log(new import_external.default(), new import_external.foo()); @@ -1272,7 +1271,7 @@ var replace = { }; // re-export.js -var import_external_pkg = __toModule(require("external-pkg")); +var import_external_pkg = __toESM(require("external-pkg")); // entry.js var sideEffects2 = console.log("this should be renamed"); @@ -1376,7 +1375,7 @@ var require_custom_react = __commonJS({ }); // entry.jsx -var import_custom_react = __toModule(require_custom_react()); +var import_custom_react = __toESM(require_custom_react()); console.log(/* @__PURE__ */ (0, import_custom_react.elem)("div", null), /* @__PURE__ */ (0, import_custom_react.elem)(import_custom_react.frag, null, "fragment")); ================================================================================ @@ -2075,21 +2074,21 @@ import("foo");import(foo()); TestMinifiedExportsAndModuleFormatCommonJS ---------- /out.js ---------- // foo/test.js -var r = {}; -f(r, { - foo: () => m +var o = {}; +p(o, { + foo: () => l }); -var m = 123; +var l = 123; // bar/test.js -var t = {}; -f(t, { - bar: () => s +var r = {}; +p(r, { + bar: () => m }); -var s = 123; +var m = 123; // entry.js -console.log(exports, module.exports, r, t); +console.log(exports, module.exports, o, r); ================================================================================ TestMinifyArguments @@ -2238,7 +2237,7 @@ var require_foo = __commonJS({ }); // entry.js -var import_foo = __toModule(require_foo()); +var import_foo = __toESM(require_foo()); (() => { console.log((0, import_foo.fn)()); })(); @@ -2295,7 +2294,7 @@ var require_demo_pkg = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_demo_pkg()); +var import_demo_pkg = __toESM(require_demo_pkg()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -2324,14 +2323,14 @@ console.log("test"); TestQuotedProperty ---------- /out/entry.js ---------- // entry.js -var ns = __toModule(require("ext")); +var ns = __toESM(require("ext")); console.log(ns.mustBeUnquoted, ns["mustBeQuoted"]); ================================================================================ TestQuotedPropertyMangle ---------- /out/entry.js ---------- // entry.js -var ns = __toModule(require("ext")); +var ns = __toESM(require("ext")); console.log(ns.mustBeUnquoted, ns.mustBeUnquoted2); ================================================================================ @@ -2345,7 +2344,7 @@ var require_foo = __commonJS({ }); // entry.js -var import_foo = __toModule(require_foo()); +var import_foo = __toESM(require_foo()); var export_bar = import_foo.bar; export { export_bar as bar @@ -2355,14 +2354,16 @@ export { TestReExportDefaultExternalCommonJS ---------- /out.js ---------- // entry.js -__export(exports, { +var entry_exports = {}; +__export(entry_exports, { bar: () => import_bar.default, foo: () => import_foo.default }); -var import_foo = __toModule(require("foo")); +var import_foo = __toESM(require("foo")); // bar.js -var import_bar = __toModule(require("bar")); +var import_bar = __toESM(require("bar")); +module.exports = __toCommonJS(entry_exports); ================================================================================ TestReExportDefaultExternalES6 @@ -2399,12 +2400,14 @@ export { default as bar } from "./bar"; ================================================================================ TestReExportDefaultNoBundleCommonJS ---------- /out.js ---------- -__export(exports, { +var entry_exports = {}; +__export(entry_exports, { bar: () => import_bar.default, foo: () => import_foo.default }); -var import_foo = __toModule(require("./foo")); -var import_bar = __toModule(require("./bar")); +var import_foo = __toESM(require("./foo")); +var import_bar = __toESM(require("./bar")); +module.exports = __toCommonJS(entry_exports); ================================================================================ TestReExportDefaultNoBundleES6 @@ -2663,8 +2666,8 @@ console.log([ __require(window.SOME_PATH), __require.resolve("some-path"), __require.resolve(window.SOME_PATH), - Promise.resolve().then(() => __toModule(__require("some-path"))), - Promise.resolve().then(() => __toModule(__require(window.SOME_PATH))) + Promise.resolve().then(() => __toESM(__require("some-path"))), + Promise.resolve().then(() => __toESM(__require(window.SOME_PATH))) ]); ================================================================================ @@ -3252,7 +3255,7 @@ var init_dummy = __esm({ // es6-import-assign.ts var require_es6_import_assign = __commonJS({ "es6-import-assign.ts"(exports) { - var x2 = (init_dummy(), dummy_exports); + var x2 = (init_dummy(), __toCommonJS(dummy_exports)); console.log(exports); } }); @@ -3385,21 +3388,21 @@ var require_es6_ns_export_abstract_class = __commonJS({ }); // entry.js -var import_cjs = __toModule(require_cjs()); +var import_cjs = __toESM(require_cjs()); // es6-import-stmt.js init_dummy(); console.log(void 0); // entry.js -var import_es6_import_assign = __toModule(require_es6_import_assign()); -var import_es6_import_dynamic = __toModule(require_es6_import_dynamic()); +var import_es6_import_assign = __toESM(require_es6_import_assign()); +var import_es6_import_dynamic = __toESM(require_es6_import_dynamic()); // es6-import-meta.js console.log(void 0); // entry.js -var import_es6_expr_import_dynamic = __toModule(require_es6_expr_import_dynamic()); +var import_es6_expr_import_dynamic = __toESM(require_es6_expr_import_dynamic()); // es6-expr-import-meta.js console.log(void 0); @@ -3450,22 +3453,22 @@ init_dummy(); console.log(void 0); // entry.js -var import_es6_export_assign = __toModule(require_es6_export_assign()); +var import_es6_export_assign = __toESM(require_es6_export_assign()); // es6-export-import-assign.ts -var x = (init_dummy(), dummy_exports); +var x = (init_dummy(), __toCommonJS(dummy_exports)); console.log(void 0); // entry.js -var import_es6_ns_export_variable = __toModule(require_es6_ns_export_variable()); -var import_es6_ns_export_function = __toModule(require_es6_ns_export_function()); -var import_es6_ns_export_async_function = __toModule(require_es6_ns_export_async_function()); -var import_es6_ns_export_enum = __toModule(require_es6_ns_export_enum()); -var import_es6_ns_export_const_enum = __toModule(require_es6_ns_export_const_enum()); -var import_es6_ns_export_module = __toModule(require_es6_ns_export_module()); -var import_es6_ns_export_namespace = __toModule(require_es6_ns_export_namespace()); -var import_es6_ns_export_class = __toModule(require_es6_ns_export_class()); -var import_es6_ns_export_abstract_class = __toModule(require_es6_ns_export_abstract_class()); +var import_es6_ns_export_variable = __toESM(require_es6_ns_export_variable()); +var import_es6_ns_export_function = __toESM(require_es6_ns_export_function()); +var import_es6_ns_export_async_function = __toESM(require_es6_ns_export_async_function()); +var import_es6_ns_export_enum = __toESM(require_es6_ns_export_enum()); +var import_es6_ns_export_const_enum = __toESM(require_es6_ns_export_const_enum()); +var import_es6_ns_export_module = __toESM(require_es6_ns_export_module()); +var import_es6_ns_export_namespace = __toESM(require_es6_ns_export_namespace()); +var import_es6_ns_export_class = __toESM(require_es6_ns_export_class()); +var import_es6_ns_export_abstract_class = __toESM(require_es6_ns_export_abstract_class()); ================================================================================ TestTopLevelAwaitAllowedImportWithSplitting @@ -3499,7 +3502,6 @@ TestTopLevelAwaitAllowedImportWithoutSplitting ---------- /out.js ---------- // c.js var c_exports = {}; -__markAsModule(c_exports); var init_c = __esm({ async "c.js"() { await 0; @@ -3508,7 +3510,6 @@ var init_c = __esm({ // b.js var b_exports = {}; -__markAsModule(b_exports); var init_b = __esm({ async "b.js"() { await init_c(); @@ -3517,7 +3518,6 @@ var init_b = __esm({ // a.js var a_exports = {}; -__markAsModule(a_exports); var init_a = __esm({ async "a.js"() { await init_b(); @@ -3526,7 +3526,6 @@ var init_a = __esm({ // entry.js var entry_exports = {}; -__markAsModule(entry_exports); var init_entry = __esm({ async "entry.js"() { init_a(); @@ -3568,7 +3567,7 @@ TestUseStrictDirectiveBundleIssue1837 var import_process; var init_shims = __esm({ "shims.js"() { - import_process = __toModule(__require("process")); + import_process = __toESM(__require("process")); } }); @@ -3652,9 +3651,9 @@ switch (x) { !a instanceof b; // entry.js -var import_return_asi = __toModule(require_return_asi()); -var import_return_asi2 = __toModule(require_return_asi2()); -var import_return_asi3 = __toModule(require_return_asi3()); +var import_return_asi = __toESM(require_return_asi()); +var import_return_asi2 = __toESM(require_return_asi2()); +var import_return_asi3 = __toESM(require_return_asi3()); // equals-neg-zero.js x === -0; diff --git a/internal/bundler/snapshots/snapshots_importstar.txt b/internal/bundler/snapshots/snapshots_importstar.txt index 8c5312c7fd6..5da9d998944 100644 --- a/internal/bundler/snapshots/snapshots_importstar.txt +++ b/internal/bundler/snapshots/snapshots_importstar.txt @@ -8,10 +8,12 @@ var require_foo = __commonJS({ }); // entry.js -__export(exports, { +var entry_exports = {}; +__export(entry_exports, { ns: () => ns }); -var ns = __toModule(require_foo()); +var ns = __toESM(require_foo()); +module.exports = __toCommonJS(entry_exports); ================================================================================ TestExportOtherCommonJS @@ -24,10 +26,12 @@ var require_foo = __commonJS({ }); // entry.js -__export(exports, { +var entry_exports = {}; +__export(entry_exports, { bar: () => import_foo.bar }); -var import_foo = __toModule(require_foo()); +var import_foo = __toESM(require_foo()); +module.exports = __toCommonJS(entry_exports); ================================================================================ TestExportOtherNestedCommonJS @@ -40,48 +44,56 @@ var require_foo = __commonJS({ }); // entry.js -__export(exports, { +var entry_exports = {}; +__export(entry_exports, { y: () => import_foo.x }); // bar.js -var import_foo = __toModule(require_foo()); +var import_foo = __toESM(require_foo()); +module.exports = __toCommonJS(entry_exports); ================================================================================ TestExportSelfAndImportSelfCommonJS ---------- /out.js ---------- // entry.js -__export(exports, { +var entry_exports = {}; +__export(entry_exports, { foo: () => foo }); var foo = 123; -console.log(exports); +console.log(entry_exports); +module.exports = __toCommonJS(entry_exports); ================================================================================ TestExportSelfAndRequireSelfCommonJS ---------- /out.js ---------- // entry.js -__export(exports, { +var entry_exports = {}; +__export(entry_exports, { foo: () => foo }); var foo; var init_entry = __esm({ "entry.js"() { foo = 123; - console.log((init_entry(), exports)); + console.log((init_entry(), __toCommonJS(entry_exports))); } }); init_entry(); +module.exports = __toCommonJS(entry_exports); ================================================================================ TestExportSelfAsNamespaceCommonJS ---------- /out.js ---------- // entry.js -__export(exports, { +var entry_exports = {}; +__export(entry_exports, { foo: () => foo, - ns: () => exports + ns: () => entry_exports }); var foo = 123; +module.exports = __toCommonJS(entry_exports); ================================================================================ TestExportSelfAsNamespaceES6 @@ -102,10 +114,12 @@ export { TestExportSelfCommonJS ---------- /out.js ---------- // entry.js -__export(exports, { +var entry_exports = {}; +__export(entry_exports, { foo: () => foo }); var foo = 123; +module.exports = __toCommonJS(entry_exports); ================================================================================ TestExportSelfCommonJSMinified @@ -144,19 +158,21 @@ var someName = (() => { foo: () => foo }); var foo = 123; - return entry_exports; + return __toCommonJS(entry_exports); })(); ================================================================================ TestExportStarDefaultExportCommonJS ---------- /out.js ---------- // entry.js -__export(exports, { +var entry_exports = {}; +__export(entry_exports, { foo: () => foo }); // foo.js var foo = "foo"; +module.exports = __toCommonJS(entry_exports); ================================================================================ TestImportDefaultNamespaceComboIssue446 @@ -255,10 +271,12 @@ var require_foo = __commonJS({ }); // entry.js -__export(exports, { +var entry_exports = {}; +__export(entry_exports, { ns: () => ns }); -var ns = __toModule(require_foo()); +var ns = __toESM(require_foo()); +module.exports = __toCommonJS(entry_exports); ================================================================================ TestImportExportSelfAsNamespaceES6 @@ -303,8 +321,8 @@ var require_empty2 = __commonJS({ }); // entry-nope.js -var js = __toModule(require_empty()); -var cjs = __toModule(require_empty2()); +var js = __toESM(require_empty()); +var cjs = __toESM(require_empty2()); console.log(void 0, void 0, void 0); ---------- /out/entry-default.js ---------- @@ -321,8 +339,8 @@ var require_empty2 = __commonJS({ }); // entry-default.js -var js = __toModule(require_empty()); -var cjs = __toModule(require_empty2()); +var js = __toESM(require_empty()); +var cjs = __toESM(require_empty2()); console.log(js.default, void 0, cjs.default); ================================================================================ @@ -343,8 +361,8 @@ var require_no_side_effects2 = __commonJS({ }); // entry-nope.js -var js = __toModule(require_no_side_effects()); -var cjs = __toModule(require_no_side_effects2()); +var js = __toESM(require_no_side_effects()); +var cjs = __toESM(require_no_side_effects2()); console.log(void 0, void 0, void 0); ---------- /out/entry-default.js ---------- @@ -363,8 +381,8 @@ var require_no_side_effects2 = __commonJS({ }); // entry-default.js -var js = __toModule(require_no_side_effects()); -var cjs = __toModule(require_no_side_effects2()); +var js = __toESM(require_no_side_effects()); +var cjs = __toESM(require_no_side_effects2()); console.log(js.default, void 0, cjs.default); ================================================================================ @@ -401,7 +419,7 @@ TestImportSelfCommonJS // entry.js var require_entry = __commonJS({ "entry.js"(exports) { - var import_entry = __toModule(require_entry()); + var import_entry = __toESM(require_entry()); exports.foo = 123; console.log(import_entry.foo); } @@ -425,7 +443,7 @@ var init_foo = __esm({ // entry.js init_foo(); -var ns2 = (init_foo(), foo_exports); +var ns2 = (init_foo(), __toCommonJS(foo_exports)); console.log(foo, ns2.foo); ================================================================================ @@ -453,7 +471,7 @@ var require_foo = __commonJS({ }); // entry.js -var ns = __toModule(require_foo()); +var ns = __toESM(require_foo()); var foo2 = 234; console.log(ns, ns.foo, foo2); @@ -468,7 +486,7 @@ var require_foo = __commonJS({ }); // entry.js -var ns = __toModule(require_foo()); +var ns = __toESM(require_foo()); var foo2 = 234; console.log(ns.foo, ns.foo, foo2); @@ -483,7 +501,7 @@ var require_foo = __commonJS({ }); // entry.js -var ns = __toModule(require_foo()); +var ns = __toESM(require_foo()); var foo = 234; console.log(foo); @@ -713,7 +731,7 @@ var require_foo = __commonJS({ }); // entry.js -var ns = __toModule(require_foo()); +var ns = __toESM(require_foo()); console.log(ns, ns.foo); ================================================================================ @@ -761,7 +779,7 @@ var require_foo = __commonJS({ }); // entry.js -var ns = __toModule(require_foo()); +var ns = __toESM(require_foo()); console.log(ns.foo); ================================================================================ @@ -847,10 +865,12 @@ export { ================================================================================ TestReExportStarAsCommonJSNoBundle ---------- /out.js ---------- -__export(exports, { +var entry_exports = {}; +__export(entry_exports, { out: () => out }); -var out = __toModule(require("foo")); +var out = __toESM(require("foo")); +module.exports = __toCommonJS(entry_exports); ================================================================================ TestReExportStarAsES6NoBundle @@ -864,10 +884,12 @@ export { TestReExportStarAsExternalCommonJS ---------- /out.js ---------- // entry.js -__export(exports, { +var entry_exports = {}; +__export(entry_exports, { out: () => out }); -var out = __toModule(require("foo")); +var out = __toESM(require("foo")); +module.exports = __toCommonJS(entry_exports); ================================================================================ TestReExportStarAsExternalES6 @@ -887,8 +909,8 @@ var mod = (() => { __export(entry_exports, { out: () => out }); - var out = __toModule(__require("foo")); - return entry_exports; + var out = __toESM(__require("foo")); + return __toCommonJS(entry_exports); })(); ================================================================================ @@ -899,15 +921,16 @@ var mod = (() => { __export(entry_exports, { out: () => out }); - var out = __toModule(require("foo")); - return entry_exports; + var out = __toESM(require("foo")); + return __toCommonJS(entry_exports); })(); ================================================================================ TestReExportStarCommonJSNoBundle ---------- /out.js ---------- -__markAsModule(exports); -__reExport(exports, __toModule(require("foo"))); +var entry_exports = {}; +__reExport(entry_exports, __toESM(require("foo"))); +module.exports = __toCommonJS(entry_exports); ================================================================================ TestReExportStarES6NoBundle @@ -918,8 +941,9 @@ export * from "foo"; TestReExportStarExternalCommonJS ---------- /out.js ---------- // entry.js -__markAsModule(exports); -__reExport(exports, __toModule(require("foo"))); +var entry_exports = {}; +__reExport(entry_exports, __toESM(require("foo"))); +module.exports = __toCommonJS(entry_exports); ================================================================================ TestReExportStarExternalES6 @@ -933,9 +957,8 @@ TestReExportStarExternalIIFE var mod = (() => { // entry.js var entry_exports = {}; - __markAsModule(entry_exports); - __reExport(entry_exports, __toModule(__require("foo"))); - return entry_exports; + __reExport(entry_exports, __toESM(__require("foo"))); + return __toCommonJS(entry_exports); })(); ================================================================================ @@ -943,9 +966,8 @@ TestReExportStarIIFENoBundle ---------- /out.js ---------- var mod = (() => { var entry_exports = {}; - __markAsModule(entry_exports); - __reExport(entry_exports, __toModule(require("foo"))); - return entry_exports; + __reExport(entry_exports, __toESM(require("foo"))); + return __toCommonJS(entry_exports); })(); ================================================================================ diff --git a/internal/bundler/snapshots/snapshots_importstar_ts.txt b/internal/bundler/snapshots/snapshots_importstar_ts.txt index 6bbade4d118..c4fee5b6b7c 100644 --- a/internal/bundler/snapshots/snapshots_importstar_ts.txt +++ b/internal/bundler/snapshots/snapshots_importstar_ts.txt @@ -14,7 +14,7 @@ var init_foo = __esm({ // entry.js init_foo(); -var ns2 = (init_foo(), foo_exports); +var ns2 = (init_foo(), __toCommonJS(foo_exports)); console.log(foo, ns2.foo); ================================================================================ @@ -42,7 +42,7 @@ var require_foo = __commonJS({ }); // entry.ts -var ns = __toModule(require_foo()); +var ns = __toESM(require_foo()); var foo2 = 234; console.log(ns, ns.foo, foo2); @@ -57,7 +57,7 @@ var require_foo = __commonJS({ }); // entry.ts -var ns = __toModule(require_foo()); +var ns = __toESM(require_foo()); var foo2 = 234; console.log(ns.foo, ns.foo, foo2); diff --git a/internal/bundler/snapshots/snapshots_packagejson.txt b/internal/bundler/snapshots/snapshots_packagejson.txt index d95fc90f9fb..51b8cc47c35 100644 --- a/internal/bundler/snapshots/snapshots_packagejson.txt +++ b/internal/bundler/snapshots/snapshots_packagejson.txt @@ -10,7 +10,7 @@ var require_demo_pkg = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_demo_pkg()); +var import_demo_pkg = __toESM(require_demo_pkg()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -71,7 +71,7 @@ var require_demo_pkg = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_demo_pkg()); +var import_demo_pkg = __toESM(require_demo_pkg()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -97,7 +97,7 @@ var require_demo_pkg = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_demo_pkg()); +var import_demo_pkg = __toESM(require_demo_pkg()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -123,7 +123,7 @@ var require_demo_pkg = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_demo_pkg()); +var import_demo_pkg = __toESM(require_demo_pkg()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -146,7 +146,7 @@ var require_demo_pkg = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_demo_pkg()); +var import_demo_pkg = __toESM(require_demo_pkg()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -169,7 +169,7 @@ var require_main = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_main()); +var import_demo_pkg = __toESM(require_main()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -193,7 +193,7 @@ var require_main = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_main()); +var import_demo_pkg = __toESM(require_main()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -217,7 +217,7 @@ var require_main_browser = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_main_browser()); +var import_demo_pkg = __toESM(require_main_browser()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -287,7 +287,7 @@ var require_main = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_main()); +var import_demo_pkg = __toESM(require_main()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -303,7 +303,7 @@ var require_main_browser = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_main_browser()); +var import_demo_pkg = __toESM(require_main_browser()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -319,7 +319,7 @@ var require_browser = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_browser()); +var import_demo_pkg = __toESM(require_browser()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -335,7 +335,7 @@ var require_main = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_main()); +var import_demo_pkg = __toESM(require_main()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -363,7 +363,7 @@ var require_main_browser = __commonJS({ console.log(require_main_browser()); // Users/user/project/src/test-module.js -var import_demo_pkg = __toModule(require_main_browser()); +var import_demo_pkg = __toESM(require_main_browser()); console.log(import_demo_pkg.default); ================================================================================ @@ -382,7 +382,7 @@ var init_module = __esm({ }); // Users/user/project/src/test-main.js -console.log((init_module(), module_exports)); +console.log((init_module(), __toCommonJS(module_exports))); // Users/user/project/src/test-module.js init_module(); @@ -402,7 +402,7 @@ var require_demo_pkg = __commonJS({ console.log(require_demo_pkg()); // Users/user/project/src/test-module.js -var import_demo_pkg = __toModule(require_demo_pkg()); +var import_demo_pkg = __toESM(require_demo_pkg()); console.log(import_demo_pkg.default); ================================================================================ @@ -421,7 +421,7 @@ var init_module = __esm({ }); // Users/user/project/src/test-index.js -console.log((init_module(), module_exports)); +console.log((init_module(), __toCommonJS(module_exports))); // Users/user/project/src/test-module.js init_module(); @@ -438,7 +438,7 @@ var require_main = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_main()); +var import_demo_pkg = __toESM(require_main()); console.log(import_demo_pkg.default, require_main()); ================================================================================ @@ -455,7 +455,7 @@ var require_main = __commonJS({ console.log(require_main()); // Users/user/project/src/test-module.js -var import_demo_pkg = __toModule(require_main()); +var import_demo_pkg = __toESM(require_main()); console.log(import_demo_pkg.default); ================================================================================ @@ -587,7 +587,7 @@ var require_custom_main = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_custom_main()); +var import_demo_pkg = __toESM(require_custom_main()); console.log((0, import_demo_pkg.default)()); ================================================================================ @@ -601,7 +601,7 @@ var require_a = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_a()); +var import_demo_pkg = __toESM(require_a()); console.log(import_demo_pkg.default); ================================================================================ @@ -637,5 +637,5 @@ var require_main = __commonJS({ }); // Users/user/project/src/entry.js -var import_demo_pkg = __toModule(require_main()); +var import_demo_pkg = __toESM(require_main()); console.log((0, import_demo_pkg.default)()); diff --git a/internal/bundler/snapshots/snapshots_splitting.txt b/internal/bundler/snapshots/snapshots_splitting.txt index f3c396ff5e0..97632c329cd 100644 --- a/internal/bundler/snapshots/snapshots_splitting.txt +++ b/internal/bundler/snapshots/snapshots_splitting.txt @@ -203,21 +203,21 @@ console.log(123); TestSplittingDynamicAndNotDynamicCommonJSIntoES6 ---------- /out/entry.js ---------- import { - __toModule, + __toESM, require_foo -} from "./chunk-JPAPXZUJ.js"; +} from "./chunk-KUHUE66N.js"; // entry.js -var import_foo = __toModule(require_foo()); -import("./foo-2T7XICVR.js").then(({ default: { bar: b } }) => console.log(import_foo.bar, b)); +var import_foo = __toESM(require_foo()); +import("./foo-U6JCMRHQ.js").then(({ default: { bar: b } }) => console.log(import_foo.bar, b)); ----------- /out/foo-2T7XICVR.js ---------- +---------- /out/foo-U6JCMRHQ.js ---------- import { require_foo -} from "./chunk-JPAPXZUJ.js"; +} from "./chunk-KUHUE66N.js"; export default require_foo(); ----------- /out/chunk-JPAPXZUJ.js ---------- +---------- /out/chunk-KUHUE66N.js ---------- // foo.js var require_foo = __commonJS({ "foo.js"(exports) { @@ -226,7 +226,7 @@ var require_foo = __commonJS({ }); export { - __toModule, + __toESM, require_foo }; @@ -259,16 +259,10 @@ export { ================================================================================ TestSplittingDynamicCommonJSIntoES6 ---------- /out/entry.js ---------- -import "./chunk-D343XTR4.js"; - // entry.js -import("./foo-PKYCIAV6.js").then(({ default: { bar } }) => console.log(bar)); - ----------- /out/foo-PKYCIAV6.js ---------- -import { - __commonJS -} from "./chunk-D343XTR4.js"; +import("./foo-PPQD77K4.js").then(({ default: { bar } }) => console.log(bar)); +---------- /out/foo-PPQD77K4.js ---------- // foo.js var require_foo = __commonJS({ "foo.js"(exports) { @@ -277,11 +271,6 @@ var require_foo = __commonJS({ }); export default require_foo(); ----------- /out/chunk-D343XTR4.js ---------- -export { - __commonJS -}; - ================================================================================ TestSplittingDynamicES6IntoES6 ---------- /out/entry.js ---------- @@ -328,7 +317,7 @@ TestSplittingHybridESMAndCJSIssue617 import { foo, init_a -} from "./chunk-2OZ4VUMW.js"; +} from "./chunk-QRBKE4XE.js"; init_a(); export { foo @@ -336,17 +325,18 @@ export { ---------- /out/b.js ---------- import { + __toCommonJS, a_exports, init_a -} from "./chunk-2OZ4VUMW.js"; +} from "./chunk-QRBKE4XE.js"; // b.js -var bar = (init_a(), a_exports); +var bar = (init_a(), __toCommonJS(a_exports)); export { bar }; ----------- /out/chunk-2OZ4VUMW.js ---------- +---------- /out/chunk-QRBKE4XE.js ---------- // a.js var a_exports = {}; __export(a_exports, { @@ -359,6 +349,7 @@ var init_a = __esm({ }); export { + __toCommonJS, foo, a_exports, init_a @@ -399,7 +390,7 @@ TestSplittingMissingLazyExport ---------- /out/a.js ---------- import { foo -} from "./chunk-XM7WD27G.js"; +} from "./chunk-QVTGQSXT.js"; // a.js console.log(foo()); @@ -407,15 +398,14 @@ console.log(foo()); ---------- /out/b.js ---------- import { bar -} from "./chunk-XM7WD27G.js"; +} from "./chunk-QVTGQSXT.js"; // b.js console.log(bar()); ----------- /out/chunk-XM7WD27G.js ---------- +---------- /out/chunk-QVTGQSXT.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 2d79f85e621..db37b6d78cb 100644 --- a/internal/bundler/snapshots/snapshots_ts.txt +++ b/internal/bundler/snapshots/snapshots_ts.txt @@ -342,7 +342,7 @@ var require_b = __commonJS({ }); // a.ts -var import_b = __toModule(require_b()); +var import_b = __toESM(require_b()); console.log(import_b.default); ================================================================================ @@ -350,7 +350,6 @@ TestTSExportMissingES6 ---------- /out.js ---------- // foo.ts var foo_exports = {}; -__markAsModule(foo_exports); // entry.js console.log(foo_exports); diff --git a/internal/bundler/snapshots/snapshots_tsconfig.txt b/internal/bundler/snapshots/snapshots_tsconfig.txt index bfc7ef16ae0..d4382766513 100644 --- a/internal/bundler/snapshots/snapshots_tsconfig.txt +++ b/internal/bundler/snapshots/snapshots_tsconfig.txt @@ -10,7 +10,7 @@ var require_util = __commonJS({ }); // Users/user/project/src/app/entry.js -var import_util = __toModule(require_util()); +var import_util = __toESM(require_util()); console.log((0, import_util.default)()); ================================================================================ @@ -219,7 +219,7 @@ var require_util = __commonJS({ }); // Users/user/project/src/app/entry.js -var import_util = __toModule(require_util()); +var import_util = __toESM(require_util()); console.log((0, import_util.default)()); ================================================================================ @@ -235,7 +235,7 @@ var require_util = __commonJS({ }); // Users/user/project/src/app/entry.js -var import_util = __toModule(require_util()); +var import_util = __toESM(require_util()); console.log((0, import_util.default)()); ================================================================================ @@ -251,7 +251,7 @@ var require_util = __commonJS({ }); // Users/user/project/src/app/entry.js -var import_util = __toModule(require_util()); +var import_util = __toESM(require_util()); console.log((0, import_util.default)()); ================================================================================ @@ -324,7 +324,7 @@ var require_util = __commonJS({ }); // Users/user/project/src/app/entry.js -var import_util = __toModule(require_util()); +var import_util = __toESM(require_util()); console.log((0, import_util.default)()); ================================================================================ diff --git a/internal/graph/meta.go b/internal/graph/meta.go index 9529851282a..f7cb4597756 100644 --- a/internal/graph/meta.go +++ b/internal/graph/meta.go @@ -38,7 +38,7 @@ const ( // }); // // // bar.ts - // let foo = flag ? (init_foo(), foo_exports) : null; + // let foo = flag ? (init_foo(), __toCommonJS(foo_exports)) : null; // WrapESM ) @@ -133,6 +133,11 @@ type JSReprMeta struct { Wrap WrapKind + // If true, we need to insert "var exports = {};". This is the case for ESM + // files when the import namespace is captured via "import * as" and also + // when they are the target of a "require()" call. + NeedsExportsVariable bool + // If true, the "__export(exports, { ... })" call will be force-included even // if there are no parts that reference "exports". Otherwise this call will // be removed due to the tree shaking pass. This is used when for entry point @@ -143,8 +148,7 @@ type JSReprMeta struct { // This is set when we need to pull in the "__export" symbol in to the part // at "nsExportPartIndex". This can't be done in "createExportsForFile" // because of concurrent map hazards. Instead, it must be done later. - NeedsExportSymbolFromRuntime bool - NeedsMarkAsModuleSymbolFromRuntime bool + NeedsExportSymbolFromRuntime bool // Wrapped files must also ensure that their dependencies are wrapped. This // flag is used during the traversal that enforces this invariant, and is used diff --git a/internal/js_parser/js_parser.go b/internal/js_parser/js_parser.go index 6203a2f6758..25b10659926 100644 --- a/internal/js_parser/js_parser.go +++ b/internal/js_parser/js_parser.go @@ -12625,7 +12625,7 @@ func (p *parser) visitExprInOut(expr js_ast.Expr, in exprIn) (js_ast.Expr, exprO // import(foo) // // After: - // Promise.resolve().then(() => require(foo)) + // Promise.resolve().then(() => __toESM(require(foo))) // // This is normally done by the printer since we don't know during the // parsing stage whether this module is external or not. However, it's @@ -12635,7 +12635,7 @@ func (p *parser) visitExprInOut(expr js_ast.Expr, in exprIn) (js_ast.Expr, exprO // correctly, and you need a string literal to get an import record. if p.options.unsupportedJSFeatures.Has(compat.DynamicImport) { var then js_ast.Expr - value := p.callRuntime(arg.Loc, "__toModule", []js_ast.Expr{{Loc: expr.Loc, Data: &js_ast.ECall{ + value := p.callRuntime(arg.Loc, "__toESM", []js_ast.Expr{{Loc: expr.Loc, Data: &js_ast.ECall{ Target: p.valueToSubstituteForRequire(expr.Loc), Args: []js_ast.Expr{arg}, }}}) @@ -13397,9 +13397,6 @@ 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{p.tracker.MsgData(js_lexer.RangeOfIdentifier(p.source, name.AliasLoc), fmt.Sprintf("The name %q was originally exported here:", alias))}) - } else if alias == "__esModule" { - p.log.Add(logger.Error, &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 f48036fc5c6..57ddaab73f6 100644 --- a/internal/js_parser/js_parser_test.go +++ b/internal/js_parser/js_parser_test.go @@ -2546,13 +2546,6 @@ 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/internal/js_printer/js_printer.go b/internal/js_printer/js_printer.go index a94989d5565..03650cfc409 100644 --- a/internal/js_printer/js_printer.go +++ b/internal/js_printer/js_printer.go @@ -437,6 +437,7 @@ type printer struct { options Options extractedLegalComments map[string]bool needsSemicolon bool + moduleType js_ast.ModuleType js []byte stmtStart int exportDefaultStart int @@ -1041,10 +1042,10 @@ func (p *printer) printRequireOrImportExpr( if !record.SourceIndex.IsValid() { // External "require()" if record.Kind != ast.ImportDynamic { - if record.WrapWithToModule { - p.printSymbol(p.options.ToModuleRef) + // Wrap this with a call to "__toESM()" if this is a CommonJS file + if record.WrapWithToESM { + p.printSymbol(p.options.ToESMRef) p.print("(") - defer p.print(")") } // Potentially substitute our own "__require" stub for "require" @@ -1059,6 +1060,16 @@ func (p *printer) printRequireOrImportExpr( p.addSourceMapping(record.Range.Loc) p.printQuotedUTF8(record.Path.Text, true /* allowBacktick */) p.print(")") + + // Finish the call to "__toESM()" + if record.WrapWithToESM { + if p.moduleType == js_ast.ModuleESM { + p.print(",") + p.printSpace() + p.print("1") + } + p.print(")") + } return } @@ -1073,11 +1084,18 @@ func (p *printer) printRequireOrImportExpr( p.printDotThenPrefix() defer p.printDotThenSuffix() - // Wrap this with a call to "__toModule()" if this is a CommonJS file - if record.WrapWithToModule { - p.printSymbol(p.options.ToModuleRef) + // Wrap this with a call to "__toESM()" if this is a CommonJS file + if record.WrapWithToESM { + p.printSymbol(p.options.ToESMRef) p.print("(") - defer p.print(")") + defer func() { + if p.moduleType == js_ast.ModuleESM { + p.print(",") + p.printSpace() + p.print("1") + } + p.print(")") + }() } // Potentially substitute our own "__require" stub for "require" @@ -1145,11 +1163,10 @@ func (p *printer) printRequireOrImportExpr( defer p.print(")") } - // Wrap this with a call to "__toModule()" if this is a CommonJS file - if record.WrapWithToModule { - p.printSymbol(p.options.ToModuleRef) + // Wrap this with a call to "__toESM()" if this is a CommonJS file + if record.WrapWithToESM { + p.printSymbol(p.options.ToESMRef) p.print("(") - defer p.print(")") } // Call the wrapper @@ -1160,7 +1177,26 @@ func (p *printer) printRequireOrImportExpr( if meta.ExportsRef != js_ast.InvalidRef { p.print(",") p.printSpace() + + // Wrap this with a call to "__toCommonJS()" if this is an ESM file + if record.WrapWithToCJS { + p.printSymbol(p.options.ToCommonJSRef) + p.print("(") + } p.printSymbol(meta.ExportsRef) + if record.WrapWithToCJS { + p.print(")") + } + } + + // Finish the call to "__toESM()" + if record.WrapWithToESM { + if p.moduleType == js_ast.ModuleESM { + p.print(",") + p.printSpace() + p.print("1") + } + p.print(")") } } @@ -3101,7 +3137,8 @@ type Options struct { LegalComments config.LegalComments AddSourceMappings bool Indent int - ToModuleRef js_ast.Ref + ToCommonJSRef js_ast.Ref + ToESMRef js_ast.Ref RuntimeRequireRef js_ast.Ref UnsupportedFeatures compat.JSFeature RequireOrImportMetaForSource func(uint32) RequireOrImportMeta @@ -3141,6 +3178,7 @@ func Print(tree js_ast.AST, symbols js_ast.SymbolMap, r renamer.Renamer, options renamer: r, importRecords: tree.ImportRecords, options: options, + moduleType: tree.ModuleType, stmtStart: -1, exportDefaultStart: -1, arrowExprStart: -1, diff --git a/internal/runtime/runtime.go b/internal/runtime/runtime.go index 49a76fcf826..bd6eb01c9d2 100644 --- a/internal/runtime/runtime.go +++ b/internal/runtime/runtime.go @@ -112,10 +112,10 @@ func code(isES6 bool) string { } export var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)) - // Tells importing modules that this can be considered an ES6 module + // Tells importing modules that this can be considered an ES module var __markAsModule = target => __defProp(target, '__esModule', { value: true }) - // Tells importing modules that this can be considered an ES6 module + // Update the "name" property on the function or class for "--keep-names" export var __name = (target, value) => __defProp(target, 'name', { value, configurable: true }) // This fallback "require" function exists so that "typeof require" can @@ -180,13 +180,12 @@ func code(isES6 bool) string { } export var __commonJSMin = (cb, mod) => () => (mod || cb((mod = {exports: {}}).exports, mod), mod.exports) - // Used to implement ES6 exports to CommonJS + // Used to implement ESM exports both for "require()" and "import * as" export var __export = (target, all) => { - __markAsModule(target) for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }) } - export var __reExport = (target, module, desc) => { + export var __reExport = (target, module, copyDefault, desc) => { if (module && typeof module === 'object' || typeof module === 'function') ` @@ -194,14 +193,14 @@ func code(isES6 bool) string { if isES6 { text += ` for (let key of __getOwnPropNames(module)) - if (!__hasOwnProp.call(target, key) && key !== 'default') + if (!__hasOwnProp.call(target, key) && (copyDefault || key !== 'default')) __defProp(target, key, { get: () => module[key], enumerable: !(desc = __getOwnPropDesc(module, key)) || desc.enumerable }) ` } else { text += ` for (var keys = __getOwnPropNames(module), i = 0, n = keys.length, key; i < n; i++) { key = keys[i] - if (!__hasOwnProp.call(target, key) && key !== 'default') + if (!__hasOwnProp.call(target, key) && (copyDefault || key !== 'default')) __defProp(target, key, { get: (k => module[k]).bind(null, key), enumerable: !(desc = __getOwnPropDesc(module, key)) || desc.enumerable }) } ` @@ -211,24 +210,34 @@ func code(isES6 bool) string { return target } - // Converts the module from CommonJS to ES6 if necessary - export var __toModule = module => { + // Converts the module from CommonJS to ESM + export var __toESM = (module, isNodeMode) => { return __reExport(__markAsModule( __defProp( module != null ? __create(__getProtoOf(module)) : {}, 'default', - // If this is an ESM file that has been converted to a CommonJS file - // using a Babel-compatible transform (i.e. "__esModule" has been set) - // and there is already a "default" property, then forward "default" - // to that property. Otherwise set "default" to "module.exports" for - // node compatibility. - module && module.__esModule && 'default' in module + // If the importer is not in node compatibility mode and this is an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has been set), then forward + // "default" to the export named "default". Otherwise set "default" to + // "module.exports" for node compatibility. + !isNodeMode && module && module.__esModule ? { get: () => module.default, enumerable: true } : { value: module, enumerable: true }) ), module) } + // Converts the module from ESM to CommonJS + export var __toCommonJS = /* @__PURE__ */ (cache => { + return (module, temp) => { + return (cache && cache.get(module)) || ( + temp = __reExport(__markAsModule({}), module, /* copyDefault */ 1), + cache && cache.set(module, temp), + temp) + } + })(typeof WeakMap !== 'undefined' ? new WeakMap : 0) + // For TypeScript decorators // - kind === undefined: class // - kind === 1: method, parameter diff --git a/scripts/end-to-end-tests.js b/scripts/end-to-end-tests.js index b3bd5ac1939..83ab60c92ad 100644 --- a/scripts/end-to-end-tests.js +++ b/scripts/end-to-end-tests.js @@ -1348,11 +1348,27 @@ 'foo.js': `exports.__esModule = true; exports.default = 123`, }), test(['in.js', '--outfile=node.js', '--format=cjs'], { - 'in.js': `import def from './foo'; if (!def || def.foo !== 123) throw 'fail'`, + 'in.js': `import def from './foo'; if (def !== void 0) throw 'fail'`, 'foo.js': `exports.__esModule = true; exports.foo = 123`, }), + test(['in.js', '--outfile=node.js', '--format=cjs'], { + 'in.js': `import * as ns from './foo'; if (ns.default !== void 0 || ns.foo !== 123) throw 'fail'`, + 'foo.js': `exports.__esModule = true; exports.foo = 123`, + }), + test(['in.js', '--outfile=node.js', '--format=cjs'], { + 'in.js': `import def from './foo'; if (!def || def.foo !== 123) throw 'fail'`, + 'foo.js': `exports.__esModule = false; exports.foo = 123`, + }), test(['in.js', '--outfile=node.js', '--format=cjs'], { 'in.js': `import * as ns from './foo'; if (!ns.default || ns.default.foo !== 123) throw 'fail'`, + 'foo.js': `exports.__esModule = false; exports.foo = 123`, + }), + test(['in.mjs', '--outfile=node.js', '--format=cjs'], { + 'in.mjs': `import def from './foo'; if (!def || def.foo !== 123) throw 'fail'`, + 'foo.js': `exports.__esModule = true; exports.foo = 123`, + }), + test(['in.mjs', '--outfile=node.js', '--format=cjs'], { + 'in.mjs': `import * as ns from './foo'; if (!ns.default || ns.default.foo !== 123) throw 'fail'`, 'foo.js': `exports.__esModule = true; exports.foo = 123`, }), ) diff --git a/scripts/esbuild.js b/scripts/esbuild.js index df29f29945d..ad2313f7534 100644 --- a/scripts/esbuild.js +++ b/scripts/esbuild.js @@ -59,18 +59,18 @@ const buildNeutralLib = (esbuildPath) => { fs.writeFileSync(path.join(libDir, 'main.d.ts'), types_ts) // Get supported platforms - const platforms = {} - new Function('exports', 'require', childProcess.execFileSync(esbuildPath, [ + const platforms = { exports: {} } + new Function('module', 'exports', 'require', childProcess.execFileSync(esbuildPath, [ path.join(repoDir, 'lib', 'npm', 'node-platform.ts'), '--bundle', '--target=' + nodeTarget, '--external:esbuild', '--platform=node', '--log-level=warning', - ], { cwd: repoDir }))(platforms, require) + ], { cwd: repoDir }))(platforms, platforms.exports, require) const optionalDependencies = Object.fromEntries(Object.values({ - ...platforms.knownWindowsPackages, - ...platforms.knownUnixlikePackages, + ...platforms.exports.knownWindowsPackages, + ...platforms.exports.knownUnixlikePackages, }).sort().map(x => [x, version])) // Update "npm/esbuild/package.json" @@ -180,8 +180,8 @@ exports.buildWasmLib = async (esbuildPath) => { } // Generate "npm/esbuild-wasm/lib/browser.*" - const umdPrefix = `(exports=>{` - const umdSuffix = `})(typeof exports==="object"?exports:(typeof self!=="undefined"?self:this).esbuild={});` + const umdPrefix = `(module=>{` + const umdSuffix = `})(typeof module==="object"?module:{set exports(x){(typeof self!=="undefined"?self:this).esbuild=x}});` const browserCJS = childProcess.execFileSync(esbuildPath, [ path.join(repoDir, 'lib', 'npm', 'browser.ts'), '--bundle', @@ -323,7 +323,7 @@ exports.installForTests = () => { // Evaluate the code const ESBUILD_PACKAGE_PATH = path.join(installDir, 'node_modules', 'esbuild') const mod = require(ESBUILD_PACKAGE_PATH) - mod.ESBUILD_PACKAGE_PATH = ESBUILD_PACKAGE_PATH + Object.defineProperty(mod, 'ESBUILD_PACKAGE_PATH', { value: ESBUILD_PACKAGE_PATH }) return mod } diff --git a/scripts/js-api-tests.js b/scripts/js-api-tests.js index 455bd63c6f2..5e2c88fbb70 100644 --- a/scripts/js-api-tests.js +++ b/scripts/js-api-tests.js @@ -2430,10 +2430,10 @@ require("/assets/file.png"); assert.strictEqual(await tryTargetESM('node14.13.1'), `// \nimport "node:fs";\nimport("node:fs");\n`) assert.strictEqual(await tryTargetESM('node14.13.0'), `// \nimport "fs";\nimport("fs");\n`) - assert.strictEqual(await tryTargetESM('node13'), `// \nimport "fs";\nPromise.resolve().then(() => __toModule(__require("fs")));\n`) + assert.strictEqual(await tryTargetESM('node13'), `// \nimport "fs";\nPromise.resolve().then(() => __toESM(__require("fs")));\n`) assert.strictEqual(await tryTargetESM('node12.99'), `// \nimport "node:fs";\nimport("node:fs");\n`) assert.strictEqual(await tryTargetESM('node12.20'), `// \nimport "node:fs";\nimport("node:fs");\n`) - assert.strictEqual(await tryTargetESM('node12.19'), `// \nimport "fs";\nPromise.resolve().then(() => __toModule(__require("fs")));\n`) + assert.strictEqual(await tryTargetESM('node12.19'), `// \nimport "fs";\nPromise.resolve().then(() => __toESM(__require("fs")));\n`) }, async nodeColonPrefixRequire({ esbuild }) { @@ -2472,12 +2472,12 @@ require("/assets/file.png"); return code.slice(code.indexOf(`// \n`)) } - assert.strictEqual(await tryTargetESM('node16'), `// \nvar import_node_fs = __toModule(require("node:fs"));\nimport("node:fs");\n`) - assert.strictEqual(await tryTargetESM('node15.99'), `// \nvar import_node_fs = __toModule(require("fs"));\nimport("fs");\n`) - assert.strictEqual(await tryTargetESM('node15'), `// \nvar import_node_fs = __toModule(require("fs"));\nimport("fs");\n`) - assert.strictEqual(await tryTargetESM('node14.99'), `// \nvar import_node_fs = __toModule(require("node:fs"));\nimport("node:fs");\n`) - assert.strictEqual(await tryTargetESM('node14.18'), `// \nvar import_node_fs = __toModule(require("node:fs"));\nimport("node:fs");\n`) - assert.strictEqual(await tryTargetESM('node14.17'), `// \nvar import_node_fs = __toModule(require("fs"));\nimport("fs");\n`) + assert.strictEqual(await tryTargetESM('node16'), `// \nvar import_node_fs = __toESM(require("node:fs"));\nimport("node:fs");\n`) + assert.strictEqual(await tryTargetESM('node15.99'), `// \nvar import_node_fs = __toESM(require("fs"));\nimport("fs");\n`) + assert.strictEqual(await tryTargetESM('node15'), `// \nvar import_node_fs = __toESM(require("fs"));\nimport("fs");\n`) + assert.strictEqual(await tryTargetESM('node14.99'), `// \nvar import_node_fs = __toESM(require("node:fs"));\nimport("node:fs");\n`) + assert.strictEqual(await tryTargetESM('node14.18'), `// \nvar import_node_fs = __toESM(require("node:fs"));\nimport("node:fs");\n`) + assert.strictEqual(await tryTargetESM('node14.17'), `// \nvar import_node_fs = __toESM(require("fs"));\nimport("fs");\n`) }, } @@ -3569,23 +3569,23 @@ let transformTests = { async es6_export_to_cjs({ esbuild }) { const { code } = await esbuild.transform(`export {exists} from "fs"`, { format: 'cjs' }) - const exports = {} - new Function('require', 'exports', code)(require, exports) - if (exports.exists !== fs.exists) throw 'fail' + const module = { exports: {} } + new Function('module', 'exports', 'require', code)(module, module.exports, require) + if (module.exports.exists !== fs.exists) throw 'fail' }, async es6_export_star_to_cjs({ esbuild }) { const { code } = await esbuild.transform(`export * from "fs"`, { format: 'cjs' }) - const exports = {} - new Function('require', 'exports', code)(require, exports) - if (exports.exists !== fs.exists) throw 'fail' + const module = { exports: {} } + new Function('module', 'exports', 'require', code)(module, module.exports, require) + if (module.exports.exists !== fs.exists) throw 'fail' }, async es6_export_star_as_to_cjs({ esbuild }) { const { code } = await esbuild.transform(`export * as fs from "fs"`, { format: 'cjs' }) - const exports = {} - new Function('require', 'exports', code)(require, exports) - if (exports.fs.exists !== fs.exists) throw 'fail' + const module = { exports: {} } + new Function('module', 'exports', 'require', code)(module, module.exports, require) + if (module.exports.fs.exists !== fs.exists) throw 'fail' }, async es6_import_to_esm({ esbuild }) { @@ -4055,25 +4055,25 @@ let transformTests = { async dynamicImportStringES6({ esbuild }) { const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve')) const { code } = await esbuild.transform(`import('foo')`, { target: 'chrome62' }) - assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toModule(require("foo")));\n`) + assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toESM(require("foo")));\n`) }, async dynamicImportStringES5({ esbuild }) { const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve')) const { code } = await esbuild.transform(`import('foo')`, { target: 'chrome48' }) - assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(function() {\n return __toModule(require("foo"));\n});\n`) + assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(function() {\n return __toESM(require("foo"));\n});\n`) }, async dynamicImportStringES5Minify({ esbuild }) { const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve')) const { code } = await esbuild.transform(`import('foo')`, { target: 'chrome48', minifyWhitespace: true }) - assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(function(){return __toModule(require("foo"))});\n`) + assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(function(){return __toESM(require("foo"))});\n`) }, async dynamicImportStringNode12_19({ esbuild }) { const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve')) const { code } = await esbuild.transform(`import('foo')`, { target: 'node12.19' }) - assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toModule(require("foo")));\n`) + assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toESM(require("foo")));\n`) }, async dynamicImportStringNode12_20({ esbuild }) { @@ -4084,13 +4084,13 @@ let transformTests = { async dynamicImportStringNode13({ esbuild }) { const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve')) const { code } = await esbuild.transform(`import('foo')`, { target: 'node13' }) - assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toModule(require("foo")));\n`) + assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toESM(require("foo")));\n`) }, async dynamicImportStringNode13_1({ esbuild }) { const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve')) const { code } = await esbuild.transform(`import('foo')`, { target: 'node13.1' }) - assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toModule(require("foo")));\n`) + assert.strictEqual(fromPromiseResolve(code), `Promise.resolve().then(() => __toESM(require("foo")));\n`) }, async dynamicImportStringNode13_2({ esbuild }) { @@ -4106,19 +4106,19 @@ let transformTests = { async dynamicImportExpressionES6({ esbuild }) { const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve')) const { code: code2 } = await esbuild.transform(`import(foo)`, { target: 'chrome62' }) - assert.strictEqual(fromPromiseResolve(code2), `Promise.resolve().then(() => __toModule(require(foo)));\n`) + assert.strictEqual(fromPromiseResolve(code2), `Promise.resolve().then(() => __toESM(require(foo)));\n`) }, async dynamicImportExpressionES5({ esbuild }) { const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve')) const { code: code3 } = await esbuild.transform(`import(foo)`, { target: 'chrome48' }) - assert.strictEqual(fromPromiseResolve(code3), `Promise.resolve().then(function() {\n return __toModule(require(foo));\n});\n`) + assert.strictEqual(fromPromiseResolve(code3), `Promise.resolve().then(function() {\n return __toESM(require(foo));\n});\n`) }, async dynamicImportExpressionES5Minify({ esbuild }) { const fromPromiseResolve = text => text.slice(text.indexOf('Promise.resolve')) const { code: code4 } = await esbuild.transform(`import(foo)`, { target: 'chrome48', minifyWhitespace: true }) - assert.strictEqual(fromPromiseResolve(code4), `Promise.resolve().then(function(){return __toModule(require(foo))});\n`) + assert.strictEqual(fromPromiseResolve(code4), `Promise.resolve().then(function(){return __toESM(require(foo))});\n`) }, async caseInsensitiveTarget({ esbuild }) { diff --git a/scripts/plugin-tests.js b/scripts/plugin-tests.js index 0fd38aa19f0..1a956bb75ac 100644 --- a/scripts/plugin-tests.js +++ b/scripts/plugin-tests.js @@ -2064,9 +2064,7 @@ let pluginTests = { }, }], }) - if (esbuildFromBuild !== esbuild) { - throw new Error('Unexpected value for the "esbuild" property') - } + assert.deepStrictEqual({ ...esbuildFromBuild }, { ...esbuild }) }, async onResolveInvalidPathSuffix({ testDir, esbuild }) {