pm2模块es6支持
2019年03月17日

概述

最近在使用es6的import/export写代码.根据ECMAScript标准的定义,以后会使用import/export进行模块的相关操作,而nodejs现存的require功能仅仅是一个内置方法.
所以为了尽早熟悉这种语法模式和相关部署,就尽早迁移了过来.

针对import/export目前发现的问题:

  1. 需要nodejs 6.0+
  2. 文件扩展名必须是.mjs
  3. require方法互斥,不能同时使用
  4. 该功能的实现还是实现性的,node需要--experimental-modules参数,才可以启用
  5. 该功能引入的模块,需要在代码的最顶层,无法嵌套
  6. 该功能只支持静态调用,动态调用需要import()方法(需要nodejs v10)
  7. 代码错误跟踪变得更模糊,希望能在后续改进

即便有以上这么多缺点吧,大多数项目还是能顺利的迁移过来,唯独rss builder,需要动态加载模块,而开发环境,无法安装nodejs v10,所以暂时没有迁移
运行命令:

node --experimental-modules main.mjs

但是在生产环境,采用pm2运行代码,就出现了问题.
普通的pm2启动命令:

pm2 start main.js

pm2的操作说明里,提到可以使用node_args参数,启用ES6支持:

pm2 start main.mjs --node-args="--experimental-modules"

或者使用config文件:

// cat app.config.js
module.exports = {
    apps: [{
        name: 'webauthn',
        script: 'main.mjs',
        node_args: '--experimental-modules',
        instances: 1,
        exec_mode: "fork",
        wait_ready: false,
        watch: false,
        listen_timeout: 8000,
        kill_timeout: 3000
    }]
}

但是都会提示如下错误:

# pm2 logs <NAME>
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: …

解决办法

后来参考网上的issue,解决办法如下:

  1. 安装esm模块
npm i esm --save
  1. 修改入口文件扩展名
mv main.mjs main.js
  1. 修改pm2启动命令
pm2 start main.js --node-args="-r esm"

或者使用config文件:

// cat app.config.js
module.exports = {
    apps: [{
        name: 'webauthn',
        script: 'main.js',
        node_args: '-r esm',
        instances: 1,
        exec_mode: "fork",
        wait_ready: false,
        watch: false,
        listen_timeout: 8000,
        kill_timeout: 3000
    }]
}
  1. 运行项目程序:
pm2 start app.config.js

参考链接

pm2 issue