Search code examples
javascriptecmascript-6ecmascript-2016

Different behavior between ES6 and ES2016 using babel on cluster.on


I am trying to use cluster to exploit the benefit of having multi-core CPUs. With code:

var cluster = require('cluster');

if (cluster.isMaster) {
    for(var i = 0; i < 2; ++i) {
        cluster.fork();
    }
    cluster.on('exit', function (worker) {
        console.log('Worker ' + worker.process.pid + ' exitted.');
    });
} else {
    console.log('Worker ' + cluster.worker.process.pid);
    process.exit(0);
}

node worked perfectly with output

Worker 14058
Worker 14064
Worker 14058 exitted.
Worker 14064 exitted.

However, when I tried to use import together with babel, I got problems:

import *  as cluster from 'cluster'

if (cluster.isMaster) {
    for(let i = 0; i < 2; ++i) {
        cluster.fork();
    }
    cluster.on('exit', (worker) => console.log('Worker ' + worker.process.pid + ' exitted.'));
} else {
    console.log('Worker ' + cluster.worker.process.pid);
    process.exit(0);
}

the output (after babel) of node is:

2.js:13
    cluster.on('exit', function (worker) {
            ^

TypeError: cluster.on is not a function
    at Object.<anonymous> (2.js:13:13)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.runMain (module.js:590:10)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:509:3
Worker 14140
Worker 14146

This looks weird. I am using node v6.4.0, with babel 6.11.4 (babel-core 6.13.2), the content of .babelrc is:

{
  "presets": ["es2016", "es2015"]
}

Any ideas what happened?


Solution

  • Ok, I figured out the reason, ref: Difference between import X and import * as X in node.js (ES6 / Babel)?

    The point is change import * as cluster from 'cluster' to import cluster from 'cluster'.

    With import * as cluster from 'cluster', everything that is exportable is exported into an object with name cluster, and it has structure:

    { domain: null,
      _events: {},
      _eventsCount: 0,
      _maxListeners: undefined,
      Worker: 
       { [Function: Worker]
         super_: 
          { [Function: EventEmitter]
            EventEmitter: [Circular],
            usingDomains: false,
            defaultMaxListeners: 10,
            init: [Function],
            listenerCount: [Function] } },
      isWorker: false,
      isMaster: true,
      workers: {},
      settings: {},
      schedulingPolicy: 2,
      SCHED_NONE: 1,
      SCHED_RR: 2,
      setupMaster: [Function],
      fork: [Function],
      disconnect: [Function],
      default: 
       EventEmitter {
         domain: null,
         _events: {},
         _eventsCount: 0,
         _maxListeners: undefined,
         Worker: { [Function: Worker] super_: [Object] },
         isWorker: false,
         isMaster: true,
         workers: {},
         settings: {},
         schedulingPolicy: 2,
         SCHED_NONE: 1,
         SCHED_RR: 2,
         setupMaster: [Function],
         fork: [Function],
         disconnect: [Function] } }
    

    On the other hand, when import cluster from 'cluster', the cluster object is the default export:

    EventEmitter {
      domain: null,
      _events: {},
      _eventsCount: 0,
      _maxListeners: undefined,
      Worker: 
       { [Function: Worker]
         super_: 
          { [Function: EventEmitter]
            EventEmitter: [Circular],
            usingDomains: false,
            defaultMaxListeners: 10,
            init: [Function],
            listenerCount: [Function] } },
      isWorker: false,
      isMaster: true,
      workers: {},
      settings: {},
      schedulingPolicy: 2,
      SCHED_NONE: 1,
      SCHED_RR: 2,
      setupMaster: [Function],
      fork: [Function],
      disconnect: [Function] }