Skip to content

Commit 0abdb2f

Browse files
committed
vfs: add require(esm) and ESM detection tests
Add tests covering require() of ESM modules from VFS with package.json type detection (.js with type:module, nested directory walk-up, ESM-to-ESM imports) and .mjs extension-based ESM loading without type:module.
1 parent b270cdb commit 0abdb2f

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed

test/parallel/test-vfs-require.js

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,128 @@ const vfs = require('node:vfs');
169169
myVfs.unmount();
170170
}
171171

172+
// Test require(esm): .js file detected as ESM via VFS package.json type:module
173+
{
174+
const myVfs = vfs.create();
175+
myVfs.mkdirSync('/app', { recursive: true });
176+
myVfs.writeFileSync('/app/package.json', JSON.stringify({
177+
name: 'esm-app',
178+
type: 'module',
179+
}));
180+
myVfs.writeFileSync('/app/lib.js',
181+
'export const value = 42;' +
182+
' export function hello() { return "hi"; }');
183+
myVfs.mount('/virtual13');
184+
185+
const mod = require('/virtual13/app/lib.js');
186+
assert.strictEqual(mod.value, 42);
187+
assert.strictEqual(mod.hello(), 'hi');
188+
189+
myVfs.unmount();
190+
}
191+
192+
// Test require(esm): nested .js walks up to parent package.json in VFS
193+
{
194+
const myVfs = vfs.create();
195+
myVfs.mkdirSync('/project/src/utils', { recursive: true });
196+
myVfs.writeFileSync('/project/package.json', JSON.stringify({
197+
name: 'nested-esm',
198+
type: 'module',
199+
}));
200+
myVfs.writeFileSync('/project/src/utils/math.js',
201+
'export const add = (a, b) => a + b;' +
202+
' export default 99;');
203+
myVfs.mount('/virtual14');
204+
205+
const mod = require('/virtual14/project/src/utils/math.js');
206+
assert.strictEqual(mod.add(3, 4), 7);
207+
assert.strictEqual(mod.default, 99);
208+
209+
myVfs.unmount();
210+
}
211+
212+
// Test require(esm): .js without type field stays CJS
213+
{
214+
const myVfs = vfs.create();
215+
myVfs.mkdirSync('/cjs-app', { recursive: true });
216+
myVfs.writeFileSync('/cjs-app/package.json', JSON.stringify({
217+
name: 'cjs-app',
218+
}));
219+
myVfs.writeFileSync('/cjs-app/index.js',
220+
'module.exports = { cjs: true };');
221+
myVfs.mount('/virtual15');
222+
223+
const mod = require('/virtual15/cjs-app/index.js');
224+
assert.strictEqual(mod.cjs, true);
225+
226+
myVfs.unmount();
227+
}
228+
229+
// Test require(esm): ESM .js that imports another ESM .js in VFS
230+
{
231+
const myVfs = vfs.create();
232+
myVfs.mkdirSync('/multi/src', { recursive: true });
233+
myVfs.writeFileSync('/multi/package.json', JSON.stringify({
234+
type: 'module',
235+
}));
236+
myVfs.writeFileSync('/multi/src/dep.js', 'export const X = 100;');
237+
myVfs.writeFileSync('/multi/src/main.js',
238+
'import { X } from "./dep.js";' +
239+
' export const result = X + 1;');
240+
myVfs.mount('/virtual16');
241+
242+
const mod = require('/virtual16/multi/src/main.js');
243+
assert.strictEqual(mod.result, 101);
244+
245+
myVfs.unmount();
246+
}
247+
248+
// Test require(esm): .mjs without any package.json loads as ESM
249+
{
250+
const myVfs = vfs.create();
251+
myVfs.writeFileSync('/no-pkg.mjs',
252+
'export const x = 1; export default "hello";');
253+
myVfs.mount('/virtual17');
254+
255+
const mod = require('/virtual17/no-pkg.mjs');
256+
assert.strictEqual(mod.x, 1);
257+
assert.strictEqual(mod.default, 'hello');
258+
259+
myVfs.unmount();
260+
}
261+
262+
// Test require(esm): .mjs with package.json that has no type field
263+
{
264+
const myVfs = vfs.create();
265+
myVfs.mkdirSync('/app', { recursive: true });
266+
myVfs.writeFileSync('/app/package.json',
267+
JSON.stringify({ name: 'no-type' }));
268+
myVfs.writeFileSync('/app/lib.mjs', 'export const val = 42;');
269+
myVfs.mount('/virtual18');
270+
271+
const mod = require('/virtual18/app/lib.mjs');
272+
assert.strictEqual(mod.val, 42);
273+
274+
myVfs.unmount();
275+
}
276+
277+
// Test require(esm): .mjs in type:commonjs package still loads as ESM
278+
{
279+
const myVfs = vfs.create();
280+
myVfs.mkdirSync('/cjs-pkg', { recursive: true });
281+
myVfs.writeFileSync('/cjs-pkg/package.json', JSON.stringify({
282+
name: 'cjs-pkg',
283+
type: 'commonjs',
284+
}));
285+
myVfs.writeFileSync('/cjs-pkg/esm.mjs', 'export const z = 99;');
286+
myVfs.mount('/virtual19');
287+
288+
const mod = require('/virtual19/cjs-pkg/esm.mjs');
289+
assert.strictEqual(mod.z, 99);
290+
291+
myVfs.unmount();
292+
}
293+
172294
// Test that unmounting stops interception
173295
{
174296
const myVfs = vfs.create();

0 commit comments

Comments
 (0)