diff --git a/CHANGELOG.md b/CHANGELOG.md index 23cd7c7b235..d35f821ad36 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ This release fixes a problem where bundling a TypeScript file containing a glob import could emit a call to a helper function that doesn't exist. The problem happened because esbuild's TypeScript transformation removes unused imports (which is required for correctness, as they may be type-only imports) and esbuild's glob import transformation wasn't correctly marking the imported helper function as used. This wasn't caught earlier because most of esbuild's glob import tests were written in JavaScript, not in TypeScript. +* Fix `require()` glob imports with bundling disabled ([#3546](https://github.com/evanw/esbuild/issues/3546)) + + Previously `require()` calls containing glob imports were incorrectly transformed when bundling was disabled. All glob imports should only be transformed when bundling is enabled. This bug has been fixed. + * Fix a panic when transforming optional chaining with `define` ([#3551](https://github.com/evanw/esbuild/issues/3551), [#3554](https://github.com/evanw/esbuild/pull/3554)) This release fixes a case where esbuild could crash with a panic, which was triggered by using `define` to replace an expression containing an optional chain. Here is an example: diff --git a/internal/bundler_tests/bundler_glob_test.go b/internal/bundler_tests/bundler_glob_test.go index dea1e410e55..093619d29f4 100644 --- a/internal/bundler_tests/bundler_glob_test.go +++ b/internal/bundler_tests/bundler_glob_test.go @@ -10,6 +10,32 @@ var glob_suite = suite{ name: "glob", } +func TestGlobBasicNoBundle(t *testing.T) { + glob_suite.expectBundled(t, bundled{ + files: map[string]string{ + "/entry.js": ` + const ab = Math.random() < 0.5 ? 'a.js' : 'b.js' + console.log({ + concat: { + require: require('./src/' + ab), + import: import('./src/' + ab), + }, + template: { + require: require(` + "`./src/${ab}`" + `), + import: import(` + "`./src/${ab}`" + `), + }, + }) + `, + }, + entryPaths: []string{"/entry.js"}, + options: config.Options{ + Mode: config.ModeConvertFormat, + OutputFormat: config.FormatCommonJS, + AbsOutputFile: "/out.js", + }, + }) +} + func TestGlobBasicNoSplitting(t *testing.T) { glob_suite.expectBundled(t, bundled{ files: map[string]string{ diff --git a/internal/bundler_tests/snapshots/snapshots_glob.txt b/internal/bundler_tests/snapshots/snapshots_glob.txt index d376aa87a55..5c008b8090d 100644 --- a/internal/bundler_tests/snapshots/snapshots_glob.txt +++ b/internal/bundler_tests/snapshots/snapshots_glob.txt @@ -1,3 +1,18 @@ +TestGlobBasicNoBundle +---------- /out.js ---------- +const ab = Math.random() < 0.5 ? "a.js" : "b.js"; +console.log({ + concat: { + require: require("./src/" + ab), + import: import("./src/" + ab) + }, + template: { + require: require(`./src/${ab}`), + import: import(`./src/${ab}`) + } +}); + +================================================================================ TestGlobBasicNoSplitting ---------- /out.js ---------- // src/a.js diff --git a/internal/js_parser/js_parser.go b/internal/js_parser/js_parser.go index 8a56f66df57..d6fe809bd3c 100644 --- a/internal/js_parser/js_parser.go +++ b/internal/js_parser/js_parser.go @@ -14790,8 +14790,10 @@ func (p *parser) visitExprInOut(expr js_ast.Expr, in exprIn) (js_ast.Expr, exprO } // Handle glob patterns - if value := p.handleGlobPattern(arg, ast.ImportRequire, "globRequire", nil); value.Data != nil { - return value + if p.options.mode == config.ModeBundle { + if value := p.handleGlobPattern(arg, ast.ImportRequire, "globRequire", nil); value.Data != nil { + return value + } } // Use a debug log so people can see this if they want to