import assert from "assert"; import { expect, mock, test } from "bun:test"; import { tempDirWithFiles } from "harness"; import path from "path"; test("require.extensions shape makes sense", () => { const extensions = require.extensions; expect(extensions).toBeDefined(); expect(typeof extensions).toBe("object"); expect(extensions[".js"]).toBeFunction(); expect(extensions[".json"]).toBeFunction(); expect(extensions[".node"]).toBeFunction(); // When --experimental-strip-types is passed, TypeScript files can be loaded. expect(extensions[".cts"]).toBeFunction(); expect(extensions[".ts"]).toBeFunction(); expect(extensions[".mjs"]).toBeFunction(); expect(extensions[".mts"]).toBeFunction(); expect(require("module")._extensions === require.extensions).toBe(true); }); test("custom require extension 1", () => { const custom = (require.extensions[".custom"] = mock(function (module, filename) { expect(filename).toBe(path.join(import.meta.dir, "extensions-fixture", "c.custom")); (module as any)._compile(`module.exports = 'custom';`, filename); })); const mod = require("./extensions-fixture/c"); expect(mod).toBe("custom"); expect(custom.mock.calls.length).toBe(1); delete require.extensions[".custom"]; expect(() => require("./extensions-fixture/c")).toThrow(/Cannot find module/); expect(require("./extensions-fixture/c.custom")).toBe("custom"); // already loaded delete require.cache[require.resolve("./extensions-fixture/c.custom")]; expect(custom.mock.calls.length).toBe(1); expect(require("./extensions-fixture/c.custom")).toBe("c dot custom"); // use js loader }); test("custom require extension overwrite default loader", () => { const original = require.extensions[".js"]; try { const custom = (require.extensions[".js"] = mock(function (module, filename) { expect(filename).toBe(path.join(import.meta.dir, "extensions-fixture", "d.js")); (module as any)._compile(`module.exports = 'custom';`, filename); })); const mod = require("./extensions-fixture/d"); expect(mod).toBe("custom"); expect(custom.mock.calls.length).toBe(1); require.extensions[".js"] = original; expect(require("./extensions-fixture/d")).toBe("custom"); // already loaded delete require.cache[require.resolve("./extensions-fixture/d")]; expect(custom.mock.calls.length).toBe(1); expect(require("./extensions-fixture/d")).toBe("d.js"); // use js loader } finally { require.extensions[".js"] = original; } }); test("custom require extension overwrite default loader with other default loader", () => { const original = require.extensions[".js"]; try { require.extensions[".js"] = require.extensions[".ts"]!; const mod = require("./extensions-fixture/e.js"); // should not enter JS expect(mod).toBe("hello world"); } finally { require.extensions[".js"] = original; } }); test("test that assigning properties weirdly wont do anything bad", () => { const original = require.extensions[".js"]; try { function f1() {} function f2() {} require.extensions[".js"] = f1; require.extensions[".abc"] = f2; require.extensions[".js"] = f2; require.extensions[".js"] = undefined!; require.extensions[".abc"] = undefined!; require.extensions[".abc"] = f1; require.extensions[".js"] = f2; } finally { require.extensions[".js"] = original; } }); test("wrapping an existing extension with no logic", () => { const original = require.extensions[".js"]; try { delete require.cache[require.resolve("./extensions-fixture/d")]; const mocked = (require.extensions[".js"] = mock(function (module, filename) { expect(module).toBeDefined(); expect(filename).toBe(path.join(import.meta.dir, "extensions-fixture", "d.js")); original(module, filename); })); const mod = require("./extensions-fixture/d"); expect(mod).toBe("d.js"); expect(mocked).toBeCalled(); } finally { require.extensions[".js"] = original; } }); test("wrapping an existing extension with mutated compile function", () => { const original = require.extensions[".js"]; try { delete require.cache[require.resolve("./extensions-fixture/d")]; const mocked = (require.extensions[".js"] = mock(function (module, filename) { expect(module).toBeDefined(); expect(filename).toBe(path.join(import.meta.dir, "extensions-fixture", "d.js")); const originalCompile = module._compile; module._compile = function (code, filename) { expect(code).toBe('\n module.exports = \"d.js\";\n'); expect(filename).toBe(path.join(import.meta.dir, "extensions-fixture", "d.js")); originalCompile.call(module, 'module.exports = "new";', filename); }; original(module, filename); })); const mod = require("./extensions-fixture/d"); expect(mod).toBe("new"); expect(mocked).toBeCalled(); } finally { require.extensions[".js"] = original; } }); test("wrapping an existing extension with mutated compile function ts", () => { const original = require.extensions[".ts"]; assert(original); try { delete require.cache[require.resolve("./extensions-fixture/e.js")]; const mocked = (require.extensions[".js"] = mock(function (module, filename) { expect(module).toBeDefined(); expect(filename).toBe(path.join(import.meta.dir, "extensions-fixture", "e.js")); const originalCompile = module._compile; module._compile = function (code, filename) { expect(code).toBe( '\n var J;\n ((J) => J.x = \"hello\")(J ||= {});\n const hello = \" world\";\n module.exports = \"hello world\";\n', ); expect(filename).toBe(path.join(import.meta.dir, "extensions-fixture", "e.js")); originalCompile.call(module, 'module.exports = "new";', filename); }; original(module, filename); })); const mod = require("./extensions-fixture/e"); expect(mod).toBe("new"); expect(mocked).toBeCalled(); } finally { require.extensions[".js"] = original; } }); test("wrapping an existing extension but it's secretly sync esm", () => { const original = require.extensions[".ts"]; assert(original); try { delete require.cache[require.resolve("./extensions-fixture/secretly_esm.cjs")]; let called = false; const mocked = (require.extensions[".cjs"] = mock(function (module, filename) { expect(module).toBeDefined(); expect(filename).toBe(path.join(import.meta.dir, "extensions-fixture", "secretly_esm.cjs")); module._compile = function (code, filename) { called = true; throw new Error("should not be called"); }; original(module, filename); })); const mod = require("./extensions-fixture/secretly_esm"); expect(mod).toEqual({ default: 1 }); expect(mocked).toBeCalled(); } finally { require.extensions[".cjs"] = original; } }); test("mutating extensions is banned by some files", () => { // vercel is not allowed to mutate require.extensions const files = ["node_modules/next/dist/build/next-config-ts/index.js", "node_modules/@meteorjs/babel/index.js"]; const fixture = tempDirWithFiles( "extensions-fixture", Object.fromEntries( files.map(file => [ file, ` const assert = require('assert'); const mock = function (module, filename) { throw new Error('should not be called'); }; require.extensions['.js'] = mock; assert(require.extensions['.js'] !== mock); globalThis.pass += 1; `, ]), ), ); globalThis.pass = 0; let n = 0; for (const file of files) { require(path.join(fixture, file)); n++; expect(globalThis.pass).toBe(n); } });