欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用pkg打包ThinkJS項目的方法步驟

 更新時間:2019年12月30日 11:58:32   作者:公子  
這篇文章主要介紹了使用pkg打包ThinkJS項目的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

在 ThinkJS 的用戶群里,經(jīng)常有開發(fā)者提出需要對源碼進行加密保護的需求。我們知道 JavaScript 是一門動態(tài)語言,不像其他靜態(tài)語言可以編譯成二進制包防止源碼泄露。所以就出現(xiàn)了 pkg、nexe 之類的工具,支持將 JS 代碼連同 Node 一塊打包成一個可執(zhí)行文件,一來解決了環(huán)境依賴的問題,二來解決了大家關(guān)心的源碼保護的問題。

pkg 模塊的 README 中,羅列了它的幾大用處,如果你有下面的幾個需求的話建議不妨試試。

  • 為應(yīng)用提供商業(yè)發(fā)行版而不用暴露源碼
  • 為應(yīng)用提供 demo 而不用暴露源碼
  • 一鍵打包所有平臺可執(zhí)行文件而不需要對應(yīng)平臺環(huán)境依賴
  • 提供自解壓或自安裝的解決方案
  • 運行應(yīng)用不需要安裝 Node.js 和 npm
  • 部署僅需要一份單文件,不需要通過 npm 安裝大量的依賴
  • 資源打包后讓應(yīng)用遷移起來更加方便
  • 在指定 Node.js 版本下對應(yīng)用進行測試而不需要安裝對應(yīng)的版本

如何使用

關(guān)于 pkg 模塊的基礎(chǔ)使用,大家可以看 《把你的NodeJS程序給沒有NodeJS的人運行》 這篇文章。通過 npm install -g pkg 在全局安裝上模塊后就可以在命令行中使用 pkg 命令了。pkg 除了支持在命令行中指定參數(shù)之外,還支持在 package.json 中進行配置。

{
 ...
 "bin": "production.js",
 "scripts": {
  "pkg": "pkg . --out-path=dist/"
 },
 "pkg": {
  "scripts": [...]
  "assets": [...],
  "targets": [...]
 },
 ...
}

以上就是一個簡單的配置。bin 用來指定最終打包的入口文件,pkg.scripts 和 pkg.assets 用來指定除了入口文件之外需要打包進可執(zhí)行文件中的內(nèi)容,其中前者用來指定其他 .js 文件,后者用來指定非.js的資源。pkg.targets 則是用來指定需要打包的平臺,平臺名稱結(jié)構(gòu)如下,node${version}-${platform}-${arch}。version 用來指定具體 Node 的版本,platform 用來指定編譯的平臺,可以是 freebsd, linux, alpine, macos 或者 win,最后 arch 用來指定編譯平臺的架構(gòu),可以是 x64, x86, armv6 或者 armv7。例如 node10-macos-x64 表示的就是基于 Node 10 打包在 MacOS 平臺上執(zhí)行的可執(zhí)行程序。scripts, assets 和 targets 都支持數(shù)組配置多個。

將入口文件、依賴的腳本和資源、需要編譯的平臺配置好之后,執(zhí)行 npm run pkg 即可完成編譯。

如何打包 ThinkJS

pkg 的原理大概是提供一個虛擬的文件系統(tǒng),將 __filename, __dirname 等變量以及官方 API 中的 IO 操作方法指向本地文件系統(tǒng)的變量修改成指向虛擬系統(tǒng)。通過該虛擬文件系統(tǒng)讀取壓縮打包后的程序源碼,提供腳本執(zhí)行的環(huán)境。需要注意的是該虛擬文件系統(tǒng)是只讀的,所以如果程序中有基于 __dirname 進行讀寫操作的方法,需要規(guī)避規(guī)避掉。

代碼預處理

在 ThinkJS 項目中會有以下兩個地方有文件寫入操作:

  1. 項目啟動后會在 runtime/config/${env}.json 下寫入最終的配置文件
  2. 生產(chǎn)環(huán)境下默認會在 logs/ 目錄中寫入線上日志

這些目錄默認都是基于當前項目文件夾的,所以基于之前的理論都需要規(guī)避。pkg 的 README 中告訴我們 process.cwd() 還是會指向到真實的環(huán)境中,所以我們可以修改以上目錄的位置到 process.cwd() 來解決這個問題。

//pkg.js
const path = require('path');
const Application = require('thinkjs');

const instance = new Application({
 //在啟動文件中可以自定義配置 runtime 目錄
 RUNTIME_PATH: path.join(process.cwd(), 'runtime'), 
 ROOT_PATH: __dirname,
 proxy: true,
 env: 'pkg',
});

instance.run();

基于 production.js 我們新建一個 pkg.js 啟動文件,定義項目啟動后的 RUNTIME_PATH 路徑,并將 env 賦值為 pkg,方便后續(xù)的配置中通過 think.env === 'pkg' 來切換配置。

//src/config/adapter.js
const {Console, DateFile} = require('think-logger3');
const isDev = think.env === 'development';
const isPkg = think.env === 'pkg';
exports.logger = {
 type: isDev ? 'console' : 'dateFile',
 console: {
  handle: Console
 },
 dateFile: {
  handle: DateFile,
  level: 'ALL',
  absolute: true,
  pattern: '-yyyy-MM-dd',
  alwaysIncludePattern: true,
  filename: path.join(isPkg ? process.cwd() : think.ROOT_PATH, 'logs/app.log')
 }
};

