Skip to content

Commit a947b9b

Browse files
authored
fix: load mjs files correctly (#5429)
1 parent 7071c70 commit a947b9b

File tree

8 files changed

+91
-80
lines changed

8 files changed

+91
-80
lines changed

eslint.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ module.exports = [
7171
},
7272
{
7373
files: [
74-
'test/compiler-esm/*.js'
74+
'test/compiler-esm/*.{js,mjs}'
7575
],
7676
languageOptions: {
7777
sourceType: 'module',

lib/nodejs/esm-utils.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,19 @@ const tryImportAndRequire = async (file, esmDecorator) => {
9090
// and `require.cache` effective, while allowing us to load ESM modules
9191
// and CJS modules in the same way.
9292
const requireModule = async (file, esmDecorator) => {
93+
if (path.extname(file) === '.mjs') {
94+
return formattedImport(file, esmDecorator);
95+
}
9396
try {
9497
return require(file);
9598
} catch (err) {
9699
// Import if require fails.
97100
return dealWithExports(await formattedImport(file, esmDecorator));
98101
}
99-
}
102+
};
100103

104+
// We only assign this `requireOrImport` function once based on Node version
105+
// We check for file extensions in `requireModule` and `tryImportAndRequire`
101106
if (process.features.require_module) {
102107
exports.requireOrImport = requireModule;
103108
} else {

test/compiler-esm/test-tla.mjs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const obj = { foo: 'bar' };
2+
3+
describe('esm written in esm with top-level-await', () => {
4+
it('should work', () => {
5+
expect(obj, 'to equal', { foo: 'bar' });
6+
});
7+
});
8+
9+
await undefined;
10+
11+
export const foo = 'bar';
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const obj = { foo: 'bar' };
2+
3+
describe('esm written in esm with top-level-await', () => {
4+
it('should work', () => {
5+
expect(obj, 'to equal', { foo: 'bar' });
6+
});
7+
});
8+
9+
await undefined;
10+
11+
export const foo = 'bar';

test/compiler-esm/test.mjs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const obj = {foo: 'bar'};
2+
3+
describe('esm written in esm', () => {
4+
it('should work', () => {
5+
expect(obj, 'to equal', {foo: 'bar'});
6+
});
7+
});
8+
9+
export const foo = 'bar';
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const obj = {foo: 'bar'};
2+
3+
describe('esm written in esm', () => {
4+
it('should work', () => {
5+
expect(obj, 'to equal', {foo: 'bar'});
6+
});
7+
});
8+
9+
export const foo = 'bar';

test/integration/compiler-esm-only-loader.spec.js

Lines changed: 22 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,18 @@ var path = require('node:path');
55

66
// Regression test for https://github.com/mochajs/mocha/issues/5380
77
describe('support ESM only module loader packages', function () {
8-
it('should support ESM .js extension', function (done) {
8+
/**
9+
* Load the filename using an ESM-only loader and expect things to work
10+
* @param {string} filename Name of the file to load
11+
* @param {Function} done A Mocha done callback for when the test ends
12+
*/
13+
function loadAndExpect(filename, done) {
914
exec(
1015
'"' +
1116
process.execPath +
1217
'" "' +
1318
path.join('bin', 'mocha') +
14-
'" -R json --require "@test/esm-only-loader" "test/compiler-esm/*.js"',
19+
`" -R json --require "@test/esm-only-loader" "${filename}"`,
1520
{cwd: path.join(__dirname, '..', '..')},
1621
function (error, stdout) {
1722
if (error && !stdout) {
@@ -24,48 +29,26 @@ describe('support ESM only module loader packages', function () {
2429
expect(results.tests[index], 'to have property', 'fullTitle');
2530
titles.push(results.tests[index].fullTitle);
2631
}
27-
expect(
28-
titles,
29-
'to contain',
30-
'esm written in esm should work',
31-
).and(
32-
'to contain',
33-
'esm written in esm with top-level-await should work',
34-
).and('to have length', 2);
32+
expect(titles, 'to contain', 'esm written in esm should work')
33+
.and(
34+
'to contain',
35+
'esm written in esm with top-level-await should work'
36+
)
37+
.and('to have length', 2);
3538
done();
3639
}
3740
);
41+
}
42+
43+
it('should support ESM .js extension', function (done) {
44+
loadAndExpect('test/compiler-esm/*.js', done);
3845
});
3946

4047
it('should support ESM .ts extension', function (done) {
41-
exec(
42-
'"' +
43-
process.execPath +
44-
'" "' +
45-
path.join('bin', 'mocha') +
46-
'" -R json --require "@test/esm-only-loader" "test/compiler-esm/*.ts"',
47-
{cwd: path.join(__dirname, '..', '..')},
48-
function (error, stdout) {
49-
if (error && !stdout) {
50-
return done(error);
51-
}
52-
var results = JSON.parse(stdout);
53-
expect(results, 'to have property', 'tests');
54-
var titles = [];
55-
for (var index = 0; index < results.tests.length; index += 1) {
56-
expect(results.tests[index], 'to have property', 'fullTitle');
57-
titles.push(results.tests[index].fullTitle);
58-
}
59-
expect(
60-
titles,
61-
'to contain',
62-
'esm written in esm should work',
63-
).and(
64-
'to contain',
65-
'esm written in esm with top-level-await should work',
66-
).and('to have length', 2);
67-
done();
68-
}
69-
);
48+
loadAndExpect('test/compiler-esm/*.ts', done);
49+
});
50+
51+
it('should support ESM .mjs extension', function (done) {
52+
loadAndExpect('test/compiler-esm/*.mjs', done);
7053
});
7154
});

test/integration/compiler-esm.spec.js

Lines changed: 22 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@ var exec = require('node:child_process').exec;
44
var path = require('node:path');
55

66
describe('support ESM module loader compilers', function () {
7-
it('should support ESM .js extension', function (done) {
7+
/**
8+
* Runs `exec` on an ESM setup for the given file
9+
* @param {string} filename Path to the file to load
10+
* @param {Function} done A Mocha done callback for when the test ends
11+
*/
12+
function loadAndExpect(filename, done) {
813
exec(
914
'"' +
1015
process.execPath +
1116
'" "' +
1217
path.join('bin', 'mocha') +
13-
'" -R json --require test/compiler-fixtures/esm.fixture "test/compiler-esm/*.js"',
18+
`" -R json --require test/compiler-fixtures/esm.fixture "${filename}"`,
1419
{cwd: path.join(__dirname, '..', '..')},
1520
function (error, stdout) {
1621
if (error && !stdout) {
@@ -23,48 +28,26 @@ describe('support ESM module loader compilers', function () {
2328
expect(results.tests[index], 'to have property', 'fullTitle');
2429
titles.push(results.tests[index].fullTitle);
2530
}
26-
expect(
27-
titles,
28-
'to contain',
29-
'esm written in esm should work',
30-
).and(
31-
'to contain',
32-
'esm written in esm with top-level-await should work',
33-
).and('to have length', 2);
31+
expect(titles, 'to contain', 'esm written in esm should work')
32+
.and(
33+
'to contain',
34+
'esm written in esm with top-level-await should work'
35+
)
36+
.and('to have length', 2);
3437
done();
3538
}
3639
);
40+
}
41+
42+
it('should support ESM .js extension', function (done) {
43+
loadAndExpect('test/compiler-esm/*.js', done);
3744
});
3845

3946
it('should support ESM .ts extension', function (done) {
40-
exec(
41-
'"' +
42-
process.execPath +
43-
'" "' +
44-
path.join('bin', 'mocha') +
45-
'" -R json --require test/compiler-fixtures/esm.fixture "test/compiler-esm/*.ts"',
46-
{cwd: path.join(__dirname, '..', '..')},
47-
function (error, stdout) {
48-
if (error && !stdout) {
49-
return done(error);
50-
}
51-
var results = JSON.parse(stdout);
52-
expect(results, 'to have property', 'tests');
53-
var titles = [];
54-
for (var index = 0; index < results.tests.length; index += 1) {
55-
expect(results.tests[index], 'to have property', 'fullTitle');
56-
titles.push(results.tests[index].fullTitle);
57-
}
58-
expect(
59-
titles,
60-
'to contain',
61-
'esm written in esm should work',
62-
).and(
63-
'to contain',
64-
'esm written in esm with top-level-await should work',
65-
).and('to have length', 2);
66-
done();
67-
}
68-
);
47+
loadAndExpect('test/compiler-esm/*.ts', done);
48+
});
49+
50+
it('should support ESM .mjs extension', function (done) {
51+
loadAndExpect('test/compiler-esm/*.mjs', done);
6952
});
7053
});

0 commit comments

Comments
 (0)