With Node.js v12.11.1, On Windows 10,
node --experimental-modules test.js
Source Code
console.log("version:", process.version)
;(async () => {
console.log("==== ESM ====")
await import("x-esm") //→ Found as expected
await import("./node_modules/x-esm/index.js?q=0") //→ Found and `x-esm` re-ran as expected
await import("./node_modules/x-esm/index.js?q=1") //→ Found and `x-esm` re-ran as expected
console.log("==== CJS ====")
const cjs = await import("x-cjs") //→ Found as expected
const cjs0 = await import("./node_modules/x-cjs/index.js?q=0") //→ Found but `x-cjs` didn't re-run
const cjs1 = await import("./node_modules/x-cjs/index.js?q=1") //→ Found but `x-cjs` didn't re-run
console.log(cjs === cjs0, cjs === cjs1, cjs0 === cjs1) //→ all are false but `x-cjs` didn't run three times
console.log("---- remove 'require.cache' ----")
delete require.cache[require.resolve("x-cjs")]
await import("x-cjs") //→ Found but `x-cjs` didn't re-run
await import("./node_modules/x-cjs/index.js?q=0") //→ Found but `x-cjs` didn't re-run
await import("./node_modules/x-cjs/index.js?q=1") //→ Found but `x-cjs` didn't re-run
await import("./node_modules/x-cjs/index.js?q=2") //→ Found and `x-cjs` re-ran as expected
await import("./node_modules/x-cjs/index.js?q=3") //→ Found but `x-cjs` didn't re-run
})().catch(error => {
console.error(error)
process.exitCode = 1
})Result
(node:14972) ExperimentalWarning: The ESM module loader is experimental.
version: v12.11.1
==== ESM ====
x-esm
x-esm
x-esm
==== CJS ====
x-cjs
false false false
---- remove 'require.cache' ----
x-cjs
I tried to import packages without import cache. From the document, it looks I should use query strings.
await import("x-esm") //→ Found as expected
await import("./node_modules/x-esm/index.js?q=0") //→ Found and `x-esm` re-ran as expected
await import("./node_modules/x-esm/index.js?q=1") //→ Found and `x-esm` re-ran as expectedx-esm is an ES module package. It worked as expected.
const cjs = await import("x-cjs") //→ Found as expected
const cjs0 = await import("./node_modules/x-cjs/index.js?q=0") //→ Found but `x-cjs` didn't re-run
const cjs1 = await import("./node_modules/x-cjs/index.js?q=1") //→ Found but `x-cjs` didn't re-run
console.log(cjs === cjs0, cjs === cjs1, cjs0 === cjs1) //→ all are false but `x-cjs` didn't run three timesx-cjs is a CJS package. The result was odd. The console.log() in x-cjs package ran only one time, but the returned values are different for each query string.
I found the entry of x-cjs in require.cache. However, the cache entry is odd as well. It's different from require("x-cjs"), the entry doesn't have parent property and the module.children of test.js is still empty.
Anyway, I tried to remove the cache entry.
console.log("---- remove 'require.cache' ----")
delete require.cache[require.resolve("x-cjs")]
await import("x-cjs") //→ Found but `x-cjs` didn't re-run
await import("./node_modules/x-cjs/index.js?q=0") //→ Found but `x-cjs` didn't re-run
await import("./node_modules/x-cjs/index.js?q=1") //→ Found but `x-cjs` didn't re-run
await import("./node_modules/x-cjs/index.js?q=2") //→ Found and `x-cjs` re-ran as expected
await import("./node_modules/x-cjs/index.js?q=3") //→ Found but `x-cjs` didn't re-runCryptic. I guess this behavior is:
import(cjs)has cache apart fromrequire.cache.- The
import(cjs)cache is created fromrequire.cache. - It runs CJS package only if
require.cacheentry was not found. - The
import(cjs)cache is not removed even ifrequire.cacheentry deleted.
Therefore, I have to do the following steps if I want to import packages without cache.
- Find the main file of the package because I cannot put query strings to the package name.
const url = "file:" + require.resolve(packageName) + uniqueQueryString;
- Import it.
const ret = await import(url);
- Delete
require.cacheentry.delete require.cache[require.resolve(packageName)];
- Is it intentional behavior that
import(cjs)creates incompleterequire.cacheentries? - If yes, is it intentional behavior that
import(cjs)with query strings returns different objects for the same CJS package?
I'm guessing that import(cjs) should not create any require.cache entries, and import(cjs) with query strings re-runs CJS packages as same as ES packages.