1. 程式人生 > >nodejs之使用babel支援es6和pm2下使用babel

nodejs之使用babel支援es6和pm2下使用babel

nodejs之使用babel支援es6和pm2下使用babel

步驟一:安裝pm2

通過npm全域性模式安裝:

npm install -g pm2

步驟二:安裝babel相關模組

npm install --save babel-core
npm install --save babel-preset-env或者es2015
npm install babel-
cli -g

安裝完成之後,務必要在根目錄建立.babelrc檔案,內容如下:

{
    "presets": [
     "env"或者"es2015"
    ],
    "plugins": []
}

步驟三:測試babel是否能夠正常使用

1.建立一個Person.js,程式碼如下:

class Person{
    constructor(){
        this.name="haha"
    }
    get(){
        return this.name;
    }
}
export default Person;

2.建立一個app.js,程式碼如下:

import Person from './Person'
var express=require('express');
var app=express();
let person=new Person();
app.listen(4000,function(){
    console.log("開啟4000伺服器:",person.get())
})

3.執行app.js
使用node app.js
會拋異常:

import Person from './Person';
^^^^^^

SyntaxError: Unexpected token import
    at createScript
(vm.js:80:10) at Object.runInThisContext (vm.js:139:10) at Module._compile (module.js:616:28) at loader (E:\nvm\nvm\npm\node_modules\babel-cli\node_modules\babel-register\lib\node.js:144:5) at Object.require.extensions.(anonymous function) [as .js] (E:\nvm\nvm\npm\node_modules\babel-cli\node_modules\babel-register\lib\node.js:154:7) at Module.load (module.js:565:32) at tryModuleLoad (module.js:505:12) at Function.Module._load (module.js:497:3) at Function.Module.runMain (module.js:693:10) at Object.<anonymous> (E:\nvm\nvm\npm\node_modules\babel-cli\lib\_babel-node.js:154:22)

使用babel-node app.js
正常執行:

開啟4000伺服器: haha

但是我們在正規部署node伺服器的時候,往往會交給程序守護工具如pm2去管理我們的伺服器,所以怎麼讓pm2去使用babel-node執行我們的服務呢

步驟四:配置pm2

1.首先使用pm2 init 命令初始化檔案可得到pm2的ecosystem.config.js配置檔案,編輯ecosystem.config.js配置檔案如下:

module.exports = {
  /**
   * Application configuration section
   * http://pm2.keymetrics.io/docs/usage/application-declaration/
   */
  apps : [

    // First application
    {
      name      : 'API',
      script    : 'app.js',
      cwd:"./",
      log_date_format:"YYYY-MM-DD HH:mm:ss",
      out_file:"./logs/out-0.log",
      error_file:"./logs/err-0.log",
      watch:true,
      exec_interpreter:"babel-node",//此配置就是使用babel-node去執行nodejs檔案
      exec_mode:"fork",
      env: {
        COMMON_VARIABLE: 'true'
      },
      env_production : {
        NODE_ENV: 'production'
      }
    }
  ]

2.然後使用pm2 start ecosystem.config.js,執行node服務。

注:
但是本人測試不加入exec_interpreter:"babel-node"時,pm2能夠正常開啟,只是會拋不支援import的錯誤;加入exec_interpreter:"babel-node"後,會直接導致pm2執行錯誤。
所以貼上自己的解決方式
就是去掉pm2配置檔案的exec_interpreter:"babel-node"配置,在使用pm2 start ecosystem.config.js時加入–interpreter babel-node即:
執行

pm2 start ecosystem.config.js --interpreter babel-node

雖然pm2正常啟動,但是輸入pm2 logs 0檢視程序日誌時,發現又會丟擲無法識別import的錯誤。根據分析好像使用pm2結合babel-node啟動專案時,並不會自動找到.babelrc檔案。

3.解決辦法
(1)再建立一個server.js檔案
如下:

require('babel-register');
require('babel-polyfill');
require('./app')

注:
需要使用pm2安裝babel-polyfill模組,即:

npm install --save babel-polyfill

(2)修改ecosystem.config.js檔案
將script改為‘server.js’即:

module.exports = {
  /**
   * Application configuration section
   * http://pm2.keymetrics.io/docs/usage/application-declaration/
   */
  apps : [

    // First application
    {
      name      : 'API',
      script    : 'server.js',
      cwd:"./",
      log_date_format:"YYYY-MM-DD HH:mm:ss",
      out_file:"./logs/out-0.log",
      error_file:"./logs/err-0.log",
      watch:true,
      //exec_interpreter:"babel-node",
      exec_mode:"fork",
      env: {
        COMMON_VARIABLE: 'true'
      },
      env_production : {
        NODE_ENV: 'production'
      }
    },
  ]
};

(3)使用pm2啟動專案

pm2 start ecosystem.config.js --interpreter babel-node

這樣就可以正常啟動es6專案了。

總結

1.直接使用babel-node
使用babel-node去執行es6檔案時,並不需要加入server.js檔案,即並不需要引入’babel-register’和’babel-polyfill’模組,否則會丟擲:

throw new Error("only one instance of babel-polyfill is allowed");
  ^

Error: only one instance of babel-polyfill is allowed
    at Object.<anonymous> (E:\WebStormProject_2\seckill\Bable_Test\node_modules\babel-polyfill\lib\index.js:10:9)
    at Module._compile (module.js:652:30)
    at Module._extensions..js (module.js:663:10)
    at require.extensions.(anonymous function) (E:\nvm\nvm\npm\node_modules\babel-cli\node_modules\babel-register\lib\node.js:152:7)
    at Object.require.extensions.(anonymous function) [as .js] (E:\WebStormProject_2\seckill\Bable_Test\node_modules\babel-register\lib\node.js:152:7)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)
    at Function.Module._load (module.js:497:3)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)

意思是不能建立多個babel-polyfill例項。我們可以認為直接使用babel-node命令執行時,它會建立一個babel-polyfill例項去讀取.babelrc檔案。
2.使用pm2執行es6專案
除了pm2 start ecosystem.config.js --interpreter babel-node命令以外,需要引入’babel-register’和’babel-polyfill’模組,否則仍然會無法識別import等es6語法。
3.babel-polyfill 作用
因為babel只編譯語法,不編譯API,所以如果用到一些ES6的API需要引入該babel-polyfill模組。

例如:

Babel預設只轉換新的JavaScript句法(syntax),而不轉換新的API,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全域性物件,以及一些定義在全域性物件上的方法(比如Object.assign)都不會轉碼。

舉例來說,ES6在Array物件上新增了Array.from方法。Babel就不會轉碼這個方法。如果想讓這個方法執行,必須使用babel-polyfill,為當前環境提供一個墊片。