使用pkg打包Node.js應(yīng)用的方法步驟
Node.js應(yīng)用不需要經(jīng)過編譯過程,可以直接把源代碼拷貝到部署機(jī)上執(zhí)行,確實(shí)比C++、Java這類編譯型應(yīng)用部署方便。然而,Node.js應(yīng)用執(zhí)行需要有運(yùn)行環(huán)境,意味著你需要先在部署機(jī)器上安裝Node.js。雖說沒有麻煩到哪里去,但畢竟多了一個(gè)步驟,特別是對于離線環(huán)境下的部署機(jī),麻煩程度還要上升一級。假設(shè)你用Node.js寫一些小的桌面級工具軟件,部署到客戶機(jī)上還要先安裝Node.js,有點(diǎn)“大炮打蚊子”的感覺。更嚴(yán)重的是,如果部署機(jī)器上游多個(gè)Node.js應(yīng)用,而且這些應(yīng)用要依賴于不同的Node.js版本,那就更難部署了。
理想的情況是將Node.js打包為一個(gè)單獨(dú)的可執(zhí)行文件,部署的時(shí)候直接拷貝過去就行了。除了部署方便外,因?yàn)椴恍枰倏截愒创a了,還有利于保護(hù)知識產(chǎn)權(quán)。
將Node.js打包為可執(zhí)行文件的工具有pkg、nexe、node-packer、enclose等,從打包速度、使用便捷程度、功能完整性來說,pkg是最優(yōu)秀的。這篇文章就來講一講半年來我使用pkg打包Node.js應(yīng)用的一些經(jīng)驗(yàn)。
pkg的打包原理簡單來說,就是將js代碼以及相關(guān)的資源文件打包到可執(zhí)行文件中,然后劫持fs里面的一些函數(shù),使它能夠讀到可執(zhí)行文件中的代碼和資源文件。例如,原來的require('./a.js')會被劫持到一個(gè)虛擬目錄require('/snapshot/a.js')。
安裝
pkg既可以全局安裝也可以局部安裝,推薦采用局部安裝:
npm install pkg --save-dev
用法
pkg使用比較簡單,執(zhí)行下pkg -h就可以基本了解用法,基本語法是:
pkg [options] <input>
<input>可以通過三種方式指定:
1.一個(gè)腳本文件,例如pkg index.js;
2.package.json,例如pkg package.json,這時(shí)會使用package.json中的bin字段作為入口文件;
3.一個(gè)目錄,例如pkg .,這時(shí)會尋找指定目錄下的package.json文件,然后在找bin字段作為入口文件。
[options]中可以指定打包的參數(shù):
1.-t指定打包的目標(biāo)平臺和Node版本,如-t node6-win-x64,node6-linux-x64,node6-macos-x64可以同時(shí)打包3個(gè)平臺的可執(zhí)行程序;
2.-o指定輸出可執(zhí)行文件的名稱,但如果用-t指定了多個(gè)目標(biāo),那么就要用--out-path指定輸出的目錄;
3.-c指定一個(gè)JSON配置文件,用來指定需要額外打包腳本和資源文件,通常使用package.json配置。
使用pkg的最佳實(shí)踐是:在package.json中的pkg字段中指定打包參數(shù),使用npm scripts來執(zhí)行打包過程,例如:
{
...
"bin": "./bin/www",
"scripts": {
"pkg": "pkg . --out-path=dist/"
},
"pkg": {
"scripts": [...]
"assets": [...],
"targets": [...]
},
...
}
scripts和assets用來配置未打包進(jìn)可執(zhí)行文件的腳本和資源文件,文件路徑可以使用glob通配符。這里就浮現(xiàn)出一個(gè)問題:為什么有的腳本和資源文件打包不進(jìn)去呢?
要回答這個(gè)問題,就涉及到pkg打包文件的機(jī)制。按照pkg文檔的說法,pkg只會自動地打包相對于__dirname、__filename的文件,例如path.join(__dirname, '../path/to/asset')。至于require(),因?yàn)閞equire本身就是相對于__dirname的,所以能夠自動打包。假設(shè)文件中有以下代碼:
require('./build/' + cmd + '.js')
path.join(__dirname, 'views/' + viewName)
這些路徑都不是常量,pkg沒辦法幫你自動識別要打包哪個(gè)文件,所以文件就丟失了,所以這時(shí)候就使用scripts和assets來告訴pkg,這些文件要打包進(jìn)去。那么我們怎么知道哪些文件沒有被打包呢?難倒要一行行地去翻源代碼嗎?其實(shí)很簡單,只需要把打包好的文件運(yùn)行下,報(bào)錯(cuò)信息一般就會告訴你缺失哪些文件,并且pkg在打包過程中也會提示一些它不能自動打包的文件。
注意事項(xiàng)
如果說pkg還有哪兒還可以改進(jìn)的地方,那就是無法自動打包二進(jìn)制模塊*.node文件。如果你的項(xiàng)目中引用了二進(jìn)制模塊,如sqlite3,那么你需要手動地將*.node文件復(fù)制到可執(zhí)行文件同一目錄,我通常使用命令cp node_modules/**/*.node .一鍵完成。但是,如果你要跨平臺打包,例如在windows上打包linux版本,相應(yīng)的二進(jìn)制模塊也要換成linux版本,通常需要你手動的下載或者編譯。
那為什么pkg不能將二進(jìn)制模塊打包進(jìn)去呢?我猜想是require載入一個(gè)js文件和node文件,它們的機(jī)制是不一樣的。另外從設(shè)計(jì)來說,不自動打包二進(jìn)制模塊也是合理的,因?yàn)槎M(jìn)制模塊都是平臺相關(guān)的。如果我在windows上生成一個(gè)linux文件,那么就需要拉取linux版本的.node文件,這是比較困難的。并且有些二進(jìn)制模塊不提供預(yù)編譯版本,需要安裝的時(shí)候編譯,pkg再牛也不可能模擬一個(gè)其他平臺的編譯環(huán)境吧。nexe可以自動打包二進(jìn)制模塊,但是只能打包當(dāng)前平臺和當(dāng)前版本的可執(zhí)行文件。這意味著如果Node.js應(yīng)用引用了二進(jìn)制包,那么這個(gè)應(yīng)用就不能跨平臺打包了,所以我認(rèn)為這方面,nexe不能算是一個(gè)好的設(shè)計(jì)。
還有一點(diǎn)就是關(guān)于項(xiàng)目中的配置文件處理,比如數(shù)據(jù)庫連接參數(shù)、環(huán)境變量等。因?yàn)檫@些配置文件會跟著不同的部署環(huán)境進(jìn)行更改,所以為了方便更改,一般不希望把配置文件打包到exe。為了避免pkg自動地將配置文件打包到exe中,代碼中不要采用以下方式讀取配置文件:
fs.readFile(path.join(__dirname, './config.json')), callback)
而是采用相對于process.CWD()的方法讀取:
fs.readFile(path.join(process.CWD(), './config.json'), callback) // 或者
fs.readFile('./config.json', callback)
如果配置文件是js格式的,那么不要直接require('./config'),而是采用動態(tài)require:
const config = require(process.CWD() + './config')
另外要提及的是pkg打包之后動態(tài)載入js文件會有安全性問題,即用戶可以在js文件寫任何處理邏輯,注入到打包后的exe中。例如,可以讀取exe里面的虛擬文件系統(tǒng),把源代碼導(dǎo)出來。所以,盡量不要采用JS作為配置文件,也不要動態(tài)載入js模塊。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- webpack打包、編譯、熱更新Node內(nèi)存不足問題解決
- autojs的nodejs打包成品app經(jīng)驗(yàn)分享
- express搭建的nodejs項(xiàng)目使用webpack進(jìn)行壓縮打包
- Node.js打包管理工具NPM用法
- NodeJs使用webpack打包項(xiàng)目的方法詳解
- docker打包node項(xiàng)目的過程講解
- node app 打包工具pkg的具體使用
- webpack打包node.js后端項(xiàng)目的方法
- 用node-webkit把web應(yīng)用打包成桌面應(yīng)用(windows環(huán)境)
- 基于node打包可執(zhí)行文件工具_(dá)Pkg使用心得分享
- nodejs文件實(shí)現(xiàn)打包成exe, 并設(shè)置開機(jī)自啟動的方法詳解(沒有黑窗口)
相關(guān)文章
Nodejs?Sequelize手冊學(xué)習(xí)快速入門到應(yīng)用
這篇文章主要為大家介紹了Nodejs?Sequelize手冊學(xué)習(xí)快速入門到應(yīng)用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
Node.js調(diào)試技術(shù)總結(jié)分享
Node.js是一個(gè)可以快速構(gòu)建網(wǎng)絡(luò)服務(wù)及應(yīng)用的平臺。該平臺的構(gòu)建是基于Chrome's JavaScript runtime,也就是說,實(shí)際上它是對Google V8引擎(應(yīng)用于Google Chrome瀏覽器)進(jìn)行了封裝。 今天介紹Node.js調(diào)式目前有幾種技術(shù),需要的朋友可以參考下。2017-03-03
node.js應(yīng)用后臺守護(hù)進(jìn)程管理器Forever安裝和使用實(shí)例
這篇文章主要介紹了node.js應(yīng)用后臺守護(hù)進(jìn)程管理器Forever安裝和使用實(shí)例,forever可以看做是一個(gè)nodejs的守護(hù)進(jìn)程,能夠啟動,停止,重啟我們的app應(yīng)用,需要的朋友可以參考下2014-06-06
整理幾個(gè)關(guān)鍵節(jié)點(diǎn)深入理解nodejs
這篇文章主要介紹了整理幾個(gè)關(guān)鍵節(jié)點(diǎn)深入理解nodejs,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,需要的小伙伴可以參考一下,需要的小伙伴可以參考一下2022-07-07
詳解node如何將Excel導(dǎo)入數(shù)據(jù)庫
這篇文章主要為大家詳細(xì)介紹了node如何通過腳本實(shí)現(xiàn)將Excel導(dǎo)入mysql數(shù)據(jù)庫里,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2024-11-11