在 adapter 配置中我們將原來基于 think.ROOT_PATH 的路徑修改成基于 process.cwd()。除了日志服務(wù)之外,如果業(yè)務(wù)中有使用到 cache 和 session 等服務(wù),它們?nèi)绻彩腔谖募鎯Φ脑?,也需要修改對?yīng)的文件存儲配置。當然這些都是 ThinkJS 自帶的一些服務(wù),如果項目中有用到其它的一些服務(wù),或者說本身的業(yè)務(wù)邏輯中有涉及到文件寫入的也都需要修改配置。

打包配置

項目的寫入操作規(guī)避掉之后我們就可以正常的配置 pkg 然后進行打包處理了。一份簡單的 pkg 模塊的配置大概是這樣的:

//package.json
{
 "bin": "pkg.js",
 "pkg": {
  "assets": [
   "src/**/*",
   "view/**/*",
   "www/**/*"
  ],
  "targets": [
   "node10-linux-x64",
   "node10-macos-x64",
   "node10-win-x64"
  ]
 }
}

這里我們指定了 pkg.js 為打包的入口文件,指定了需要編譯出 linux, macos, win 三個平臺的可執(zhí)行腳本,同時指定了需要將 src/, view/, www/ 三個目錄作為資源一塊打包進去。這是因為 ThinkJS 是動態(tài) require 的項目,具體的業(yè)務(wù)邏輯都是在執(zhí)行的時候通過遍歷文件目錄讀取文件的形式載入的,對于 pkg 模塊打包來說無法在編譯的時候知道這些依賴關(guān)系,所以需要作為啟動依賴的“資源”一塊打包進去。

配置好后直接在項目目錄下執(zhí)行 pkg .,如果一切 OK 的話應(yīng)該能在當前目錄中看到三個可執(zhí)行文件,直接執(zhí)行對應(yīng)平臺的二進制文件即可啟動服務(wù)了。

➜ www.thinkjs.org git:(master) npm run pkg-build

> thinkjs-official@1.2.0 pkg-build /Users/lizheming/workspace/thinkjs/www.thinkjs.org
> pkg ./ --out-path=dist

> pkg@4.4.0
➜ www.thinkjs.org git:(master) ✗ ls -alh dist
total 577096
drwxr-xr-x  5 lizheming staff  160B 12 28 17:35 .
drwxr-xr-x@ 30 lizheming staff  960B 12 28 17:34 ..
-rwxr-xr-x  1 lizheming staff  87M 12 28 17:34 thinkjs-official-linux
-rwxr-xr-x  1 lizheming staff  87M 12 28 17:35 thinkjs-official-macos
-rw-r--r--  1 lizheming staff  82M 12 28 17:35 thinkjs-official-win.exe
➜ www.thinkjs.org git:(master) ✗

后記

項目打包后有一個問題是配置沒辦法修改了,如果有動態(tài)配置的需求的話就不是很方便了。這里提供兩個思路解決該問題:

  1. 將動態(tài)的配置配置到環(huán)境變量中,程序通過讀取環(huán)境變量覆蓋默認的配置。
  2. 利用 ThinkJS 提供的 beforeStartServer() 鉤子在啟動前讀取真實目錄下的配置文件進行配置覆蓋。
//pkg.js
const path = require('path');
think.beforeStartServer(() => {
 const configFile = path.join(process.cwd(), 'config.js');
 const config = require(configFile);
 think.config(config);
});

另外隨著項目的復雜度提高,業(yè)務(wù)內(nèi)可能會引入大量的第三方模塊。前文只是解決了 ThinkJS 項目本身的動態(tài)引入問題,如果引入的第三方模塊也有動態(tài)引入的話也需要在 pkg.assets 配置中顯示指定出來。還有就是針對 C++ 模塊,pkg 目前還沒有辦法做到自動引入,同樣需要在 pkg.assets 中指定依賴資源。

//package.json
{
 "pkg": {
  "assets": [
   //以 node-sqlite3 模塊為例
   "node_modules/sqlite3/lib/binding/node-v64-darwin-x64/node_sqlite3.node"
  ]
 }
}

其中 node-v64-darwin-x64 可能會根據(jù)平臺不一樣導致名字不太一樣。無法引入 .node 模塊的原因是因為 C++ 模塊安裝的時候會通過 node-gyp 進行動態(tài)編譯,該操作是和平臺相關(guān)的。也就是說該特性和 pkg 模塊在一個平臺上能打包所有平臺的二進制包特性是沖突的,畢竟 pkg 模塊也沒辦法在 Mac 平臺上編譯 Windows 平臺的模塊。所以在這種情況下除了需要手動引入編譯后的 .node 模塊之外,還需要注意引入的該 .node 模塊和 pkg.targets 指定的編譯平臺的一致性。

獲取 .node 模塊除了在對應(yīng)平臺模塊安裝之外,也可以選擇下載其它同學提供編譯好的模塊。淘寶源上提供了很多二進制模塊的編譯后結(jié)果,以 node-sqlite3 為例,它的所有編譯模塊可以在 https://npm.taobao.org/mirrors/sqlite3這里下載,自行選擇對應(yīng)的版本和平臺即可。

本文說的打包配置都已在 ThinkJS 官網(wǎng) 項目中實現(xiàn),想要嘗試的同學可以直接克隆官網(wǎng)項目,安裝完依賴后執(zhí)行 npm run pkg-build 即可在 dist/ 目錄中獲得二進制可執(zhí)行文件。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論