Skip to content

Commit e6223ee

Browse files
committed
module: warn on invalid package.json type field
Add validation to warn users when the "type" field in package.json contains an invalid value. Previously, values like "CommonJS" (wrong case) would silently fall back to typeless behavior. Now a clear warning message is displayed indicating the expected values are "commonjs" or "module". Fixes: #60085
1 parent 0c1fb98 commit e6223ee

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

src/node_modules.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,15 @@ const BindingData::PackageConfig* BindingData::GetPackageJSON(
212212
if (value.get_string().get(field_value)) {
213213
return throw_invalid_package_config();
214214
}
215+
216+
if (field_value != "commonjs" && field_value != "module") {
217+
fprintf(stderr,
218+
"node: [MODULE_INVALID_TYPE] Invalid \"type\" field in package.json: \"%.*s\". "
219+
"Expected \"commonjs\" or \"module\".\n",
220+
static_cast<int>(field_value.size()),
221+
field_value.data());
222+
}
223+
215224
// Only update type if it is "commonjs" or "module"
216225
// The default value is "none" for backward compatibility.
217226
if (field_value == "commonjs" || field_value == "module") {
@@ -275,7 +284,7 @@ void BindingData::ReadPackageJSON(const FunctionCallbackInfo<Value>& args) {
275284

276285
if (package_json == nullptr) {
277286
return;
278-
}
287+
}
279288

280289
args.GetReturnValue().Set(package_json->Serialize(realm));
281290
}

test/parallel/test-find-package-json.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,4 +204,68 @@ describe('findPackageJSON', () => { // Throws when no arguments are provided
204204
assert.ok(stdout.includes(foundPjsonPath), stdout);
205205
assert.strictEqual(code, 0);
206206
});
207+
208+
209+
});
210+
211+
describe('package.json type field validation', () => {
212+
it('should warn for invalid type field values', async () => {
213+
tmpdir.refresh();
214+
215+
fs.mkdirSync(tmpdir.resolve('invalid-type-pkg'), { recursive: true });
216+
fs.writeFileSync(
217+
tmpdir.resolve('invalid-type-pkg/package.json'),
218+
JSON.stringify({ type: 'CommonJS' })
219+
);
220+
fs.writeFileSync(
221+
tmpdir.resolve('invalid-type-pkg/index.js'),
222+
'module.exports = 42;'
223+
);
224+
225+
const { stderr } = await common.spawnPromisified(process.execPath, [
226+
tmpdir.resolve('invalid-type-pkg/index.js'),
227+
]);
228+
229+
assert.ok(stderr.includes('MODULE_INVALID_TYPE'));
230+
assert.ok(stderr.includes('CommonJS'));
231+
});
232+
233+
it('should not warn for valid type values', async () => {
234+
tmpdir.refresh();
235+
236+
fs.mkdirSync(tmpdir.resolve('valid-type-pkg'), { recursive: true });
237+
fs.writeFileSync(
238+
tmpdir.resolve('valid-type-pkg/package.json'),
239+
JSON.stringify({ type: 'commonjs' })
240+
);
241+
fs.writeFileSync(
242+
tmpdir.resolve('valid-type-pkg/index.js'),
243+
'module.exports = 42;'
244+
);
245+
246+
const { stderr } = await common.spawnPromisified(process.execPath, [
247+
tmpdir.resolve('valid-type-pkg/index.js'),
248+
]);
249+
250+
assert.ok(!stderr.includes('MODULE_INVALID_TYPE'));
251+
});
252+
253+
it('should not warn when type field is missing', async () => {
254+
tmpdir.refresh();
255+
fs.mkdirSync(tmpdir.resolve('no-type-pkg'), { recursive: true });
256+
fs.writeFileSync(
257+
tmpdir.resolve('no-type-pkg/package.json'),
258+
JSON.stringify({ name: 'test' })
259+
);
260+
fs.writeFileSync(
261+
tmpdir.resolve('no-type-pkg/index.js'),
262+
'module.exports = 42;'
263+
);
264+
265+
const { stderr } = await common.spawnPromisified(process.execPath, [
266+
tmpdir.resolve('no-type-pkg/index.js'),
267+
]);
268+
269+
assert.ok(!stderr.includes('MODULE_INVALID_TYPE'));
270+
});
207271
});

0 commit comments

Comments
 (0)