diff options
-rw-r--r-- | src/options.zig | 11 | ||||
-rw-r--r-- | src/resolver/resolver.zig | 12 | ||||
-rw-r--r-- | test/bundler/esbuild/packagejson.test.ts | 76 |
3 files changed, 96 insertions, 3 deletions
diff --git a/src/options.zig b/src/options.zig index d4df6d4f5..38fac946c 100644 --- a/src/options.zig +++ b/src/options.zig @@ -1417,6 +1417,7 @@ pub const BundleOptions = struct { public_path: []const u8 = "", extension_order: []const string = &Defaults.ExtensionOrder, esm_extension_order: []const string = &Defaults.ModuleExtensionOrder, + main_field_extension_order: []const string = &Defaults.MainFieldExtensionOrder, out_extensions: bun.StringHashMap(string), import_path_format: ImportPathFormat = ImportPathFormat.relative, framework: ?Framework = null, @@ -1556,6 +1557,16 @@ pub const BundleOptions = struct { ".json", }; + pub const MainFieldExtensionOrder = [_]string{ + ".js", + ".cjs", + ".cts", + ".tsx", + ".ts", + ".jsx", + ".json", + }; + pub const ModuleExtensionOrder = [_]string{ ".tsx", ".jsx", diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig index 409df85af..ee65a23cb 100644 --- a/src/resolver/resolver.zig +++ b/src/resolver/resolver.zig @@ -3378,7 +3378,13 @@ pub const Resolver = struct { continue; }; - var _result = r.loadFromMainField(path, dir_info, field_rel_path, key, extension_order) orelse continue; + var _result = r.loadFromMainField( + path, + dir_info, + field_rel_path, + key, + if (strings.eqlComptime(key, "main")) r.opts.main_field_extension_order else extension_order, + ) orelse continue; // If the user did not manually configure a "main" field order, then // use a special per-module automatic algorithm to decide whether to @@ -3389,13 +3395,13 @@ pub const Resolver = struct { if (main_field_values.get("main")) |main_rel_path| { if (main_rel_path.len > 0) { - absolute_result = r.loadFromMainField(path, dir_info, main_rel_path, "main", extension_order); + absolute_result = r.loadFromMainField(path, dir_info, main_rel_path, "main", r.opts.main_field_extension_order); } } else { // Some packages have a "module" field without a "main" field but // still have an implicit "index.js" file. In that case, treat that // as the value for "main". - absolute_result = r.loadAsIndexWithBrowserRemapping(dir_info, path, extension_order); + absolute_result = r.loadAsIndexWithBrowserRemapping(dir_info, path, r.opts.main_field_extension_order); } if (absolute_result) |auto_main_result| { diff --git a/test/bundler/esbuild/packagejson.test.ts b/test/bundler/esbuild/packagejson.test.ts index e6ca66ac6..5d459b968 100644 --- a/test/bundler/esbuild/packagejson.test.ts +++ b/test/bundler/esbuild/packagejson.test.ts @@ -915,6 +915,82 @@ describe("bundler", () => { stdout: "browser main\nbrowser main", }, }); + itBundled("packagejson/DualPackageHazardMainFieldWithoutExtension", { + files: { + "/Users/user/project/src/entry.js": /* js */ ` + const { foo } = require("bar"); + const { foo: foo2 } = await import("bar"); + console.log(foo === foo2); + `, + "/Users/user/project/node_modules/bar/package.json": /* json */ ` + { + "name": "bar", + "version": "2.0.0", + "main": "index" + } + `, + "/Users/user/project/node_modules/bar/index.js": /* js */ ` + module.exports.foo = function() { return "cjs"; }; + `, + "/Users/user/project/node_modules/bar/index.mjs": /* js */ ` + export const foo = function(){ return "esm"; }; + `, + }, + run: { + stdout: "true", + }, + }); + itBundled("packagejson/DualPackageHazardModuleFieldAndMainFieldWithoutExtension", { + files: { + "/Users/user/project/src/entry.js": /* js */ ` + const { foo } = require("bar"); + const { foo: foo2 } = await import("bar"); + console.log(foo === foo2); + `, + "/Users/user/project/node_modules/bar/package.json": /* json */ ` + { + "name": "bar", + "version": "2.0.0", + "main": "index", + "module": "index.mjs" + } + `, + "/Users/user/project/node_modules/bar/index.js": /* js */ ` + module.exports.foo = function() { return "cjs"; }; + `, + "/Users/user/project/node_modules/bar/index.mjs": /* js */ ` + export const foo = function(){ return "esm"; }; + `, + }, + run: { + stdout: "true", + }, + }); + itBundled("packagejson/DualPackageHazardModuleFieldNoMainField", { + files: { + "/Users/user/project/src/entry.js": /* js */ ` + const { foo } = require("bar"); + const { foo: foo2 } = await import("bar"); + console.log(foo === foo2); + `, + "/Users/user/project/node_modules/bar/package.json": /* json */ ` + { + "name": "bar", + "version": "2.0.0", + "module": "index.mjs" + } + `, + "/Users/user/project/node_modules/bar/index.js": /* js */ ` + module.exports.foo = function() { return "cjs"; }; + `, + "/Users/user/project/node_modules/bar/index.mjs": /* js */ ` + export const foo = function(){ return "esm"; }; + `, + }, + run: { + stdout: "true", + }, + }); itBundled("packagejson/MainFieldsA", { files: { "/Users/user/project/src/entry.js": /* js */ ` |