Skip to content

Commit 2695f82

Browse files
guybedfordtargos
authored andcommitted
module: warn on require of .js inside type: module
PR-URL: #29909 Reviewed-By: Jan Krems <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Colin Ihrig <[email protected]>
1 parent 1fefd7f commit 2695f82

File tree

4 files changed

+67
-5
lines changed

4 files changed

+67
-5
lines changed

lib/internal/modules/cjs/loader.js

+27-5
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,10 @@ function readPackageScope(checkPath) {
261261
if (checkPath.endsWith(path.sep + 'node_modules'))
262262
return false;
263263
const pjson = readPackage(checkPath);
264-
if (pjson) return pjson;
264+
if (pjson) return {
265+
path: checkPath,
266+
data: pjson
267+
};
265268
}
266269
return false;
267270
}
@@ -960,13 +963,32 @@ Module.prototype._compile = function(content, filename) {
960963
return result;
961964
};
962965

963-
964966
// Native extension for .js
967+
let warnRequireESM = true;
965968
Module._extensions['.js'] = function(module, filename) {
966-
if (experimentalModules && filename.endsWith('.js')) {
969+
if (filename.endsWith('.js')) {
967970
const pkg = readPackageScope(filename);
968-
if (pkg && pkg.type === 'module') {
969-
throw new ERR_REQUIRE_ESM(filename);
971+
if (pkg && pkg.data && pkg.data.type === 'module') {
972+
if (warnRequireESM) {
973+
const parentPath = module.parent && module.parent.filename;
974+
const basename = parentPath &&
975+
path.basename(filename) === path.basename(parentPath) ?
976+
filename : path.basename(filename);
977+
process.emitWarning(
978+
'require() of ES modules is not supported.\nrequire() of ' +
979+
`${filename} ${parentPath ? `from ${module.parent.filename} ` : ''}` +
980+
'is an ES module file as it is a .js file whose nearest parent ' +
981+
'package.json contains "type": "module" which defines all .js ' +
982+
'files in that package scope as ES modules.\nInstead rename ' +
983+
`${basename} to end in .cjs, change the requiring code to use ` +
984+
'import(), or remove "type": "module" from ' +
985+
`${path.resolve(pkg.path, 'package.json')}.`
986+
);
987+
warnRequireESM = false;
988+
}
989+
if (experimentalModules) {
990+
throw new ERR_REQUIRE_ESM(filename);
991+
}
970992
}
971993
}
972994
const content = fs.readFileSync(filename, 'utf8');

test/es-module/test-cjs-esm-warn.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const fixtures = require('../common/fixtures');
5+
const { spawn } = require('child_process');
6+
const assert = require('assert');
7+
const path = require('path');
8+
9+
const requiring = path.resolve(fixtures.path('/es-modules/cjs-esm.js'));
10+
const required = path.resolve(
11+
fixtures.path('/es-modules/package-type-module/cjs.js')
12+
);
13+
const pjson = path.resolve(
14+
fixtures.path('/es-modules/package-type-module/package.json')
15+
);
16+
17+
const basename = 'cjs.js';
18+
19+
const child = spawn(process.execPath, [requiring]);
20+
let stderr = '';
21+
child.stderr.setEncoding('utf8');
22+
child.stderr.on('data', (data) => {
23+
stderr += data;
24+
});
25+
child.on('close', common.mustCall((code, signal) => {
26+
assert.strictEqual(code, 0);
27+
assert.strictEqual(signal, null);
28+
29+
assert.strictEqual(stderr, `(node:${child.pid}) Warning: ` +
30+
'require() of ES modules is not supported.\nrequire() of ' +
31+
`${required} from ${requiring} ` +
32+
'is an ES module file as it is a .js file whose nearest parent ' +
33+
'package.json contains "type": "module" which defines all .js ' +
34+
'files in that package scope as ES modules.\nInstead rename ' +
35+
`${basename} to end in .cjs, change the requiring code to use ` +
36+
'import(), or remove "type": "module" from ' +
37+
`${pjson}.\n`);
38+
}));

test/fixtures/es-modules/cjs-esm.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
require('./package-type-module/cjs.js');
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = 'asdf';

0 commit comments

Comments
 (0)