From 4f6196050cdd2166fe03955c53811a07fc1d30c0 Mon Sep 17 00:00:00 2001 From: ExE Boss <3889017+ExE-Boss@users.noreply.github.com> Date: Sat, 6 Feb 2021 12:10:00 +0100 Subject: [PATCH] =?UTF-8?q?module:=20add=C2=A0support=20for=C2=A0`node:`?= =?UTF-8?q?=E2=80=91prefixed=20`require(=E2=80=A6)`=C2=A0calls?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: https://github.com/nodejs/node/issues/36098 --- lib/internal/modules/cjs/loader.js | 14 ++++++++-- test/parallel/test-require-node-prefix.js | 34 +++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-require-node-prefix.js diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index 5abfa465e0407d..3608007ea5bd1c 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -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'); @@ -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) { @@ -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; } diff --git a/test/parallel/test-require-node-prefix.js b/test/parallel/test-require-node-prefix.js new file mode 100644 index 00000000000000..7582ca4bffc9c3 --- /dev/null +++ b/test/parallel/test-require-node-prefix.js @@ -0,0 +1,34 @@ +'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' }, + ); +} + +// `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; +}