Skip to content

Commit

Permalink
module: add support for node:‑prefixed require(…) calls
Browse files Browse the repository at this point in the history
  • Loading branch information
ExE-Boss committed Feb 6, 2021
1 parent c0e66e3 commit 98b9a8a
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
14 changes: 12 additions & 2 deletions lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ let hasLoadedAnyUserCJSModule = false;
const {
ERR_INVALID_ARG_VALUE,
ERR_INVALID_MODULE_SPECIFIER,
ERR_REQUIRE_ESM
ERR_REQUIRE_ESM,
ERR_UNKNOWN_BUILTIN_MODULE,
} = require('internal/errors').codes;
const { validateString } = require('internal/validators');
const pendingDeprecation = getOptionValue('--pending-deprecation');
Expand Down Expand Up @@ -766,6 +767,14 @@ Module._load = function(request, parent, isMain) {
}

const filename = Module._resolveFilename(request, parent, isMain);
if (StringPrototypeStartsWith(filename, 'node:')) {
const specifier = StringPrototypeSlice(filename, 5);

const mod = loadNativeModule(specifier, request);
if (mod && mod.canBeRequiredByUsers) return mod.exports;

throw new ERR_UNKNOWN_BUILTIN_MODULE(specifier);
}

const cachedModule = Module._cache[filename];
if (cachedModule !== undefined) {
Expand Down Expand Up @@ -837,7 +846,8 @@ Module._load = function(request, parent, isMain) {
};

Module._resolveFilename = function(request, parent, isMain, options) {
if (NativeModule.canBeRequiredByUsers(request)) {
if (StringPrototypeStartsWith(request, 'node:') ||
NativeModule.canBeRequiredByUsers(request)) {
return request;
}

Expand Down
39 changes: 39 additions & 0 deletions test/parallel/test-require-node-prefix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
'use strict';

require('../common');
const assert = require('assert');
const fs = require('fs');

// For direct use of require expressions inside of CJS modules,
// including via eval, all kinds of specifiers should work without issue.
{
// Importing a built-in, both direct & via eval
assert.strictEqual(require('fs'), fs);
assert.strictEqual(eval('require("fs")'), fs);
assert.strictEqual(require('node:fs'), fs);
assert.strictEqual(eval('require("node:fs")'), fs);

assert.throws(
() => require('node:unknown'),
{ code: 'ERR_UNKNOWN_BUILTIN_MODULE' },
);

assert.throws(
() => require('node:internal/test/binding'),
{ code: 'ERR_UNKNOWN_BUILTIN_MODULE' },
);
}

// `node:`-prefixed `require(...)` calls bypass the require cache:
{
const fakeModule = {};

require.cache.fs = { exports: fakeModule };

assert.strictEqual(require('fs'), fakeModule);
assert.strictEqual(eval('require("fs")'), fakeModule);
assert.strictEqual(require('node:fs'), fs);
assert.strictEqual(eval('require("node:fs")'), fs);

delete require.cache.fs;
}

0 comments on commit 98b9a8a

Please sign in to comment.