When I'm sending a message from parent.js to child.js in commonJs syntax then it works. In parent.js I have
//parent.js
const cp = require('child_process');
let child = cp.fork('./child.js');
child.on('message', (message) =>{
console.log('Parent got message: ' message);
});
// parent sends a message
child.send('Parent sends message');
in child.js I have:
// child.js
process.on('message', (m) => {
console.log('child got message:', m);
process.send('child sends message');
});
everything works and in console I'm getting:
child got message: Parent sends message
Parent got message: child sends message
but it stops working when I use ES6 import syntax:
import * as cp from 'child_process';
Do I'm doing something wrong, or this is a nodejs bug?
My node version is 16.13.2 Under not working I mean cursor in terminal is blinking, but I'm not getting any message and I'm not getting any error.
CodePudding user response:
The import foo from 'foo'
syntax is only supported in ECMAScript Modules. The ECMAScript Modules (or ESM for short) have been supported (without experimental flag) from Node v12 onwards. However, NodeJS has traditionally used CommonJS (CJS) module format (const foo = require('foo');
). To support both formats and ensure interoperability between both of them, NodeJS requires you (the developer) to explicitly identify which of the two formats your file is in.
To indicate to NodeJS that your file is in ESM format, you can use one of the following options:
- Name your file with
.mjs
extension instead of.js
. By default, NodeJS treats all.js
files as CJS modules, only files named.mjs
are considered to be ES Modules. The files withimport ...
in your above example should be namedparent.mjs
&child.mjs
respectively. - Add
"type": "module"
in yourpackage.json
. This will make NodeJS consider all.js
files in your project as ES modules. Use this if all (or almost all) files in your project useimport ...
syntax. If you need to userequire('foo');
syntax in any file, it must be named with.cjs
extension instead. - Run node process with
--input-type=module
flag passing the code from STDIN. This option is impractical in most scenarios. Though you could use it by running:node --input-type="module" < parent.js
, note that file is not passed as argument here, only its contents are redirected to STDIN of node process.