這篇文章給大家介紹vscode中如何進(jìn)行微信小程序的發(fā)布,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
成都創(chuàng)新互聯(lián)專(zhuān)注為客戶(hù)提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、外貿(mào)網(wǎng)站建設(shè)、宜春網(wǎng)絡(luò)推廣、微信小程序、宜春網(wǎng)絡(luò)營(yíng)銷(xiāo)、宜春企業(yè)策劃、宜春品牌公關(guān)、搜索引擎seo、人物專(zhuān)訪、企業(yè)宣傳片、企業(yè)代運(yùn)營(yíng)等,從售前售中售后,我們都將竭誠(chéng)為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);成都創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供宜春建站搭建服務(wù),24小時(shí)服務(wù)熱線:13518219792,官方網(wǎng)址:www.cdcxhl.com
ok,既然都已經(jīng)大致理清楚流程了,那么擁有程序員嚴(yán)謹(jǐn)態(tài)度的我們,分析分析整個(gè)過(guò)程中需要用到的哪些能力?接下來(lái)我們只對(duì)每個(gè)環(huán)節(jié)關(guān)鍵的部分做一些分析和拆解,不做全盤(pán) Vscode 插件代碼的結(jié)構(gòu)和代碼分析。
前置工作
Git 能力- 切換分支
Git 能力 - 保存當(dāng)前分支
Vscode 插件 window 能力 - 輸入描述,下拉框選擇
Git 能力 - 拉取分支
選擇構(gòu)建分支,版本并填寫(xiě)描述
臨時(shí)保存當(dāng)前分支修改
切換到目標(biāo)分支
本地構(gòu)建
Git 調(diào)用能力- 使用 Git 來(lái)撤銷(xiāo)修改文件
Shell 調(diào)用能力 - 執(zhí)行構(gòu)建命令
Shell 調(diào)用能力- 修改文件內(nèi)容注入 AppID
微信開(kāi)發(fā)平臺(tái) api 能力- 獲取當(dāng)前 AppID 最近模板列表
自動(dòng)生成版本號(hào)
注入目標(biāo)小程序 AppID
運(yùn)行 uni-app 構(gòu)建命令
撤銷(xiāo)發(fā)布臨時(shí)修改文件
部署小程序
Dubbo 能力 - 由于后端已經(jīng)存在微信開(kāi)發(fā)平臺(tái) accessToken 能力,直接調(diào)用獲取
微信開(kāi)發(fā)平臺(tái) api 能力
微信開(kāi)發(fā)工具調(diào)用能力
上傳云端草稿箱
移動(dòng)到模板庫(kù)
部署預(yù)覽版
Vscode 插件的 window 能力是默認(rèn)就帶的不需要實(shí)現(xiàn),所以就 Shell 調(diào)用,Git 調(diào)用,Dubbo調(diào)用,微信開(kāi)發(fā)平臺(tái) api 調(diào)用,微信開(kāi)發(fā)工具調(diào)用需要實(shí)現(xiàn)。
再歸歸類(lèi),其實(shí) Git 調(diào)用,和微信開(kāi)發(fā)工具調(diào)用都是命令行調(diào)用也就是 Shell 調(diào)用,微信開(kāi)發(fā)平臺(tái) api 調(diào)用其實(shí)本質(zhì)就是 http 請(qǐng)求,但是里面最最重要的 accessKey 呢是直接調(diào)用政采云后端 Dubbo 接口獲取,所以才需要 Dubbo。下面看看大致怎么去做呢?
聽(tīng)到 Shell 菊花一緊,不熟悉的人覺(jué)得天哪很復(fù)雜的樣子,其實(shí)就是使用 child_process
去開(kāi)一個(gè)子進(jìn)程,然后你就快樂(lè)的玩耍吧。所以我們?cè)陧?xiàng)目中封裝了一個(gè) shell.ts 來(lái)做所有 Shell 腳本的執(zhí)行動(dòng)作。 不熟悉child_process
的請(qǐng)移步這里
// shell.ts 部分核心代碼 import { execFile, ExecFileOptions } from "child_process"; export namespace Shell { // 在 shell 中直接調(diào)用 git 的執(zhí)行文件執(zhí)行原始命令 export async function exec( args: any[], options: ExecFileOptions = {} ): Promise { const { stdin, stdinEncoding, execFileNameOrPath, ...opts }: any = { maxBuffer: 100 * 1024 * 1024, ...options, }; return new Promise ((resolve, reject) => { if (!execFileNameOrPath) { reject('error'); } try { const proc = execFile( execFileNameOrPath, args, opts, (error: any | null, stdout, stderr) => { if (error != null) { reject(error); return; } resolve( stdout as TOut ); } ); if (stdin !== null) { proc.stdin?.end(stdin, stdinEncoding ?? "utf8"); } } catch (e) { return } }); } }
然后就可以通過(guò) Shell.exec 方法傳入?yún)?shù)就能直接調(diào)用了
有了上一個(gè) Shell 作為基礎(chǔ)我們就可以開(kāi)干 Git 的調(diào)用了,在 Shell 中第一個(gè)參數(shù)是命令的執(zhí)行文件,所以我們需要得到當(dāng)前的 Git 的執(zhí)行文件的地址作為第一個(gè)參數(shù),后面其實(shí)就是正常的 Git 命令的拼接就夠了。那么怎么知道當(dāng)前 Git 的執(zhí)行文件路徑呢?
通過(guò) Vscode 插件中集成的 Git 能力去得到 extensions.getExtension("vscode.git")
,如下方式
// 獲取 Vscode 內(nèi)置的 Git Api static async getBuiltInGitApi(): Promise{ try { const extension = extensions.getExtension("vscode.git") as Extension< GitExtension >; if (extension !== null) { const gitExtension = extension.isActive ? extension.exports : await extension.activate(); return gitExtension.getAPI(1); } } catch {} return undefined; }
在返回的對(duì)象中 gitApi.git.path
就是 Git 的執(zhí)行文件路徑。為了更加方便的調(diào)用,我們也封裝了一個(gè) git.ts 作為 Git 最最核心最最基礎(chǔ)的調(diào)用
//git.ts 的部分核心代碼 export namespace Git { export namespace Core { // 在 shell 中直接調(diào)用 git 的執(zhí)行文件執(zhí)行原始命令 export async function exec( args: any[], options: GitExecOptions = {} ): Promise { options.execFileNameOrPath = gitInfo.execPath || ""; args.splice(0, 0, "-c", "core.quotepath=false", "-c", "color.ui=false"); if (process.platform === "win32") { args.splice(0, 0, "-c", "core.longpaths=true"); } return Shell.exec(args, options); } }
在外部我們直接用 Git.Core.exec 方法直接執(zhí)行對(duì)應(yīng)的 Git 命令
首選我們要先檢查開(kāi)發(fā)者工具設(shè)置:需要在開(kāi)發(fā)者工具的設(shè)置 -> 安全設(shè)置中開(kāi)啟服務(wù)端口。這樣我們才能直接喚起開(kāi)發(fā)者然后做些我們要做的事情。
再者我們需要知道微信開(kāi)發(fā)者工具的執(zhí)行文件地址。 詳細(xì)請(qǐng)移步文檔
macOS: <安裝路徑>/Contents/MacOS/cli
windows: <安裝路徑>/cli.bat
正常來(lái)說(shuō) Mac 地址 /Applications/wechatwebdevtools.app/Contents/MacOS/cli
最后通過(guò)我們以前提供的 Shell 命令能力去執(zhí)行就搞定了。是不是很簡(jiǎn)單。我們也封裝了miniProgram.ts 來(lái)做這個(gè)事情
//miniProgram.ts 核心代碼 import { ExecFileOptions } from "child_process"; import * as vscode from "vscode"; import { Shell } from '../shell'; interface MiniProgramExecOptions extends ExecFileOptions { branchName: string; execFileNameOrPath: string; projectPath: string, userVersion: string, userDesc: string } export namespace MiniProgram { export namespace Core { // 在 shell 中直接調(diào)用 git 的執(zhí)行文件執(zhí)行原始命令 export async function exec( args: any[], options: MiniProgramExecOptions ): Promise { vscode; options.execFileNameOrPath = "/Applications/wechatwebdevtools.app/Contents/MacOS/cli"; return Shell.exec(args, options); } } }
不明覺(jué)厲,都直接調(diào) Dubbo 了吊的不行,其實(shí)很簡(jiǎn)單,有一個(gè) nodeJs 的庫(kù) node-zookeeper-dubbo
再配合 js-to-java
這兩個(gè)庫(kù)就能搞定,只不過(guò)一些配置比較麻煩,我就把代碼大致的貼出來(lái)
const nzd = require("node-zookeeper-dubbo"); const j2j = require("js-to-java"); export interface DubboInstance { mp: { getComponentToken: Function; }; } export class DubboService { private _dubbo: DubboInstance; public get dubbo(): DubboInstance { return this._dubbo; } constructor() { const options = { application: "你的項(xiàng)目名稱(chēng)", //項(xiàng)目名稱(chēng) register: "你的 () => [], }, }, }, java: j2j, //使用 js-to-java 庫(kù)來(lái)簡(jiǎn)化傳遞給 java 后端的值的寫(xiě)法 }; this._dubbo = new nzd(options); } }
至此一些基本能力已經(jīng)封裝的差不多了
Shell:Shell.exec 方法
Git:Git.Core.exec 方法
微信開(kāi)發(fā)工具: MiniProgram.Core.exec 方法
Dubbo: DobboService.dubbo.mp 方法
因?yàn)槲覀円獦?gòu)建一個(gè)預(yù)發(fā)版,所以很有可能我們需要構(gòu)建的分支不是我們當(dāng)前工作的分支,所以這步驟的話更多的是要做好一些構(gòu)建前的一些準(zhǔn)備工作,總不能因?yàn)槿思覝y(cè)試要一個(gè)預(yù)覽測(cè)試版然后一不小心把我們自己本地的辛辛苦苦開(kāi)發(fā)的東西弄沒(méi)了吧,那真的是 f**k 了。
根據(jù)流程我們先來(lái)分解下大致的技術(shù)動(dòng)作
臨時(shí)保存當(dāng)前分支修改
獲取當(dāng)前分支。
如果是在當(dāng)前分支啥都不管,否則 stash 下
切換到需要發(fā)布分支
切換下分支
再精簡(jiǎn)下: 獲取當(dāng)前分支---> 保存修改--> 切換分支。 都是 Git 的一些動(dòng)作。那么在 nodeJs 中怎么開(kāi)始自己的 Git 表演呢?一個(gè)關(guān)鍵點(diǎn):Shell 腳本和命令的調(diào)用,所以這里的本質(zhì)是調(diào)用 Shell。我們?cè)谏蟼€(gè)章節(jié)中已經(jīng)實(shí)現(xiàn)的 Shell 和 Git 的基本能力了,我們直接調(diào)用就行了。
其實(shí) Git 的命令分為兩種
高層命令(porcelain commands)
底層命令(plumbing commands)
常用的命令大家都很熟悉了,什么 branch 啊, init 啊,add 啊,commit 啊等等。底層命令又是什么鬼,其實(shí)所有的高層命令的本質(zhì)都是會(huì)調(diào)用底層命令,可以類(lèi)比為語(yǔ)言層面 Java,C#,Js 這些高級(jí)語(yǔ)言他的底層是使用 C 或者 C++ 是一個(gè)概念。 有興趣請(qǐng)移步
symbolic-ref 命令能干嘛呢?
給定一個(gè)參數(shù),讀取哪個(gè)分支頭部給定的符號(hào) ref 引用并輸出其相對(duì)于 .git/
目錄的路徑。通常,HEAD
以 參數(shù)的形式提供您的工作樹(shù)所在的分支。
有了上面 git.ts 支持基本能力那么現(xiàn)在我們就很簡(jiǎn)單多了,Git.Core.exec
在 git.ts 中增加基本命令方法
// git.ts 部分代碼 export function symbolicRef(options: GitExecOptions = {}) { return Core.exec(["symbolic-ref", "--short", "HEAD"], options); }
在 gitService 中實(shí)現(xiàn) getCurrentBranch 方法
// gitService.ts 部分代碼 public async getCurrentBranch(filePath: string): Promise{ const branchName = await Git.Cmd.symbolicRef({ cwd: filePath }); return branchName.replace(/\n/g, ""); }
當(dāng)我們獲取到當(dāng)前分支之后,和我們目標(biāo)分支進(jìn)行比對(duì)如果一致的話直接跳過(guò)該步驟,否則就需要對(duì)當(dāng)前分支保存并且切換了。
為了方便對(duì)于保存和切換我們直接用了Git 的 stash 和 checkout 命令,并且封裝了兩個(gè)方法。
// git.ts 部分代碼 export function checkout(options: GitExecOptions = {}) { const params = [ "checkout" ]; if (options.branchName) { params.push(options.branchName); }else if(options.fileName){ params.push('--',options.fileName); } return Core.exec(params, options); } export function stash(options: GitExecOptions = {}) { const params = [ "stash" ]; if (options.stashPop) { params.push('pop'); } return Core.exec (params, options); }
繼續(xù)分析下本地構(gòu)建的基本流程
大致分以下幾步
自動(dòng)生成版本號(hào)
得到當(dāng)前 AppID 在微信模板庫(kù)中版本號(hào)情況
注入需要發(fā)布的小程序 AppID
需要修改 src/manifest.json 文件中 AppID,方便開(kāi)發(fā)工具上傳使用
運(yùn)行 uni-app 構(gòu)建命令
run uniapp 命令
撤銷(xiāo)發(fā)布時(shí)候的臨時(shí)文件修改
撤銷(xiāo)文件修改
能力上來(lái)說(shuō)有那么幾個(gè)
微信 api 調(diào)用
文件讀取和修改能力
Shell 命令執(zhí)行能力
撤銷(xiāo)文件修改能力
首先怎么調(diào)用微信的 api,由于那時(shí)候我們親愛(ài)的后端同學(xué)啃次啃次的已經(jīng)吧微信 token 鑒權(quán)的能力已經(jīng)做掉了,所以我們直接接后端的微信鑒權(quán)能力就可以了。但是怎么接又是個(gè)問(wèn)題,雖然人家已經(jīng)有個(gè) restful 接口可以用,但是接口都要登錄的啊,讓人家為了我這個(gè)小小的需求弄個(gè)匿名的不大現(xiàn)實(shí)也不安全,想來(lái)想去那就不要用 restful 了,直接調(diào)他后面提供的 Dobbo 服務(wù)好了,完美。
在獲取微信 api 調(diào)用前我們需要先得到 accessToken。
所以我們會(huì)先用一個(gè)公共方法先去獲取當(dāng)前 accessToken, 然后在去請(qǐng)求微信開(kāi)發(fā)平臺(tái) api。
// miniProgramService.ts 部分代碼 public async retrieveWxToken(): Promise{ if (!Launcher.dobboService.dubbo.mp) { throw new Error("dubbo初始化錯(cuò)誤"); } const { success: dobboSuccess, error, result: wxToken, } = await Launcher.dobboService.dubbo.mp.getComponentToken(); if (!dobboSuccess) { throw new Error(`dubbo調(diào)用失敗:${error}`); } console.log("wxToken:", wxToken); return wxToken; }
如果你們的后端沒(méi)有支持微信開(kāi)發(fā)平臺(tái)的鑒權(quán)能力的話就需要自己用 nodejs 方式去實(shí)現(xiàn)了,具體的微信開(kāi)放平臺(tái)文案請(qǐng)移步
其實(shí)微信開(kāi)放平臺(tái) api 調(diào)用就是正常的 http 調(diào)用即可。
微信提供了一系列方法,對(duì)于我們這次的場(chǎng)景來(lái)說(shuō)有如下接口
getTemplateList 獲取模板列表
POST https://api.weixin.qq.com/wxa/gettemplatelist?access_token==ACCESS_TOKEN
addtotemplate 移動(dòng)草稿到模板庫(kù)
POST https://api.weixin.qq.com/wxa/gettemplatelist?access_token=ACCESS_TOKEN
deleteTemplate 刪除指定模板
POST https://api.weixin.qq.com/wxa/deletetemplate?access_token=ACCESS_TOKEN
getTemplateDraftList 獲取草稿箱列表
https://api.weixin.qq.com/wxa/gettemplatedraftlist?access_token=ACCESS_TOKEN
具體的微信開(kāi)放平臺(tái)文案請(qǐng)移步
版本號(hào)的自動(dòng)生成主要是通過(guò)在你點(diǎn)擊發(fā)布時(shí)候通過(guò)讓用戶(hù)選擇發(fā)布的版本為“大版本”,“功能迭代”還是“補(bǔ)丁修復(fù)”,在結(jié)合這里提到的獲取當(dāng)前模板列表并用 AppID 找到當(dāng)前最近的版本號(hào)再做自動(dòng)計(jì)算累加的方式得到這次發(fā)布的版本號(hào)。
構(gòu)建小程序這邊就直接沿用 uni-app 的能力直接做構(gòu)建。封裝了如下方法去構(gòu)建小程序
//miniProgramService.ts 部分代碼 public async buildMPForLocal(env: string): Promise{ let buildEnv; switch (env.toUpperCase()) { case "PROD": buildEnv = EnvEnum.prod; break; case "STAGING": buildEnv = EnvEnum.staging; break; case "TEST": buildEnv = EnvEnum.test; break; default: buildEnv = EnvEnum.dev; break; } const args = `./node_modules/.bin/cross-env NODE_ENV=production DEPLOY_ENV=${buildEnv} UNI_PLATFORM=mp-weixin ./node_modules/.bin/vue-cli-service uni-build`.split(' '); //正常需要這樣傳入 shell 參數(shù)才行 //[ // 'NODE_ENV=production', // 'DEPLOY_ENV=staging', // 'UNI_PLATFORM=mp-weixin', // './node_modules/.bin/vue-cli-service', // 'uni-build' //] const options: MPExecOptions = { execFileNameOrPath: 'node', cwd: getWorkspacePath() }; return Shell.exec(args, options); }
其余的功能
剩余文件讀取就正常使用 fs 庫(kù)的 readFileSync 方法去讀取和修改
撤銷(xiāo)修改文件則是通過(guò)調(diào)用 Git 的 checkout 命令的能力去做,也是要使用上一章節(jié)的 Git 的基本能力調(diào)用
我們 build 完成了,怎么上傳呢?微信小程序這塊還是需要借助微信開(kāi)發(fā)工具的能力來(lái)上傳
首選我們要先檢查開(kāi)發(fā)者工具設(shè)置:需要在開(kāi)發(fā)者工具的設(shè)置 -> 安全設(shè)置中開(kāi)啟服務(wù)端口。這樣我們才能直接喚起開(kāi)發(fā)者然后做些我們要做的事情。
再者我們需要知道微信開(kāi)發(fā)者工具的執(zhí)行文件地址。正常來(lái)說(shuō) Mac 地址
/Applications/wechatwebdevtools.app/Contents/MacOS/cli
最后通過(guò)我們以前提供的 Shell 命令能力去執(zhí)行就搞定了。是不是很簡(jiǎn)單。我們也封裝了miniProgram.ts 來(lái)做這個(gè)事情
// miniProgram.ts 核心代碼 export namespace Cmd { export function uploadMP(options: MiniProgramExecOptions) { const args = [ 'upload', '--project', options.projectPath, '-v', options.userVersion, '-d', options.userDesc, ]; return Core.exec(args, options); } } }
其余的功能
移動(dòng)到模板庫(kù)和部署預(yù)覽版直接調(diào)用微信開(kāi)放平臺(tái) api 即可
效果預(yù)覽圖:
至此整個(gè)小程序部署的在 Vscode 插件中實(shí)現(xiàn)的幾個(gè)關(guān)鍵的技術(shù)點(diǎn)已經(jīng)逐一做了簡(jiǎn)要的說(shuō)明,大家會(huì)不會(huì)覺(jué)得其實(shí)看下來(lái)不難,就是涉及的東西會(huì)比較多。其實(shí)還有其他的諸如整個(gè)構(gòu)建流程步驟如何可視化,Vscode 插件里面的一些基礎(chǔ)的能力等等在本文都沒(méi)有詳細(xì)提及。
其實(shí) Vscode 插件在整個(gè)開(kāi)發(fā)提效場(chǎng)景中只是當(dāng)中的一個(gè)環(huán)節(jié),我們會(huì)以敦煌工作臺(tái)為核心底座搭配 Chrome 插件,Vscode 插件,zoo-cli 形成一個(gè)開(kāi)發(fā)提效的百寶箱。Vscode 插件更多的是想給開(kāi)發(fā)者們帶來(lái)沉浸式開(kāi)發(fā)的體驗(yàn)。
關(guān)于vscode中如何進(jìn)行微信小程序的發(fā)布就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。