在平時的小程序開發過程中,可能會遇到下面這些小問題,雖然不影響開發過程,但是開發體驗確會差一點,具體如下:
- 每次在編輯器中運行構建命令,第一次還需要手動打開微信開發者工具,打開指定項目
- 每次准備發布體驗版時,需要先在本地打包,等待打包完成,在開發者工具中點擊上傳代碼
那么怎么避免重復的操作,特別是比較頻繁的發布場景,可能每天需要多次的等待及上傳操作。
對於問題1,相信很多人想的,就是每次輸入命令時,微信開發者工具可以自動打開,並且可以打開當前指定的項目;對於問題2,每次輸入構建發布命令時,先執行打包操作,然后自動執行上傳操作,不需要人為等待打包結束已經人為點擊發布按鈕。
實現一個自動上傳功能
miniprogram-ci
官方發布的cli命令,不需要開發者工具,進行小程序代碼的上傳、預覽等操作等。網上這方面的文檔挺多的,不細說。
采用這個方法的,需要提供小程序的秘鑰與設置IP白名單,可能會存在一定的風險,比較適用於有獨立的打包發布平台,在指定機器上進行打包操作
nodejs實現自動上傳
其實,通過nodejs寫的腳本或者shell之類的,可以快速實現自動上傳的效果。核心原理就是通過child_process開啟一個多進程,在執行完打包命令后,運行官方提供的命令行V2,常見的API如下:
// 登錄
cli login
// 預覽
cli preview
// 上傳
cli upload
// 啟動開發者工具
cli open
相比miniprogram-ci,使用腳本的方式實現時,會依賴開發者工具,當微信開發者工具未登錄時,運行自動上傳命令會報錯,因此也添加了判斷未登錄時,會在命令行中生成二維碼,掃碼登錄即可。
同時,采用child_process不依賴任何三方包,每個人的電腦只要安裝node環境與微信開發者工具就行了
具體實現如下:
// upload.js
#!/usr/bin/env
const child = require('child_process');
const exec = child.execSync;
function getDays() {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const strDate = date.getDate();
const hours = date.getHours();
const minutes = date.getMinutes();
return `在${year}年${month}月${strDate}日${hours}點${minutes}分提交上傳`;
}
function getName() {
const arr = process.cwd().split('/');
return arr[2];
}
const branch = child.execSync('git name-rev --name-only HEAD', { encoding: 'utf8' });
const config = {
path: `/Applications/wechatwebdevtools.app/Contents/MacOS/cli`,
projectPath: `${process.cwd()}/dist`,
version: `1.2.1`,
desc: `${getName()}${getDays()},發布分支${branch}`,
};
exec('npm run build', { stdio: 'inherit' });
child.exec(
`${config.path} upload --project ${config.projectPath} -v ${config.version} -d ${config.desc}`,
{ stdio: 'inherit' },
(err, res) => {
if (res) {
exec(`${config.path} login --qr-size small`, { stdio: 'inherit' });
exec(
`${config.path} upload --project ${config.projectPath} -v ${config.version} -d ${config.desc}`,
{ stdio: 'inherit' }
);
}
}
);
// package.json
"scripts": {
"upload": "node upload.js"
}
使用shell的方式實現自動上傳
對於前端來說,平時寫shell可能不是特別多,但是它真的可以解決非常多的問題,非常的便捷。
平時寫shell,一般分兩種,直接寫shell,或者用三方包來寫,比較知名的有shelljs與zx。對於shelljs,其實是對child_process做了一層封裝,保證了多端語法一致性。而zx是Google出品的,語法更貼合前端。我們本次就是采用zx來實現。
// 全局安裝zx
sudo npm install -g zx
具體實現如下:
// upload.mjs
#!/usr/bin/env zx
function getDays() {
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const strDate = date.getDate();
const hours = date.getHours();
const minutes = date.getMinutes();
return `在${year}年${month}月${strDate}日${hours}點${minutes}分 提交上傳`;
}
const branch = await $`git branch --show-current`;
const config = {
path: `/Applications/wechatwebdevtools.app/Contents/MacOS/cli`,
projectPath: `${process.cwd()}/dist`,
version: `1.2.1`,
desc: `${getDays()},發布分支${branch}`,
};
await $`npm run build`;
await $`${config.path} upload --project ${config.projectPath} -v ${config.version} -d ${config.desc}`;
// package.json
"scripts": {
"upload": "zx upload.mjs"
}
自動打開開發者工具
// open.js
#!/usr/bin/env
const child = require('child_process');
const exec = child.execSync;
const path = '/Applications/wechatwebdevtools.app/Contents/MacOS/cli';
const projectPath = `${process.cwd()}/dist`;
child.exec('git branch --show-current', (err, res) => {
console.log('當前分支:', res);
});
child.exec(`${path} open --project ${projectPath}`, (err, res) => {
if (res) {
exec(`${path} login --qr-size small`, { stdio: 'inherit' });
exec(`${path} open --project ${projectPath}`, { stdio: 'inherit' });
exec('npm run dev', { stdio: 'inherit' });
} else {
exec('npm run dev', { stdio: 'inherit' });
}
});
// package.json
"scripts": {
"open": "node open.js"
}