zoukankan      html  css  js  c++  java
  • PM2与Babel踩坑

    PM2与Babel踩坑

    PM2是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控、自动重启、负载均衡等,而且使用非常简单。官方文档 中文快速入门

    Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。官方文档 中文

    项目背景

    node服务,采用es6语法,import模块导入、async/await语法糖、箭头函数等等,以及koa-swagger-decorator自动生成swagger.json(api接口的注解,通过注解在swagger页面展现出每个api接口的详细描述)
    项目部署采用pm2,集群 + 环境区分(开发、测试、生产)

    babel

    如果使用koa-swagger-decorator,在github仓库中说明了使用时依赖babel-plugin-transform-decorators-legacy这个babel插件,但是This plugin is specifically for Babel 6.x. If you're using Babel 7, this plugin is not for you.(npm原话),如果你使用Babel7的话,你可以使用@babel/plugin-proposal-decorators, 但是在.babelrc中必须如下设置

    "plugins": [
        ["@babel/plugin-proposal-decorators", { "legacy": true }],
      ]
    

    好, 我们用babel-7.4.0试一下 安装babel依赖

    "dependencies": {
        "@babel/cli": "^7.4.4",
        "@babel/core": "^7.4.5",
        "@babel/plugin-proposal-decorators": "^7.4.4",
        "@babel/plugin-transform-runtime": "^7.4.4",
        "@babel/preset-env": "^7.4.5",
        "@babel/runtime": "^7.4.5",
        "@babel/runtime-corejs3": "^7.4.5",
        ...你的其他依赖
    }
    

    完整的.babelrc配置

    {
        "presets": [
            ["@babel/preset-env", {
                "targets": {"node": true},
                } 
            ]
        ],
        "plugins": [
        // 可以做到最小化加载babel-polyfill减小项目体积,虽然在node环境中无所谓
            ["@babel/plugin-transform-runtime", {
                "corejs": 3 // 可选 false | 2 | 3
            }],
            ["@babel/plugin-proposal-decorators", { "legacy": true }],
        ]
    }
    

    ok 通过上述的babel安装及.babelrc设置试一试转码

    • 入口文件app.js
    import config from './config'
    import eurekaServer from './eureka'
    import {connectDB} from './db'
    import Koa from 'koa';
    import router from './swagger/index'
    import responseHandler from './middleware/response_handle'
    import mqServer from './mq/MQServer'
    import cron from './cron'
    
    const koaCors = require('koa-cors');
    const koaBody = require('koa-body');
    const app = new Koa();
    async function initApp (){
        //连接mysql
        await connectDB();
        //连接mq
        await mqServer.connect();
        //启动Eureka
        await eurekaServer.start();
        //Eureka心跳
        app.use(eurekaServer.info()); 
        //启动定时拉取微信公众号图文及统计任务
        await cron();
        app.use(async function (ctx, next) {
            ctx.response.get("Access-Control-Allow-Origin", "*");
            ctx.response.set("Access-Control-Allow-Headers", "Content-Type,Content-Length,Accept,X-Requested-With,token");
            ctx.response.set("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
            if (ctx.request.method == "OPTIONS") ctx.response.status = 200;
            await next();
        })         
                
        //restful 中间件
        app.use(responseHandler.restify());
        app.use(koaCors());
        app.use(koaBody({ multipart: true }));
        app.use(router.routes());
        app.use(router.allowedMethods());
        app.listen(config.port, _ =>  console.log(`app started at port ${config.port}`));
        return app;
    }
    
    initApp()
    .catch(err => `未知服务错误:${err.message}`)
    
    
    • 项目目录
    
    src/
     'app.js',
     'config/',
     'controllers/',
     'cron/',
     'dao/',
     'db/',
     'domain/',
     'eureka/',
     'middleware/',
     'model/',
     'mq/',
     'repository/',
     'swagger/',
     'util/' 
     
    
    • 下一步 在package.json 中build
    
    "scripts": {
      "build": "babel src -d dist"
    },
    
    
    • 启动 node dist/app.js
    pan@ubuntu18:~/disk/panyanan/project/website_node$ node dist/app.js 
    加载local环境的配置文件成功
    sequelize deprecated The logging-option should be either a function or false. Default: console.log node_modules/sequelize/lib/sequelize.js:193:13
    Executing (default): SELECT 1+1 AS result
    connect MQ queues: {"queueNames":["q.upa_logs_node"],"connectOption":{"vhost":"OuterHost","hostname":"192.168.10.200","port":5672,"username":"admin","password":"123456"}}
    registered with eureka:  NTDWebsit/192.168.10.49:8989
    eureka注册成功
    koa deprecated Support for generators will be removed in v3. See the documentation for examples of how to convert old middleware https://github.com/koajs/koa/blob/master/docs/migration.md dist/app.js:47:7
    app started at port 8989
    
    

    用babel-6.0+试一下 安装依赖

    
     "dependencies": {
       "babel-cli": "^6.26.0",
       "babel-core": "^6.26.3",
       "babel-preset-env": "^1.7.0",
       "babel-plugin-transform-decorators-legacy": "^1.3.5",
       "babel-polyfill": "^6.26.0",
       ...其它依赖
       }
       
    

    .babelrc

    
    {
       "presets": [
           ["env", {
                   "targets": {"node": true},
                   //会加载所有polyfill
                   "useBuiltIns":true
               }
           ]
       ],
       "plugins": [
           "transform-decorators-legacy"
       ]
    }
    
    

    转码

    
    "scripts": {
    "build": "babel src -d dist"
      },
      
    

    bable6中转码过程会显示所有被转码的文件

    > selected@1.0.0 build /home/pan/disk/panyanan/project/website_node
    > babel src -d dist
    
    src/app.js -> dist/app.js
    src/config/config.dev.js -> dist/config/config.dev.js
    src/config/config.local.js -> dist/config/config.local.js
    src/config/config.pred.js -> dist/config/config.pred.js
    src/config/config.prod.js -> dist/config/config.prod.js
    src/config/index.js -> dist/config/index.js
    src/controllers/article_controller.js -> dist/controllers/article_controller.js
    src/controllers/category_controller.js -> dist/controllers/category_controller.js
    src/cron/articleTask.js -> dist/cron/articleTask.js
    src/cron/index.js -> dist/cron/index.js
    src/dao/article_dao.js -> dist/dao/article_dao.js
    src/dao/article_day_summary_dao.js -> dist/dao/article_day_summary_dao.js
    src/dao/category_dao.js -> dist/dao/category_dao.js
    src/db/index.js -> dist/db/index.js
    src/domain/article_domain.js -> dist/domain/article_domain.js
    src/domain/category_domain.js -> dist/domain/category_domain.js
    src/eureka/index.js -> dist/eureka/index.js
    src/middleware/response_handle.js -> dist/middleware/response_handle.js
    src/model/article_day_summary_model.js -> dist/model/article_day_summary_model.js
    src/model/article_model.js -> dist/model/article_model.js
    src/model/category_model.js -> dist/model/category_model.js
    src/mq/MQServer.js -> dist/mq/MQServer.js
    src/mq/UpalogsSendMsg.js -> dist/mq/UpalogsSendMsg.js
    src/repository/article_day_summary_repository.js -> dist/repository/article_day_summary_repository.js
    src/repository/article_repository.js -> dist/repository/article_repository.js
    src/repository/category_repository.js -> dist/repository/category_repository.js
    src/swagger/api.js -> dist/swagger/api.js
    src/swagger/index.js -> dist/swagger/index.js
    src/util/index.js -> dist/util/index.js
    
    

    启动 node dist/app.js

    pan@ubuntu18:~/disk/panyanan/project/website_node$ node dist/app.js 
    加载local环境的配置文件成功
    sequelize deprecated The logging-option should be either a function or false. Default: console.log node_modules/sequelize/lib/sequelize.js:193:13
    Executing (default): SELECT 1+1 AS result
    connect MQ queues: {"queueNames":["q.upa_logs_node"],"connectOption":{"vhost":"OuterHost","hostname":"192.168.10.200","port":5672,"username":"admin","password":"123456"}}
    registered with eureka:  NTDWebsit/192.168.10.49:8989
    eureka注册成功
    koa deprecated Support for generators will be removed in v3. See the documentation for examples of how to convert old middleware https://github.com/koajs/koa/blob/master/docs/migration.md dist/app.js:59:9
    app started at port 8989
    
    

    ok 以上就是在node服务中使用babel转码的尝试,babel中的配置及插件很多.设置起来也很麻烦,需要耐心的阅读官方文档,及前辈们的博客,总结一下基本概念.

    • babel-core 是babel的核心
    • babel-preset-env 是针对环境设置不同的转码规则
    • babel-polyfill,用于转码es6的api,比如Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise等全局对象,以及一些定义在全局对象上的方法(比如Object.assign)都不会转码。babel 默认只转换语法 如() => {}
    • babe-runtime可以做到按需转码,减少转码后的代码体积
    • 利用useBuiltIns选项,可以不必在代码中require(bable-polyfill)
    • 通过提前build的方式可以提高性能,相比之下 babel-node则很重,内存使用率很高
    • babel6/bable7的使用有很大不同,无论是.babelrc配置还是插件

    PM2

    pm2 基础命令可以看看官方文档
    这里说一下与babel相关的小坑,如果采用上面的build的方式是没有任何问题的,只需要修改配置文件的目录为转码之后的启动文件 apps.config.js

    pm2 start apps.config.js 启动
    如果设置env 则需要加上参数如 pm2 start apps.config.js --env prod
    则process.env.NODE_ENV == 'production'

    module.exports = {
      apps : [{
        name: 'websit_node',
        script: './dist/app.js',
        args: 'one two',
        instances: 1,
        autorestart: true,
        watch: false,
        max_memory_restart: '1G',
        env: {
          NODE_ENV: 'local'
        },
        env_dev: {
          NODE_ENV: 'development'
        },
        env_pred: {
          NODE_ENV: 'pred'
        },
        env_prod: {
          NODE_ENV: 'production'
        }
      }],
    };
    

    如果采用babel-node方式启动,则需要增加解释器配置

    module.exports = {
      apps : [{
        name: 'websit_node',
        script: './src/app.js',
        args: 'one two',
        instances: 1,
        autorestart: true,
        watch: false,
        max_memory_restart: '1G',
        interpreter: 'node_modules/babel-cli/bin/babel-node.js',
        env: {
          NODE_ENV: 'local'
        },
        env_dev: {
          NODE_ENV: 'development'
        },
        env_pred: {
          NODE_ENV: 'pred'
        },
        env_prod: {
          NODE_ENV: 'production'
        }
      }],
    };
    

    注意:

    • script字段则是未转码的项目入口文件,
    • interpreter字段,使用babe-node作为编译器执行script指定的入口文件,
    • babel-node启动的方式在pm2中不支持集群模式,就是说instances字段只能写1,而提前build的方式则没有这个限制.
  • 相关阅读:
    「UVA12293」 Box Game
    「CF803C」 Maximal GCD
    「CF525D」Arthur and Walls
    「CF442C」 Artem and Array
    LeetCode lcci 16.03 交点
    LeetCode 1305 两棵二叉搜索树中的所有元素
    LeetCode 1040 移动石子直到连续 II
    LeetCode 664 奇怪的打印机
    iOS UIPageViewController系统方法崩溃修复
    LeetCode 334 递增的三元子序列
  • 原文地址:https://www.cnblogs.com/pandapeter/p/11099251.html
Copyright © 2011-2022 走看看