From ead99142f511a7c65b6a74f990b81e5e9cb5080d Mon Sep 17 00:00:00 2001 From: Ali Hassan Date: Fri, 10 Apr 2026 22:07:09 +0500 Subject: [PATCH] sea: add test and update docs for import() with code cache Signed-off-by: Ali Hassan --- doc/api/single-executable-applications.md | 7 ++-- src/node_sea.cc | 6 ---- .../sea-config.json | 6 ++++ .../sea/use-code-cache-dynamic-import/sea.js | 13 +++++++ ...plication-use-code-cache-dynamic-import.js | 36 +++++++++++++++++++ 5 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 test/fixtures/sea/use-code-cache-dynamic-import/sea-config.json create mode 100644 test/fixtures/sea/use-code-cache-dynamic-import/sea.js create mode 100644 test/sea/test-single-executable-application-use-code-cache-dynamic-import.js diff --git a/doc/api/single-executable-applications.md b/doc/api/single-executable-applications.md index c63b8c8f57c0c3..ea3ecf71b05098 100644 --- a/doc/api/single-executable-applications.md +++ b/doc/api/single-executable-applications.md @@ -216,8 +216,6 @@ executable application is launched, instead of compiling the `main` script from scratch, Node.js would use the code cache to speed up the compilation, then execute the script, which would improve the startup performance. -**Note:** `import()` does not work when `useCodeCache` is `true`. - ### Execution arguments The `execArgv` field can be used to specify Node.js-specific @@ -451,8 +449,9 @@ injected main script with the following properties: -When using `"mainFormat": "module"`, `import()` can be used to dynamically -load built-in modules. Attempting to use `import()` to load modules from +`import()` can be used to dynamically load built-in modules in both +CommonJS and ESM (`"mainFormat": "module"`) single executable applications. +Attempting to use `import()` to load modules from the file system will throw an error. ### Using native addons in the injected main script diff --git a/src/node_sea.cc b/src/node_sea.cc index 1be41e6f14146e..b9aec0479670f1 100644 --- a/src/node_sea.cc +++ b/src/node_sea.cc @@ -666,12 +666,6 @@ std::optional GenerateCodeCache(std::string_view main_path, Local unbound = module->GetUnboundModuleScript(); cache.reset(ScriptCompiler::CreateCodeCache(unbound)); } else { - // TODO(RaisinTen): Using the V8 code cache prevents us from using - // `import()` in the SEA code. Support it. Refs: - // https://github.com/nodejs/node/pull/48191#discussion_r1213271430 - // TODO(joyeecheung): this likely has been fixed by - // https://chromium-review.googlesource.com/c/v8/v8/+/5401780 - add a test - // and update docs. LocalVector parameters( isolate, { diff --git a/test/fixtures/sea/use-code-cache-dynamic-import/sea-config.json b/test/fixtures/sea/use-code-cache-dynamic-import/sea-config.json new file mode 100644 index 00000000000000..a2da0b9d143072 --- /dev/null +++ b/test/fixtures/sea/use-code-cache-dynamic-import/sea-config.json @@ -0,0 +1,6 @@ +{ + "main": "sea.js", + "output": "sea", + "useCodeCache": true, + "disableExperimentalSEAWarning": true +} diff --git a/test/fixtures/sea/use-code-cache-dynamic-import/sea.js b/test/fixtures/sea/use-code-cache-dynamic-import/sea.js new file mode 100644 index 00000000000000..90c8a1ac66d341 --- /dev/null +++ b/test/fixtures/sea/use-code-cache-dynamic-import/sea.js @@ -0,0 +1,13 @@ +(async () => { + const assert = require('node:assert'); + + // Dynamic import of a built-in module should work even with code cache. + const { strictEqual } = await import('node:assert'); + assert.strictEqual(strictEqual, assert.strictEqual); + + // Dynamic import of another built-in module. + const { join } = await import('node:path'); + assert.strictEqual(typeof join, 'function'); + + console.log('dynamic import with code cache works'); +})(); diff --git a/test/sea/test-single-executable-application-use-code-cache-dynamic-import.js b/test/sea/test-single-executable-application-use-code-cache-dynamic-import.js new file mode 100644 index 00000000000000..5bb0e71b71e8c5 --- /dev/null +++ b/test/sea/test-single-executable-application-use-code-cache-dynamic-import.js @@ -0,0 +1,36 @@ +'use strict'; + +// This tests that import() works in a CJS single executable application +// when useCodeCache is true. A V8 fix (https://chromium-review.googlesource.com +// /c/v8/v8/+/5401780) resolved the issue where code cache serialization +// wiped host-defined options needed by HostImportModuleDynamically. + +require('../common'); + +const { + buildSEA, + skipIfBuildSEAIsNotSupported, +} = require('../common/sea'); + +skipIfBuildSEAIsNotSupported(); + +const tmpdir = require('../common/tmpdir'); +const fixtures = require('../common/fixtures'); +const { spawnSyncAndAssert } = require('../common/child_process'); + +tmpdir.refresh(); + +const outputFile = buildSEA(fixtures.path('sea', 'use-code-cache-dynamic-import')); + +spawnSyncAndAssert( + outputFile, + [], + { + env: { + NODE_DEBUG_NATIVE: 'SEA', + ...process.env, + }, + }, + { + stdout: 'dynamic import with code cache works\n', + });