由于编码兼容问题,某新平台不兼容旧平台的接口推送,我们找了个简单胶水方案:用nodejs开发程序做代理服务,并通过pkg把这些脚本编译成可执行文件(客户侧不能装nodejs和使用npm下载包)。
网上的教程不少,我就讲两点实用的经验:
- 配置packjson.js 执行pkg编译。
--output-path 可以指定编译文件的输出路径。可以利用这点写脚本指定编译文件指向生产路径。"scripts": { "pkg": "pkg ./src/app.js --out-path=dist/prod/", "pkg:simple": "pkg ./src/simple.js --out-path=dist/prod/" },
执行效果:
运行simpl-win.exe -
读取配置文件
光编译成可执行文件可不行,还得能读取外部配置文件,进行灵活配置,例如端口是设置在index.json中,日志的配置文件是在log/index.json中。
我们可以在config目录下建一个脚本index.js来读取这些json配置文件。这里要用到一个语法process.execPath,这样可以执行文件才能知道配置文件的正确路径。const path = require('path'); const { extend } = require('lodash'); const prodENVs = ['production','pkg']; // 公用的配置 let config = { env: "pkg", log: { options: { appenders: { cheese: { type: 'dateFile', filename: path.resolve(__dirname ,'../log/') + '/info', maxLogSize: 10485760, alwaysIncludePattern: true, pattern: 'yyyy-MM-dd.log' } }, categories: { default: { appenders: ['cheese'], level: 'error' } } } } } if (prodENVs.indexOf("pkg") === -1) { config.log.options.categories.default.level = 'debug' } if (prodENVs.indexOf("pkg") !== -1) { let localConfig = null; let logConfig = null; //关键语法 process.execPath //pkg编译成的执行文件有用到;普通nodejs执行 得到的是 nodejs.exe的路径。 //在程序启动后 加载配置文件 localConfig = require(path.resolve(path.dirname(process.execPath) ,'./config/index.json')); logConfig = require(path.resolve(path.dirname(process.execPath) ,'./config/log/index.json')); config.log.options = logConfig; //在程序启动后 配置日志的保存路径 config.log.options.appenders.cheese.filename= path.resolve(path.dirname(process.execPath) ,'./log/') + '/' + config.log.options.appenders.cheese.filename; // console.log(config.log.options.appenders.cheese.filename) config = extend(config, localConfig) } module.exports = config;
/* config/index.json的内容 */ { "port": 8000, "origin": null, "serverType": "http_only", "proxyurl": "http://192.168.1.156:8089/", "compress": true } /* config/log/index.json的内容 */ { "appenders": { "cheese": { "type": "dateFile", "filename": "info", "maxLogSize": 10485760, "alwaysIncludePattern": true, "pattern": "yyyy-MM-dd.log" } }, "categories": { "default": { "appenders": ["cheese"], "level": "info" } } }
但在app.js加载config/index.js文件时要require进来作为可执行文件的内部代码。注意是实际路径,不要用变量什么的,否则会出现加载文件失败的错误。const Koa = require("koa"); const http = require('http'); const log4js = require('log4js'); //配置 const config = require('./config/index.js'); const app =new Koa(); //日志 log4js.configure(config.log.options); const logger = log4js.getLogger('cheese'); app.use(async ctx => { ctx.body = 'Hello PKG & KOA' }); //监听http端口 http.createServer(app.callback()).listen(config.port); console.log(`HTTP Server is running on ${config.port}`); logger.info(`HTTP Server is running on ${config.port}`)
执行效果:
运行效果:
PKG的缺点 :对用来做控制翻转的js库 如awilix不支持---去访问 可以执行文件搭建的http服务 时返回的是404,但在nodejs环境下运行http服务却没问题。