diff --git a/lib/internal/main/mksnapshot.js b/lib/internal/main/mksnapshot.js index a0a917c7eed157..6dee4334fbaa4f 100644 --- a/lib/internal/main/mksnapshot.js +++ b/lib/internal/main/mksnapshot.js @@ -7,6 +7,8 @@ const { ObjectSetPrototypeOf, SafeArrayIterator, SafeSet, + StringPrototypeStartsWith, + StringPrototypeSlice, } = primordials; const binding = internalBinding('mksnapshot'); @@ -95,7 +97,13 @@ function supportedInUserSnapshot(id) { } function requireForUserSnapshot(id) { - if (!BuiltinModule.canBeRequiredByUsers(id)) { + let normalizedId = id; + if (StringPrototypeStartsWith(id, 'node:')) { + normalizedId = StringPrototypeSlice(id, 5); + } + if (!BuiltinModule.canBeRequiredByUsers(normalizedId) || + (id !== normalizedId && + !BuiltinModule.canBeRequiredWithoutScheme(normalizedId))) { // eslint-disable-next-line no-restricted-syntax const err = new Error( `Cannot find module '${id}'. `, @@ -103,15 +111,15 @@ function requireForUserSnapshot(id) { err.code = 'MODULE_NOT_FOUND'; throw err; } - if (!supportedInUserSnapshot(id)) { - if (!warnedModules.has(id)) { + if (!supportedInUserSnapshot(normalizedId)) { + if (!warnedModules.has(normalizedId)) { process.emitWarning( `built-in module ${id} is not yet supported in user snapshots`); - warnedModules.add(id); + warnedModules.add(normalizedId); } } - return require(id); + return require(normalizedId); } function main() { diff --git a/test/parallel/test-snapshot-namespaced-builtin.js b/test/parallel/test-snapshot-namespaced-builtin.js new file mode 100644 index 00000000000000..f3989273070333 --- /dev/null +++ b/test/parallel/test-snapshot-namespaced-builtin.js @@ -0,0 +1,42 @@ +'use strict'; + +// This tests snapshot JS API using the example in the docs. + +require('../common'); +const assert = require('assert'); +const { spawnSync } = require('child_process'); +const tmpdir = require('../common/tmpdir'); +const path = require('path'); +const fs = require('fs'); + +tmpdir.refresh(); +const blobPath = path.join(tmpdir.path, 'snapshot.blob'); +{ + // The list of modules supported in the snapshot is unstable, so just check + // a few that are known to work. + const code = ` + require("node:v8"); + require("node:fs"); + require("node:fs/promises"); + `; + fs.writeFileSync( + path.join(tmpdir.path, 'entry.js'), + code, + 'utf8' + ); + const child = spawnSync(process.execPath, [ + '--snapshot-blob', + blobPath, + '--build-snapshot', + 'entry.js', + ], { + cwd: tmpdir.path + }); + if (child.status !== 0) { + console.log(child.stderr.toString()); + console.log(child.stdout.toString()); + assert.strictEqual(child.status, 0); + } + const stats = fs.statSync(path.join(tmpdir.path, 'snapshot.blob')); + assert(stats.isFile()); +}