aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Dylan Conway <35280289+dylan-conway@users.noreply.github.com> 2023-06-28 19:28:53 -0700
committerGravatar GitHub <noreply@github.com> 2023-06-28 19:28:53 -0700
commit3258bed1c03a7808b9f2e4970012668e984ed390 (patch)
treef4628426f2d7026a0ba8e48ce19ebe0836c2cc22
parent32d9abcc03bf2c2542574ff9ae1717d933f5d85f (diff)
downloadbun-3258bed1c03a7808b9f2e4970012668e984ed390.tar.gz
bun-3258bed1c03a7808b9f2e4970012668e984ed390.tar.zst
bun-3258bed1c03a7808b9f2e4970012668e984ed390.zip
use main field over module for runtime (#3448)
* use main field over module for runtime * move flag to `Resolver` * set `prefer_module_field` in `initWithModuleGraph`
-rw-r--r--src/bun.js/javascript.zig2
-rw-r--r--src/resolver/resolver.zig9
-rw-r--r--test/bundler/esbuild/default.test.ts200
3 files changed, 210 insertions, 1 deletions
diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig
index 5c58eff60..cf6a65841 100644
--- a/src/bun.js/javascript.zig
+++ b/src/bun.js/javascript.zig
@@ -801,6 +801,7 @@ pub const VirtualMachine = struct {
vm.bundler.macro_context = null;
vm.bundler.resolver.store_fd = false;
+ vm.bundler.resolver.prefer_module_field = false;
vm.bundler.resolver.onWakePackageManager = .{
.context = &vm.modules,
@@ -898,6 +899,7 @@ pub const VirtualMachine = struct {
vm.bundler.macro_context = null;
vm.bundler.resolver.store_fd = store_fd;
+ vm.bundler.resolver.prefer_module_field = false;
vm.bundler.resolver.onWakePackageManager = .{
.context = &vm.modules,
diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig
index d9f4dc887..e1e83ba4f 100644
--- a/src/resolver/resolver.zig
+++ b/src/resolver/resolver.zig
@@ -533,6 +533,10 @@ pub const Resolver = struct {
// all parent directories
dir_cache: *DirInfo.HashMap,
+ /// This is set to false for the runtime. The runtime should choose "main"
+ /// over "module" in package.json
+ prefer_module_field: bool = true,
+
pub fn getPackageManager(this: *Resolver) *PackageManager {
return this.package_manager orelse brk: {
bun.HTTPThead.init() catch unreachable;
@@ -3408,7 +3412,10 @@ pub const Resolver = struct {
// with this same path. The goal of this code is to avoid having
// both the "module" file and the "main" file in the bundle at the
// same time.
- if (kind != ast.ImportKind.require) {
+ //
+ // Additionally, if this is for the runtime, use the "main" field.
+ // If it doesn't exist, the "module" field will be used.
+ if (r.prefer_module_field and kind != ast.ImportKind.require) {
if (r.debug_logs) |*debug| {
debug.addNoteFmt("Resolved to \"{s}\" using the \"module\" field in \"{s}\"", .{ auto_main_result.path_pair.primary.text, pkg_json.source.key_path.text });
diff --git a/test/bundler/esbuild/default.test.ts b/test/bundler/esbuild/default.test.ts
index 4c4cf87be..20856ecdf 100644
--- a/test/bundler/esbuild/default.test.ts
+++ b/test/bundler/esbuild/default.test.ts
@@ -6565,4 +6565,204 @@ describe("bundler", () => {
api.expectFile("/out.js").not.toContain("data = 123");
},
});
+ itBundled("default/BundlerUsesModuleFieldForEsm", {
+ files: {
+ "/entry.js": `
+ import { foo } from 'foo';
+ console.log(foo);
+ `,
+ "/node_modules/foo/package.json": `
+ {
+ "name": "foo",
+ "version": "2.0.0",
+ "module": "index.esm.js",
+ "main": "index.cjs.js"
+ }
+ `,
+ "/node_modules/foo/index.cjs.js": `
+ module.exports.foo = "hello index.cjs.js";
+ `,
+ "/node_modules/foo/index.esm.js": `
+ export const foo = "hello index.esm.js";
+ `,
+ },
+ run: {
+ stdout: "hello index.esm.js",
+ },
+ });
+ itBundled("default/BundlerUsesMainFieldForCjs", {
+ files: {
+ "/entry.js": `
+ const { foo } = require('foo');
+ console.log(foo);
+ `,
+ "/node_modules/foo/package.json": `
+ {
+ "name": "foo",
+ "version": "2.0.0",
+ "module": "index.esm.js",
+ "main": "index.cjs.js"
+ }
+ `,
+ "/node_modules/foo/index.cjs.js": `
+ module.exports.foo = "hello index.cjs.js";
+ `,
+ "/node_modules/foo/index.esm.js": `
+ export const foo = "hello index.esm.js";
+ `,
+ },
+ run: {
+ stdout: "hello index.cjs.js",
+ },
+ });
+ itBundled("default/RuntimeUsesMainFieldForCjs", {
+ files: {
+ "/entry.js": `
+ const { foo } = require('foo');
+ console.log(foo);
+ `,
+ "/node_modules/foo/package.json": `
+ {
+ "name": "foo",
+ "version": "2.0.0",
+ "module": "index.esm.js",
+ "main": "index.cjs.js"
+ }
+ `,
+ "/node_modules/foo/index.cjs.js": `
+ module.exports.foo = "hello index.cjs.js";
+ `,
+ "/node_modules/foo/index.esm.js": `
+ export const foo = "hello index.esm.js";
+ `,
+ },
+ bundling: false,
+ run: {
+ stdout: "hello index.cjs.js",
+ },
+ });
+ itBundled("default/RuntimeUsesMainFieldForEsm", {
+ files: {
+ "/entry.js": `
+ import { foo } from 'foo';
+ console.log(foo);
+ `,
+ "/node_modules/foo/package.json": `
+ {
+ "name": "foo",
+ "version": "2.0.0",
+ "module": "index.esm.js",
+ "main": "index.cjs.js"
+ }
+ `,
+ "/node_modules/foo/index.cjs.js": `
+ module.exports.foo = "hello index.cjs.js";
+ `,
+ "/node_modules/foo/index.esm.js": `
+ export const foo = "hello index.esm.js";
+ `,
+ },
+ bundling: false,
+ run: {
+ stdout: "hello index.cjs.js",
+ },
+ });
+ itBundled("default/BundlerUsesModuleFieldIfMainDoesNotExistCjs", {
+ files: {
+ "/entry.js": `
+ const { foo } = require('foo');
+ console.log(foo);
+ `,
+ "/node_modules/foo/package.json": `
+ {
+ "name": "foo",
+ "version": "2.0.0",
+ "module": "index.esm.js"
+ }
+ `,
+ "/node_modules/foo/index.cjs.js": `
+ module.exports.foo = "hello index.cjs.js";
+ `,
+ "/node_modules/foo/index.esm.js": `
+ export const foo = "hello index.esm.js";
+ `,
+ },
+ run: {
+ stdout: "hello index.esm.js",
+ },
+ });
+ itBundled("default/BundlerUsesModuleFieldIfMainDoesNotExistEsm", {
+ files: {
+ "/entry.js": `
+ import { foo } from 'foo';
+ console.log(foo);
+ `,
+ "/node_modules/foo/package.json": `
+ {
+ "name": "foo",
+ "version": "2.0.0",
+ "module": "index.esm.js"
+ }
+ `,
+ "/node_modules/foo/index.cjs.js": `
+ module.exports.foo = "hello index.cjs.js";
+ `,
+ "/node_modules/foo/index.esm.js": `
+ export const foo = "hello index.esm.js";
+ `,
+ },
+ run: {
+ stdout: "hello index.esm.js",
+ },
+ });
+ itBundled("default/RuntimeUsesModuleFieldIfMainDoesNotExistCjs", {
+ files: {
+ "/entry.js": `
+ const { foo } = require('foo');
+ console.log(foo);
+ `,
+ "/node_modules/foo/package.json": `
+ {
+ "name": "foo",
+ "version": "2.0.0",
+ "module": "index.esm.js"
+ }
+ `,
+ "/node_modules/foo/index.cjs.js": `
+ module.exports.foo = "hello index.cjs.js";
+ `,
+ "/node_modules/foo/index.esm.js": `
+ export const foo = "hello index.esm.js";
+ `,
+ },
+ bundling: false,
+ run: {
+ stdout: "hello index.esm.js",
+ },
+ });
+ itBundled("default/RuntimeUsesModuleFieldIfMainDoesNotExistEsm", {
+ files: {
+ "/entry.js": `
+ import { foo } from 'foo';
+ console.log(foo);
+ `,
+ "/node_modules/foo/package.json": `
+ {
+ "name": "foo",
+ "version": "2.0.0",
+ "module": "index.esm.js"
+ }
+ `,
+ "/node_modules/foo/index.cjs.js": `
+ module.exports.foo = "hello index.cjs.js";
+ `,
+ "/node_modules/foo/index.esm.js": `
+ export const foo = "hello index.esm.js";
+ `,
+ },
+ bundling: false,
+ run: {
+ stdout: "hello index.esm.js",
+ },
+ });
});