本文由 @小劉 原創(chuàng)碗啄,轉(zhuǎn)載請(qǐng)注明出處。
? ? ? ?github示例地址:https://github.com/MrSmallLiu/pkg-egg-example
? ? ? ?打包Node.js代碼的工具有很多捡鱼,有些工具在打包時(shí)將自己寫的代碼打包為二進(jìn)制文件配合node_modules一起使用,有些工具將全部代碼打包為二進(jìn)制,個(gè)人比較偏向于全部打包,例如pkg馁龟,都可以支持express、koa等框架打包漆魔,但是對(duì)于將koa框架封裝后的Egg.js框架打包都沒有說明如何使用坷檩,我在多次嘗試后,加之閱讀一部分Egg.js源碼后終于利用pkg成功的打包有送。如下介紹如何利用pkg打包Egg.js代碼淌喻。
利用pkg打包Egg.js代碼
(上面嘟囔了一堆廢話僧家,終于步入正題雀摘。)
pkg是將整個(gè)工程打包為一個(gè)二進(jìn)制文件,包括node運(yùn)行環(huán)境一起打包八拱,非常方便遷移阵赠,而且不需要客戶環(huán)境重新部署Node.js以及下載相關(guān)依賴涯塔,具體步驟如下:
安裝pkg(參考pkg)
npm install pkg -g
配置Egg.js的public路徑。由于打包后為二進(jìn)制文件清蚀,對(duì)于某些用戶將前端代碼放在Egg.js工程目錄下的將不能操作匕荸,于是修改Egg.js的public路徑配置到運(yùn)行路徑下:
// 修改config/config.default.js
config.static = {
prefix: '/',
dir: process.cwd() + '/public'
}
配置Egg.js的運(yùn)行時(shí)路徑。由于Egg.js運(yùn)行時(shí)會(huì)生成run文件夾以及相關(guān)文件枷邪,而pkg打包后為二進(jìn)制文件榛搔,不能在繼續(xù)進(jìn)行寫操作,故將rundir配置到運(yùn)行路徑下:
//修改config/config.default.js
config.rundir = process.cwd() + '/run'
修改package.json配置pkg相關(guān)參數(shù):
- 將代碼以靜態(tài)文件方式添加到打包中:
//修改package.json东揣,增加pkg節(jié)點(diǎn)
"pkg": {
"assets": [
"./config/*.js",
"./app.js",
"./app/**/*.js",
"./node_modules/nanoid/**/*.js" //該行為必須添加践惑,由于Egg.js使用nanoid庫,其中用到一個(gè)文件pkg未能解析嘶卧,于是手動(dòng)添加
]
}
- 配置pkg入口:
// 修改package.json尔觉,增加bin節(jié)點(diǎn),指定入口文件
"bin": "build.js"
// build.js文件內(nèi)容
require(__dirname + '/node_modules/egg-scripts/bin/egg-scripts.js')
- 配置build命令
// 修改package.json,在scripts下增加build命令
"scripts": {
"build": "pkg . --targets node8-linux-x64 --out-path /usr/dist --debug"
}
// --targets 指定node版本為8以及l(fā)inux-x64
// --out-path 指定打包后文件輸出路徑
// --debug 指定debug模式編譯
開始打包
// 初次打包時(shí)間較長(zhǎng)芥吟,后續(xù)打包pkg會(huì)使用node緩存侦铜,提高打包效率
npm run build
運(yùn)行
./test_pkg start /snapshot/test_pkg --port=9001 --title=test_pkg
// ./test_pkg 打包后的二進(jìn)制文件
// /snapshot/test_pkg 其中/snapshot為必須路徑,test_pkg為工程目錄路徑
// --port --title等支持與平常啟動(dòng)時(shí)的任意命令參數(shù)
以上即完成了Egg.js的項(xiàng)目打包工作钟鸵,這時(shí)可能有人會(huì)想到數(shù)據(jù)庫相關(guān)配置怎么動(dòng)態(tài)來改變呢钉稍? C++編譯的模塊能否支持打包呢?棺耍,那請(qǐng)繼續(xù)閱讀嫁盲。
擴(kuò)展
如何支持動(dòng)態(tài)config
可能有人會(huì)想到利用Egg.js的啟動(dòng)周期來做呀,那么說對(duì)了烈掠,就是利用configWillLoad周期來做羞秤,在項(xiàng)目中創(chuàng)建app.js文件(如果已經(jīng)有的請(qǐng)忽略),利用周期讀取外部config.js左敌,然后替換config/config.default.js內(nèi)容瘾蛋,示例代碼如下:
// 替換sequelize的storage,替換dataPath路徑
var fs = require('fs');
class AppBootHook {
constructor(app) {
this.app = app;
}
configWillLoad() {
let customConfig = require(process.cwd() + '/config.js');
this.app.config.sequelize.storage = customConfig.dbPath;
this.app.config.dataPath = customConfig.dataPath;
}
}
module.exports = AppBootHook;
<font color=red>注意</font>
Node.js大部分用戶應(yīng)該都會(huì)使用sequelize矫限,而對(duì)于Egg.js使用egg-sequelize哺哼,由于egg-sequelize周期中包含agent.js,啟動(dòng)時(shí)讀取config/config.default.js叼风,會(huì)導(dǎo)致啟動(dòng)失敗取董,于是本人修改了一版egg-sequelize_pkg用于打包使用,除配置名稱差異外使用方法與egg-sequelize一致无宿,不需要修改原有代碼,如下配置更改即可
// {app_root}/config/plugin.js
exports.sequelizePkg = {
enable: true,
package: 'egg-sequelize_pkg',
};
// {app_root}/config/config.default.js
exports.sequelizePkg = {
};
github地址為:https://github.com/MrSmallLiu/egg-sequelize_pkg 歡迎提問題茵汰,也歡迎star
C++模塊引入
pkg介紹對(duì)于C++編譯的.node模塊,在打包時(shí)不會(huì)將其打包進(jìn)二進(jìn)制文件中孽鸡,故需要特殊處理蹂午,目前是修改源碼引用(各位有好的辦法可以推薦給我),然后將.node模塊拿到運(yùn)行目錄下:
- 修改node_modules中對(duì)應(yīng)模塊源碼的require二進(jìn)制文件的地方栏豺,將其修改為:
// 以node-sqlite3為例
將lib/sqlite3.js中的
var binding = require(binding_path);
修改為
var binding = require(process.cwd()+'/node_sqlite3.node')
- 將源碼中的node_sqlite3.node文件拷貝到編譯后的運(yùn)行目錄,將整個(gè)文件夾zip即可在任何地方運(yùn)行
以上介紹了如何利用pkg進(jìn)行打包Egg.js工程豆胸,如有疑問可以聯(lián)系作者或者下方評(píng)論奥洼,一起討論。
QQ: 1016817543 郵箱:1016817543@qq.com github:https://github.com/MrSmallLiu (歡迎star)