From 88a75c84a95976d29e4ebfcf9d5dcfd7f7876f3a Mon Sep 17 00:00:00 2001 From: magic-akari Date: Wed, 13 Sep 2023 16:36:57 +0800 Subject: [PATCH] fix: shadow global `define` in `__commonJS` --- internal/bundler_tests/bundler_loader_test.go | 26 +++++++++++++++++++ .../snapshots/snapshots_loader.txt | 21 +++++++++++++++ internal/graph/graph.go | 3 +++ internal/js_ast/js_ast.go | 2 ++ internal/js_parser/js_parser.go | 7 +++++ internal/linker/linker.go | 5 +++- 6 files changed, 63 insertions(+), 1 deletion(-) diff --git a/internal/bundler_tests/bundler_loader_test.go b/internal/bundler_tests/bundler_loader_test.go index bab7e207693..511ca0483d3 100644 --- a/internal/bundler_tests/bundler_loader_test.go +++ b/internal/bundler_tests/bundler_loader_test.go @@ -1557,3 +1557,29 @@ func TestLoaderBundleWithImportAttributes(t *testing.T) { `, }) } + +func TestLoaderUmdDefineShouldBeShadowed(t *testing.T) { + loader_suite.expectBundled(t, bundled{ + files: map[string]string{ + "/entry.js": ` + const LZString = "test"; + if (typeof define === 'function' && define.amd) { + define(function () { return LZString; }); + } else if( typeof module !== 'undefined' && module != null ) { + module.exports = LZString + } else if( typeof angular !== 'undefined' && angular != null ) { + angular.module('LZString', []) + .factory('LZString', function () { + return LZString; + }); + } + `, + }, + entryPaths: []string{"/entry.js"}, + options: config.Options{ + Mode: config.ModeConvertFormat, + OutputFormat: config.FormatESModule, + AbsOutputFile: "/out.js", + }, + }) +} diff --git a/internal/bundler_tests/snapshots/snapshots_loader.txt b/internal/bundler_tests/snapshots/snapshots_loader.txt index a8437380822..f586f963979 100644 --- a/internal/bundler_tests/snapshots/snapshots_loader.txt +++ b/internal/bundler_tests/snapshots/snapshots_loader.txt @@ -920,6 +920,27 @@ var y_default = "y"; var x_txt = require_x(); console.log(x_txt, y_default); +================================================================================ +TestLoaderUmdDefineShouldBeShadowed +---------- /out.js ---------- +var require_entry = __commonJS({ + "entry.js"(exports, module, define) { + const LZString = "test"; + if (typeof define === "function" && define.amd) { + define(function() { + return LZString; + }); + } else if (typeof module !== "undefined" && module != null) { + module.exports = LZString; + } else if (typeof angular !== "undefined" && angular != null) { + angular.module("LZString", []).factory("LZString", function() { + return LZString; + }); + } + } +}); +export default require_entry(); + ================================================================================ TestRequireCustomExtensionBase64 ---------- /out.js ---------- diff --git a/internal/graph/graph.go b/internal/graph/graph.go index a030797d81c..cf9ab251b1b 100644 --- a/internal/graph/graph.go +++ b/internal/graph/graph.go @@ -396,6 +396,9 @@ func (g *LinkerGraph) GenerateSymbolImportAndUse( if ref == repr.AST.ModuleRef { repr.AST.UsesModuleRef = true } + if ref == repr.AST.DefineRef { + repr.AST.UsesDefineRef = true + } // Track that this specific symbol was imported if sourceIndexToImportFrom != sourceIndex { diff --git a/internal/js_ast/js_ast.go b/internal/js_ast/js_ast.go index 1b9adac56fc..f343566ae34 100644 --- a/internal/js_ast/js_ast.go +++ b/internal/js_ast/js_ast.go @@ -1533,6 +1533,7 @@ type AST struct { ExportsRef ast.Ref ModuleRef ast.Ref + DefineRef ast.Ref WrapperRef ast.Ref ApproximateLineCount int32 @@ -1545,6 +1546,7 @@ type AST struct { // here because only the parser checks those. UsesExportsRef bool UsesModuleRef bool + UsesDefineRef bool ExportsKind ExportsKind } diff --git a/internal/js_parser/js_parser.go b/internal/js_parser/js_parser.go index f006d5f18a4..2b812975f8f 100644 --- a/internal/js_parser/js_parser.go +++ b/internal/js_parser/js_parser.go @@ -220,6 +220,7 @@ type parser struct { exportsRef ast.Ref requireRef ast.Ref moduleRef ast.Ref + defineRef ast.Ref importMetaRef ast.Ref promiseRef ast.Ref regExpRef ast.Ref @@ -14368,6 +14369,7 @@ func (p *parser) visitExprInOut(expr js_ast.Expr, in exprIn) (js_ast.Expr, exprO if p.options.mode == config.ModeBundle && !p.isFileConsideredToHaveESMExports { p.recordUsage(p.moduleRef) p.recordUsage(p.exportsRef) + p.recordUsage(p.defineRef) } // Mark this scope and all parent scopes as containing a direct eval. @@ -17103,10 +17105,12 @@ func (p *parser) prepareForVisitPass() { // CommonJS-style exports p.exportsRef = p.declareCommonJSSymbol(ast.SymbolHoisted, "exports") p.moduleRef = p.declareCommonJSSymbol(ast.SymbolHoisted, "module") + p.defineRef = p.declareCommonJSSymbol(ast.SymbolHoisted, "define") } else { // ESM-style exports p.exportsRef = p.newSymbol(ast.SymbolHoisted, "exports") p.moduleRef = p.newSymbol(ast.SymbolHoisted, "module") + p.defineRef = p.newSymbol(ast.SymbolHoisted, "define") } // Handle "@jsx" and "@jsxFrag" pragmas now that lexing is done @@ -17522,6 +17526,7 @@ func (p *parser) toAST(before, parts, after []js_ast.Part, hashbang string, dire exportsKind := js_ast.ExportsNone usesExportsRef := p.symbols[p.exportsRef.InnerIndex].UseCountEstimate > 0 usesModuleRef := p.symbols[p.moduleRef.InnerIndex].UseCountEstimate > 0 + usesDefineRef := p.symbols[p.defineRef.InnerIndex].UseCountEstimate > 0 if p.esmExportKeyword.Len > 0 || p.esmImportMeta.Len > 0 || p.topLevelAwaitKeyword.Len > 0 { exportsKind = js_ast.ExportsESM @@ -17558,6 +17563,7 @@ func (p *parser) toAST(before, parts, after []js_ast.Part, hashbang string, dire Symbols: p.symbols, ExportsRef: p.exportsRef, ModuleRef: p.moduleRef, + DefineRef: p.defineRef, WrapperRef: wrapperRef, Hashbang: hashbang, Directives: directives, @@ -17578,6 +17584,7 @@ func (p *parser) toAST(before, parts, after []js_ast.Part, hashbang string, dire // CommonJS features UsesExportsRef: usesExportsRef, UsesModuleRef: usesModuleRef, + UsesDefineRef: usesDefineRef, ExportsKind: exportsKind, // ES6 features diff --git a/internal/linker/linker.go b/internal/linker/linker.go index 2385735e835..d8b595090e9 100644 --- a/internal/linker/linker.go +++ b/internal/linker/linker.go @@ -4750,8 +4750,11 @@ func (c *linkerContext) generateCodeForFileInChunkJS( args := []js_ast.Arg{} if repr.AST.UsesExportsRef || repr.AST.UsesModuleRef { args = append(args, js_ast.Arg{Binding: js_ast.Binding{Data: &js_ast.BIdentifier{Ref: repr.AST.ExportsRef}}}) - if repr.AST.UsesModuleRef { + if repr.AST.UsesModuleRef || repr.AST.UsesDefineRef { args = append(args, js_ast.Arg{Binding: js_ast.Binding{Data: &js_ast.BIdentifier{Ref: repr.AST.ModuleRef}}}) + if repr.AST.UsesDefineRef { + args = append(args, js_ast.Arg{Binding: js_ast.Binding{Data: &js_ast.BIdentifier{Ref: repr.AST.DefineRef}}}) + } } }