Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/jsc/modules/NodeModuleModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ JSC_DECLARE_CUSTOM_SETTER(setterRequireFunction);
// The reason for overstuffing this list is so that uses that use these as the
// 'external' option to a bundler will properly exclude things like 'ws' which
// only work with Bun's native 'ws' implementation and not the JS one on NPM.
//
// Modules that only resolve with the "node:" prefix ("node:sqlite",
// "node:test") are listed with the prefix, as in Node's module.builtinModules.
static constexpr ASCIILiteral builtinModuleNames[] = {
"_http_agent"_s,
"_http_client"_s,
Expand Down Expand Up @@ -92,6 +95,7 @@ static constexpr ASCIILiteral builtinModuleNames[] = {
"module"_s,
"net"_s,
"node:sqlite"_s,
"node:test"_s,
"os"_s,
"path"_s,
"path/posix"_s,
Expand Down
16 changes: 15 additions & 1 deletion test/js/node/module/node-module-module.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,21 @@ describe.concurrent("node-module-module", () => {
expect(Array.isArray(builtinModules)).toBe(true);
// "bun:wrap" is no longer listed: it is internal transpiler plumbing,
// not a requireable public module.
expect(builtinModules).toHaveLength(76);
expect(builtinModules).toHaveLength(77);
});

test("builtinModules lists prefix-only node modules with their prefix, as Node does", () => {
const prefixed = builtinModules.filter(name => name.startsWith("node:"));
// Node lists these with the prefix because the bare names are not builtins. "node:quic" is left out on
// purpose: Node 26 does not list it unless QUIC is compiled in and enabled with --experimental-quic.
expect(prefixed).toEqual(["node:sqlite", "node:test"]);
expect(builtinModules).not.toContain("test");
// Every entry resolves as a builtin, and a prefixed entry is requireable only with its prefix.
expect(builtinModules.filter(name => !isBuiltin(name))).toEqual([]);
for (const name of prefixed) {
expect(isBuiltin(name.slice("node:".length))).toBe(false);
expect(process.getBuiltinModule(name)).toBe(require(name));
}
});

test("isBuiltin() works", () => {
Expand Down
9 changes: 9 additions & 0 deletions test/js/node/test_runner/node-test.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import { spawn } from "bun";
import { describe, expect, test } from "bun:test";
import { bunEnv, bunExe } from "harness";
import { builtinModules, isBuiltin } from "node:module";
import { join } from "node:path";

describe("node:test", () => {
test("node:test is a built-in module", () => {
expect(isBuiltin("node:test")).toBe(true);
// Like node:sqlite, node:test is only available with the node: prefix.
expect(isBuiltin("test")).toBe(false);
expect(builtinModules).toContain("node:test");
expect(builtinModules).not.toContain("test");
});

// These three drive the largest fixtures (01-harness has 32 node:test cases);
// a debug+ASAN `bun test` child takes several seconds to start, so give them
// headroom and let them spawn in parallel instead of serially.
Expand Down
Loading