企業(yè)網(wǎng)站建設(shè)相關(guān)書籍windows優(yōu)化大師卸載
零、寫在前面
HBuilderX是DCloud旗下的IDE產(chǎn)品,目前只提供了Windows和Mac版本使用。本項(xiàng)目組在開發(fā)階段經(jīng)常需要向測試環(huán)境提交熱更新包,使用Jenkins進(jìn)行CD是非常有必要的一步。盡管HBuilderX提供了CLI,但Jenkins服務(wù)通常都是搭建在Linux環(huán)境下的。當(dāng)前的Uniapp wgt打包服務(wù)是使用了Windows Server + HBuilderX CLI的解決方案來進(jìn)行打包,再用Jenkins遠(yuǎn)程調(diào)用接口。這套方案的弊病有如下幾點(diǎn):
- Jenkins側(cè)僅負(fù)責(zé)少量參數(shù)的傳遞,如項(xiàng)目名、Git repo地址、分支名等,大部分流程不受控制,流水線的構(gòu)建階段顯示不透明。
- 核心由一個(gè)shell script和一個(gè)python腳本實(shí)現(xiàn),代碼邏輯存在一定重復(fù),維護(hù)難度也比較高。
- 從Git更新代碼的流程耗費(fèi)較長時(shí)間,因?yàn)槊看螆?zhí)行流水線都要刪除掉本地的repo并重新拉取。這對于帶寬只有個(gè)位數(shù)的公網(wǎng)測試服務(wù)器來說是致命的,每次構(gòu)建花費(fèi)在此步的時(shí)間就有2分鐘以上。
- 后端平臺側(cè)獲取的Token沒有緩存,即使打包提速了也會受到驗(yàn)證碼獲取1分鐘節(jié)流的限制。
- Windows服務(wù)器上運(yùn)行的HBuilderX經(jīng)常出現(xiàn)登錄態(tài)失效或啟動打包任務(wù)失敗的情況,測試在Jenkins側(cè)只能得到簡單的任務(wù)失敗提示。而且這個(gè)提示是出現(xiàn)在Git拉取代碼之后的,意味著每次失敗前都要干等2分鐘。
為了避免服務(wù)器資源的浪費(fèi),節(jié)省不必要的維護(hù)開支,我決定在等待測試的gap期研究一下這套流程的優(yōu)(chong)化(gou)。
一、初次優(yōu)化-Windows下脫離HBuilderX主程序
打包指令提取
首先從Windows端下手,先打開HBuilderX并登錄賬號,正常打一個(gè)wgt包。在打包前使用DebugView
來查看HBuilderX執(zhí)行任務(wù)時(shí)的輸出,這是一款用于捕獲Windows桌面系統(tǒng)程序中由TRACE和OutputDebugString輸出的信息的工具。抓取到的有效日志如下:
[16764] 2023-05-16 09:50:20.583 [INFO:] node "D:/HBuilderX/plugins/node/node.exe"
[16764] 2023-05-16 09:50:20.583 [INFO:] args ("--max-old-space-size=2048", "--no-warnings", "D:/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/vite-plugin-uni/bin/uni.js")
盤一下uni.js
require('../dist/cli/index.js')
可以看到備注很完善的函數(shù)cli
,這證明Uniapp打包使用的工具就是由node
構(gòu)建的,原則上來說可以不受系統(tǒng)平臺的限制,移植到Linux上使用是沒有問題的。至于HBuilderX軟件本體就是Qt寫的一個(gè)殼子,只要剖析整個(gè)打包流程就可以脫離HBuilderX本體了。
cli.command('build').option('--outDir <dir>', `[string] output directory (default: dist)`).option('--assetsInlineLimit <number>', `[number] static asset base64 inline threshold in bytes (default: 4096)`).option('--sourcemap', `[boolean] output source maps for build (default: false)`).option('--manifest', `[boolean] emit build manifest json`).option('--ssrManifest', `[boolean] emit ssr manifest json`).option('--emptyOutDir', `[boolean] force empty outDir when it's outside of root`, {default: true,
}).option('-w, --watch', `[boolean] rebuilds when modules have changed on disk`).action(action_1.runBuild);
根據(jù)參數(shù)表整理一下調(diào)用命令:
node --max-old-space-size=2048 --no-warnings "D:/HBuilderX/plugins/uniapp-cli-vite/node_modules/@dcloudio/vite-plugin-uni/bin/uni.js" build --platform app --outDir "D:/test/crp-app-dist"
直接執(zhí)行上述命令是不行的,因?yàn)閡niapp的node_modules下根本就沒有編譯該工程所需的各種依賴,并且缺少很多環(huán)境變量。具體邏輯在uniapp-cli-vite/node_modules/@dcloudio/vite-plugin-uni
的/dist/cli/build.js
和/dist/index.js
中都有所表現(xiàn)。
顯而易見的是,我們的工程目錄下(非cli模式)根本就沒有vue
、pinia
之類的包,那么上面的命令是如何確定工作目錄(工程目錄)和其它依賴所在地的呢?先說其它依賴的問題,分析plugins
目錄可以看到HBuilderX自帶了一套node
和npm
,那么去看一下npm
的腳本(在Windows版本叫做npm.cmd
):
#!/bin/sh
(set -o igncr) 2>/dev/null && set -o igncr; # cygwin encoding fix
basepath=$(cd `dirname $0`; pwd)
plugin_dir=$(dirname $basepath)which "node" >/dev/null 2>&1
if ! [ $? -eq 0 ]; thennode_Path=$plugin_dir/nodenew_path=$PATH:$node_Pathexport PATH=$new_path
fi
$basepath/node_modules/npm/bin/npm-cli.js $@
環(huán)境變量修補(bǔ)
HBuilderX在打包階段會使用自己的node
和npm
,我們要做的就是修補(bǔ)環(huán)境變量使得這些工具都能找到正確的工作目錄。
查看打包前的環(huán)境變量也很簡單,既然調(diào)用棧是uniapp-cli-vite/node_modules/@dcloudio/vite-plugin-uni/bin/uni.js
,那么直接在uni.js
的尾部追加console.log(process.env)
后再次在HBuilderX里執(zhí)行打包,記錄控制臺輸出并去除無關(guān)的環(huán)境變量即可。
以下是一個(gè)使用node.js
成功在Windows
下脫離HbuilderX
主程序調(diào)用打包的例子:
/*** @author myd*/
import {exec} from "child_process";
import * as util from "util";
import path from "path";
import os from "os";const execAsync = util.promisify(exec);
export const build = (repoName: string) => {const systemTempFolderPath = os.tmpdir();return new Promise(async (resolve, reject) => {try {const HBUILDER_DIR = "D:\\HBuilderX";const UNI_INPUT_DIR = path.join(systemTempFolderPath, repoName);const VITE_ROOT_DIR = UNI_INPUT_DIR;const UNI_HBUILDERX_PLUGINS = path.join(HBUILDER_DIR, 'plugins');const UNI_CLI_CONTEXT = path.join(UNI_HBUILDERX_PLUGINS, 'uniapp-cli-vite');const UNI_NPM_DIR = path.join(UNI_HBUILDERX_PLUGINS, 'npm');const UNI_NODE_DIR = path.join(UNI_HBUILDERX_PLUGINS, 'node');const NODE_ENV: any = 'production';const NODE = path.join(UNI_NODE_DIR, 'node');const UNI_CLI = path.join(UNI_CLI_CONTEXT, 'node_modules', '@dcloudio', 'vite-plugin-uni', 'bin', 'uni.js');const PATH_ADDONS = process.env.PATH + `;${UNI_INPUT_DIR}/node_modules/.bin;`;const childEnv = {...process.env,PATH: PATH_ADDONS,HBUILDER_DIR,UNI_INPUT_DIR,VITE_ROOT_DIR,UNI_CLI_CONTEXT,UNI_HBUILDERX_PLUGINS,UNI_NPM_DIR,UNI_NODE_DIR,NODE_ENV,NODE};process.chdir(UNI_CLI_CONTEXT);const buildCommand = `"${NODE}" --max-old-space-size=2048 --no-warnings "${UNI_CLI}" build --platform app --outDir ${path.join(systemTempFolderPath, repoName + '-dist')}`const {stdout, stderr} = await execAsync(buildCommand, {env: {...childEnv}});console.error('stderr:', stderr);resolve(1)} catch (error) {console.error('Error during build:', error);reject(0)}})
}
產(chǎn)物是一個(gè)文件夾,把這個(gè)文件夾以zip
格式壓縮后,將后綴重命名為wgt
即可。
做到這一步后,我就用Next.js
寫了一個(gè)簡單的GUI,并配合一系列輔助邏輯完成了beta版的新構(gòu)建平臺,部署到先前的Windows服務(wù)器上提供給同事進(jìn)行測試。這樣做的目的主要是為了驗(yàn)證以上工作的正確性和穩(wěn)定性,還可以從反饋意見中思考一下我對于該流程的重構(gòu)設(shè)想是否正確,還有哪些點(diǎn)沒有考慮到。
二、第二次優(yōu)化-移植到Linux上并集成回Jenkins
思考
首先明確一點(diǎn),這件事本身就是一個(gè)內(nèi)部需求的解決方案延伸,閉門造車是不可取的。當(dāng)做出一個(gè)階段性的工作后,立刻部署demo并持續(xù)收集同事的反饋意見,及時(shí)調(diào)整,這樣才能避免后續(xù)的更多問題,因?yàn)樽罱K用戶不止是我本人,還有所有參與項(xiàng)目的其他同事。軟件的易用性和穩(wěn)定性同樣重要,必須在正式部署前反復(fù)地進(jìn)行預(yù)先測試才能推行使用。
在測試了一天后,同事認(rèn)為打包速度大大提高,但簡陋的web控制臺不能同時(shí)執(zhí)行多個(gè)打包任務(wù),打包期間不能刷新或離開頁面也是硬傷。當(dāng)時(shí)我還沒有想好如何把這套代碼搬到Linux上跑,因?yàn)檫@涉及HBuilderX的平臺差異問題。將這套代碼的構(gòu)建核心抽出來集成回Jenkins是最佳選擇,但我當(dāng)時(shí)是有一些偷懶的想法的,因?yàn)檫@套輪子也同樣提供了工程選擇、Git同步的處理邏輯等,已經(jīng)解決了上面的大部分痛點(diǎn)。但輪子畢竟是輪子,最終我還是決定放棄推行自己的平臺給大家使用的想法,而是以這個(gè)平臺作為測試工具,在此之上研究將HBuilderX的打包器遷移到Linux上的方法。
uniapp-cli-vite
承擔(dān)了大部分打包功能,按理說它作為一個(gè)node
包本來是不挑系統(tǒng)的。但我陷入了思維上的誤區(qū),一定要遷移node
和npm
再給plugins
搬家。實(shí)際上只要node
環(huán)境隔離得當(dāng),只遷移npm
即可。而對于npm
來說,Linux和Windows的npm
結(jié)構(gòu)差異較大,但幾乎可以直接使用macOS的包。所以遷移工作我選擇在macOS平臺下研究。
編寫腳本&部署
明確一下思路,只要在macOS下寫一個(gè)接受工程目錄的路徑、打包產(chǎn)物的路徑和HBuilderX plugins的路徑,輸出打包產(chǎn)物的腳本并測試成功,那么就算成功了80%了。把上面的node
函數(shù)用GPT轉(zhuǎn)成sh腳本,自己再微調(diào)一下:
#!/bin/bash# HBuilder目錄修改此處
HBUILDER_DIR=/root/HBuilderX
NODE_ENV=production
repoDir=$1
# 導(dǎo)出目錄修改此處
distExportDir=$2
# Nodejs修改此處
NODE=/root/HBuilderX/plugins/node/nodeUNI_INPUT_DIR="$repoDir"
VITE_ROOT_DIR="$UNI_INPUT_DIR"
UNI_HBUILDERX_PLUGINS="$HBUILDER_DIR/plugins"
UNI_CLI_CONTEXT="$UNI_HBUILDERX_PLUGINS/uniapp-cli-vite"
UNI_NPM_DIR="$UNI_HBUILDERX_PLUGINS/npm"
UNI_NODE_DIR="$UNI_HBUILDERX_PLUGINS/node"
UNI_CLI="$UNI_CLI_CONTEXT/node_modules/@dcloudio/vite-plugin-uni/bin/uni.js"export HBUILDER_DIR
export UNI_INPUT_DIR
export VITE_ROOT_DIR
export UNI_CLI_CONTEXT
export UNI_HBUILDERX_PLUGINS
export UNI_NPM_DIR
export UNI_NODE_DIR
export NODE_ENV
export NODE
export PATH="$PATH:$UNI_INPUT_DIR/node_modules/.bin"cd "$UNI_CLI_CONTEXT"
buildCommand="$NODE --max-old-space-size=2048 --no-warnings $UNI_CLI build --platform app --outDir $distExportDir/${repoDir}-dist"
eval $buildCommand
exitCode=$?
if [ $exitCode -eq 0 ]; thenecho "Build successful"exit 1
elseecho "Error during build"exit 0
fi
效果很好,先把HBuilderX的主目錄打包為tar并傳到Linux服務(wù)器上展開:
tar -cf ~/HbuilderX-3.9.5-darwin.tar /Applications/HBuilderX.app/Contents/HBuilderX
scp -P 22 -r ~/HbuilderX-3.9.5-darwin.tar root@192.168.1.252:/root/
tar -xf ./HbuilderX-3.9.5-darwin.tar
在macOS機(jī)器上看一下HBuilderX
使用的Node版本:
myd@myddeMac-Pro ~ % /Applications/HBuilderX.app/Contents/HBuilderX/plugins/node/node -v
v16.17.0
為Linux服務(wù)器下載對應(yīng)系統(tǒng)和架構(gòu)的Node二進(jìn)制包并覆蓋HBuilderX所使用的node,這里以Linux-amd64-16.17.0
為例:
wget https://nodejs.org/download/release/v16.17.0/node-v16.17.0-linux-x64.tar.gz
tar -xzvf ./node-v16.17.0-linux-x64.tar.gz
cp ./node-v16.17.0-linux-x64/bin/node ./HBuilderX/plugins/node
chmod +x ~/HBuilderX/plugins/node/node
更多版本可以在https://nodejs.org/download/release/
查看。
公司服務(wù)器的Ubuntu 18.04
缺少node 18的依賴glibc-2.28
,因此需要進(jìn)一步對系統(tǒng)環(huán)境進(jìn)行修補(bǔ)。編譯glibc-2.28
:
sudo apt-get install g++ make gcc bison
apt install -y gawk
cd ~
wget -c https://ftp.gnu.org/gnu/glibc/glibc-2.28.tar.gz
tar -zxf glibc-2.28.tar.gz
cd glibc-2.28
mkdir glibc-build
cd glibc-build
../configure --prefix=/opt/glibc-2.28
make -j 6
make install
cd ~
rm -rf ./glibc-2.28 ./glibc-2.28.tar.gz
apt install -y patchelf
# 直裝的node使用如下命令
patchelf --set-interpreter /opt/glibc-2.28/lib/ld-linux-x86-64.so.2 --set-rpath /opt/glibc-2.28/lib/:/lib/x86_64-linux-gnu/:/usr/lib/x86_64-linux-gnu/ /usr/local/bin/node
# nvm使用如下命令
patchelf --set-interpreter /opt/glibc-2.28/lib/ld-linux-x86-64.so.2 --set-rpath /opt/glibc-2.28/lib/:/lib/x86_64-linux-gnu/:/usr/lib/x86_64-linux-gnu/ /root/.nvm/versions/node/v18.18.2/bin/node
# 記得修補(bǔ)HBuilderX的node
patchelf --set-interpreter /opt/glibc-2.28/lib/ld-linux-x86-64.so.2 --set-rpath /opt/glibc-2.28/lib/:/lib/x86_64-linux-gnu/:/usr/lib/x86_64-linux-gnu/ ~/HBuilderX/plugins/node/node
接下來修改uniapp-cli-vite
的package.json
vi /root/HBuilderX/plugins/uniapp-cli-vite/package.json
刪除devDependencies
節(jié)點(diǎn)下的@esbuild/darwin-arm64
、@esbuild/darwin-x64
和fsevents
,并安裝對應(yīng)目標(biāo)平臺的esbuild
:
npm i -D -f @esbuild/linux-x64@0.17.19
npm i -f
領(lǐng)導(dǎo)非常支持這件事,抽出時(shí)間將上面的腳本集成回了Jenkins。我也將之前對于幾個(gè)痛點(diǎn)的思考和解決方案提供了出來,至此整個(gè)wgt打包流程得到了巨大的優(yōu)化,無論是速度還是穩(wěn)定性。
三、第三次優(yōu)化-封裝Docker進(jìn)行環(huán)境隔離
思考
在第二次優(yōu)化的過程中,因?yàn)槌隽诵扪a(bǔ)glibc
這檔子事,我意識到環(huán)境隔離非常重要。Ubuntu 18.04
作為LTS版本,至今仍在廣泛使用。這種不算特別老的系統(tǒng)尚且出現(xiàn)環(huán)境導(dǎo)致的兼容性問題,假如我要在一個(gè)使用musl
庫的發(fā)行版上部署,比如Alpine Linux
或者Gentoo Linux
的時(shí)候又該怎么辦呢?
顯然,解決這個(gè)問題的最好辦法就是封裝Docker鏡像。
精簡HBuilderX包
封裝Docker鏡像自然是產(chǎn)物體積越小越好。HBuilderX macOS版在安裝若干打包所需依賴后,主目錄膨脹到2個(gè)多G,這里的大多數(shù)文件都是用不上的。在macOS下復(fù)制一份HBuilderX主程序目錄,開搞:
- 只有plugins文件夾需要保留,HBuilderX主程序及其相關(guān)的文件完全用不上。刪之。
- plugins文件夾下的大部分包也用不上,比如為HBuilderX提供代碼補(bǔ)全、語法檢查之類的IDE所需包,或者項(xiàng)目中根本沒有使用到的UTS相關(guān)包,統(tǒng)統(tǒng)刪之。
- 每刪幾個(gè)包,就執(zhí)行一遍之前的sh構(gòu)建腳本,將HBuilderX目錄指向當(dāng)前魔改的目錄下,進(jìn)行可用性測試。
- 刪到最后,只留下
about
、complie-dart-sass
、node
、npm
、uniapp-cli-vite
與node_modules
這幾個(gè)目錄。 - 魯迅說過,
node_modules
的體積比珠穆朗瑪峰還要大,結(jié)構(gòu)比馬里亞納海溝還要深。提取出node_modules
目錄下的package.json
和package-lock.json
,復(fù)制到plugins
目錄下,再將node_modules
刪之。 - 根據(jù)上文的步驟,修改一下
uniapp-cli-vite
的package.json
。
精簡以后壓縮一下,原來2個(gè)多G的plugins只剩7.2M。將壓縮包命名為core-3.9.5.zip
備用。
Docker封裝前的思考和一些選擇
既然要做Docker鏡像,那么Docker鏡像的系統(tǒng)就最好選個(gè)輕量點(diǎn)的。Alpine Linux
只有50多M,采用APK
包管理器,是一個(gè)非常理想的選擇。然而必須注意的是,Alpine Linux
的libc實(shí)現(xiàn)使用的是musl
而非常用的glibc
。但我們既然是為了封裝HBuilderX的專屬鏡像,那nodejs版本理應(yīng)和原環(huán)境一樣,也就是v16.17.0
以保障兼容性,但是APK
包管理器只能下載latest版本的nodejs
,nodejs
又依賴于glibc
。從源碼編譯不太現(xiàn)實(shí),所以這里使用多階段構(gòu)建的方法,先通過nodejs
官方提供的node-alpine
來獲取可用的nodejs
二進(jìn)制文件,再進(jìn)行后續(xù)的操作。
至于封裝好的鏡像如何使用,我的解決方案是啟動一個(gè)小型的HTTP API
服務(wù)。為了減少不必要的依賴,這個(gè)服務(wù)也使用node
來寫。服務(wù)器應(yīng)該向鏡像掛載一個(gè)項(xiàng)目文件夾,通過API調(diào)用進(jìn)行打包。Git代碼同步之類的操作全部交給Jenkins側(cè)執(zhí)行,Docker容器只負(fù)責(zé)最核心的打包部分——如無必要,勿增實(shí)體。
編寫Dockerfile
以下是開發(fā)階段的Dockerfile:
ARG NODE_VERSION=16.17.1
ARG ALPINE_VERSION=3.18
FROM node:${NODE_VERSION}-alpine AS node
ARG ALPINE_VERSION
FROM alpine:${ALPINE_VERSION}
ENV API_SERVER_URL=https://gitclone.com/github.com/hbuilderx-vanilla/api-server.git# Set China APK Manager Mirrors
RUN echo "https://mirrors.aliyun.com/alpine/v3.18/main/" > /etc/apk/repositories \&& echo "https://mirrors.aliyun.com/alpine/v3.18/community/" >> /etc/apk/repositories
RUN apk update && apk add --no-cache bash unzip wget git# Install node-16.17.1
COPY --from=node /usr/lib /usr/lib
COPY --from=node /usr/local/lib /usr/local/lib
COPY --from=node /usr/local/include /usr/local/include
COPY --from=node /usr/local/bin /usr/local/bin# Set China NPM Mirrors
RUN npm install -g yarn --force \ && npm config set registry https://registry.npmmirror.com# Inject HBuilderX 3.9.5 core
COPY core-3.9.5.zip /opt/
RUN unzip /opt/core-3.9.5.zip -d /opt/ \&& rm /opt/core-3.9.5.zip && mkdir /projects# Install HBuilderX core dependencies
COPY core-install.sh /root/
RUN chmod +x /root/core-install.sh
# Need manual run it if minimal version
# RUN /root/core-install.sh# Install and start api server
WORKDIR /root
RUN git clone ${API_SERVER_URL} && \cd api-server && \npm i
EXPOSE 3000
CMD [ "node","/root/api-server/index.js" ]
我把HTTP API
服務(wù)單獨(dú)做了一個(gè)Git倉庫出來,這樣方便后續(xù)擴(kuò)充功能和進(jìn)行bugfix。在開發(fā)環(huán)境下,一些反向代理和鏡像源的設(shè)置是必不可少的。為了減少Docker鏡像體積,我選擇在鏡像運(yùn)行后再讓用戶手動安裝HBuilderX的巨型npm依賴。
容器的部署和初始化
容器啟動示例:
docker run -d --restart=always -v /<user_name>/<projects_folder>:/projects -p 13300:3000 --name hbuilder-vanilla flymyd114/hbuilderx-vanilla:latest
/<user_name>/<projects_folder>
是本機(jī)的待打包工程父目錄,你的所有工程均應(yīng)處于該目錄下,如/Users/myd/projects
下有hello-uniapp
文件夾。13300
為建議的API端口映射點(diǎn)。
容器首次啟動后,執(zhí)行如下命令以初始化依賴:
docker exec -it <docker_id> /bin/sh
chmod +x /root/core-install.sh && /root/core-install.sh
exit
訪問http://127.0.0.1:13300
以檢查API服務(wù)是否正確啟動。
打包示例:
curl --location 'http://localhost:13300/build?project=crp-app'
產(chǎn)物將會在/projects/crp-app/wgt-dist
中生成。
發(fā)布到Github上并編寫workflows
可以看到,上面的容器已經(jīng)被發(fā)布到了DockerHub。同樣的,我也將倉庫開源并編寫了workflows
以自動構(gòu)建新版本的Docker鏡像。以下是docker-build.yml
:
name: Build and Push Docker imageon:push:branches:- maintags:- 'v*'paths:- 'Dockerfile'workflow_dispatch:jobs:build-and-push:runs-on: ubuntu-lateststeps:- name: Check out the repouses: actions/checkout@v2- name: Set up Docker Buildxuses: docker/setup-buildx-action@v1- name: Log in to Docker Hubuses: docker/login-action@v1with:username: ${{ secrets.DOCKER_HUB_USERNAME }}password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}- name: Extract metadata (tags, labels) for Dockerid: metauses: docker/metadata-action@v3with:images: flymyd114/hbuilderx-vanillatags: |type=semver,pattern={{version}}- name: Build and push Docker imageuses: docker/build-push-action@v2with:context: .file: ./Dockerfilepush: truetags: ${{ steps.meta.outputs.tags }}labels: ${{ steps.meta.outputs.labels }}
當(dāng)main分支上的commit被打上形如v3.9.5
的Tag時(shí)即可觸發(fā)workflows
。當(dāng)然,也可以手動觸發(fā)這個(gè)構(gòu)建。
注意,在Github上發(fā)布的Dockerfile
應(yīng)該去除鏡像源和反代的部分,否則構(gòu)建速度反而會變慢:
ARG NODE_VERSION=16.17.1
ARG ALPINE_VERSION=3.18
FROM node:${NODE_VERSION}-alpine AS node
FROM alpine:${ALPINE_VERSION}
ENV API_SERVER_URL=https://github.com/hbuilderx-vanilla/api-server.gitRUN apk update && \apk add --no-cache bash unzip wget git && \rm -rf /var/cache/apk/*COPY --from=node /usr/lib /usr/lib
COPY --from=node /usr/local/lib /usr/local/lib
COPY --from=node /usr/local/include /usr/local/include
COPY --from=node /usr/local/bin /usr/local/bin
RUN npm install -g yarn --forceCOPY core-3.9.8.zip /opt/
RUN unzip /opt/core-3.9.8.zip -d /opt/ && \rm /opt/core-3.9.8.zip && \mkdir /projectsCOPY core-install.sh /root/
RUN chmod +x /root/core-install.sh# Need manual run it if minimal version
# RUN /root/core-install.shWORKDIR /root
RUN git clone ${API_SERVER_URL} && \cd api-server && \npm i
EXPOSE 3000
CMD [ "node","/root/api-server/index.js" ]
后續(xù)的版本升級
公司的項(xiàng)目目前統(tǒng)一使用HBuilderX 3.9.5的基座。但隨著未來的升級,我們也需要及時(shí)更新打包核心以兼容高版本基座。天下沒有不散的筵席,這篇文章既是我對這項(xiàng)工作的一個(gè)總結(jié)歸納,也是為后來人提供一個(gè)維護(hù)的文檔和應(yīng)對版本改變的思路。對于plugins
文件夾下的依賴來說,我們只需要在一臺電腦上將HBuilderX升級到想要的版本,然后提取里面的package.json
進(jìn)行依賴版本的替換就好。通常來說,要更新的package.json
涉及about
、uniapp-cli-vite
和根目錄。更新后重新將plugins
放到core
文件夾下打包,同步修改Dockerfile
內(nèi)的zip名即可。
以3.9.5升級至3.9.8舉例,修改core/plugins
內(nèi)的如下文件:
about/package.json
uniapp-cli-vite/package.json
package.json
然后壓縮core
文件夾,重命名為core-3.9.8.zip
。修改Dockerfile
:
COPY core-3.9.8.zip /opt/
RUN unzip /opt/core-3.9.8.zip -d /opt/ && \rm /opt/core-3.9.8.zip && \mkdir /projects
Github項(xiàng)目地址
Docker項(xiàng)目:https://github.com/hbuilderx-vanilla/docker
API項(xiàng)目:https://github.com/hbuilderx-vanilla/api-server
聯(lián)系我
郵箱:flymyd@foxmail.com
或在上方項(xiàng)目處提issue,@flymyd