在最近的工做中,主要作的是C端的小程序,在開發過程當中卻是還好,一到改BUG的時候,可能就會進入保存,編譯,自動預覽的循環了,雖然微信已經提供了快簡介自動預覽,可是總歸是一個手動的過程,要是能監聽文件變化自動預覽不是更好嗎?javascript
因而我就去看了下文檔,發現微信已經提供了這個API,能夠用命令行調用,也能夠用HTTP調用。html
一開始本着配置少一點的原則,我選擇了HTTP調用,由於命令行調用須要配置微信開發者工具的安裝目錄,而HTTP調用能夠經過微信指定的路徑獲取端口號(實踐證實,too young, too simple, 認真你就輸了,HTTP調用的問題太多,因此我後來又改爲了命令行調用)。vue
而後就去官方所指示的ide文件夾找端口號了,結果並無發現那個文件。怎麼回事呢?一頓搜索以後,才知道目前的版本須要以下才能開啓http服務: 微信開發者工具 -> 查看全部項目 -> 設置 -> 安全,裏面有個服務端口,選擇開啓之後就能找到ide文件,進而獲得端口號進行後續操做了。java
fs.watch
進行目錄和文件的監聽,在文件變更後調用自動預覽文檔中提到 端口號文件位置:node
macOS : ~/Library/Application Support/微信開發者工具/Default/.ide Windows : ~/AppData/Local/微信開發者工具/User Data/Default/.idereact
既然路徑有了,那麼就好說了,只要獲取到用戶目錄,而後再拼接上不一樣平臺的後續路徑,那麼經過讀取.ide文件就能夠獲得端口號了。ios
代碼以下:git
const fs = require("fs");
const os = require("os");
const isWin = os.platform() === `win32`;
function getHttpPort() {
const home = os.homedir();
const suffix = isWin
? `/AppData/Local/微信開發者工具/User Data/Default/.ide`
: `/Library/Application Support/微信開發者工具/Default/.ide`;
const idePath = home + suffix;
const port = fs.readFileSync(idePath, { encoding: "utf8" });
return port;
}
複製代碼
實例:github
# 打開工具
http://127.0.0.1:端口號/open
# 打開/刷新項目
http://127.0.0.1:端口號/open?projectpath=項目全路徑
複製代碼
先在瀏覽器中直接進行訪問,很好,你會發現微信開發者工具並無打開,再仔細看了下文檔,用法確定沒錯的,總共就端口號和項目路徑兩個變量,怎麼可能會出錯呢?被某廠坑久了,就知道有問題是必然的。web
算了,打不開就打不開吧,影響並非很大,反正平時開發的時候,開發者工具都是打開的。這個問題呢,我猜想是由於工具每次打開端口號都會變化,而讀取的端口號是以前的,因此就沒用了。
-o, --open [projectpath]: 打開工具,若是不帶 projectpath,只是打開工具。若是帶 project path,則打開路徑中的項目,每次執行都會自動編譯刷新,而且自動打開模擬器和調試器。projectpath 不能是相對路徑。項目路徑中必須含正確格式的 project.config.json 且其中有 appid 和 projectname 字段。
調用:
cli -o /Users/username/demo
複製代碼
此次的調用徹底沒有問題的。
接口定義:
URL:/autopreview
HTTP 方法:GET
URL 參數 | 必填 | 說明 |
---|---|---|
projectpath | 是 | 指定路徑中的項目。如項目已打開,自動刷新項目。如項目未建立,自動建立並自動預覽項目 |
infooutput | 否 | 指定後,會將本次自動預覽的額外信息以 json 格式輸出至指定路徑,如代碼包大小、分包大小信息。 |
compilecondition | 否 | 指定自定義編譯條件,值爲 json 字符串,條件可指定兩個字段,pathName 表示打開的頁面,不填表示首頁,query 表示頁面參數 |
這個接口請求之後,卻是能夠用,可是坑也不小。
文檔老是缺三少四的,這裏一塊那裏一塊,稍微看漏一點這個功能可能就出不來了,說到底看文檔就是得仔細。
自動預覽必須處於登陸狀態,若是沒有登陸,會提示需先登陸。
--auto-preview <project_root>
: 自動預覽代碼,project_root 指定項目根路徑。
--auto-preview-info-output <path>
: 指定後,會將本次預覽的額外信息以 json 格式輸出至指定路徑,如代碼包大小、分包大小信息。
--compile-condition '<json>'
: 指定自定義編譯條件,json 條件可指定兩個字段,pathName 表示打開的頁面,不填表示首頁,query 表示頁面參數
用命令行測試:
cli --auto-preview /Users/username/demo --compile-condition {\"pathName\": \"pages/home/index\",\"query\":\"a=1\"}
複製代碼
JSON.stringify(obj).replace(/\"/g, `\\"`)
所得到的字符串,注意要把"換成\",且先後不須要單引號,文檔裏面那種調用方式會報錯,不信的小夥伴能夠本身嘗試。// 將D:\\www\\soft轉換成D:/www/soft這種形式
// msg爲路徑不存在時的報錯信息
function getPath(projectpath, msg) {
if (!projectpath) {
throw new Error(msg);
}
return projectpath.split(path.sep).join(`/`);
}
// 獲取打包路徑
function getDist(config = {}) {
const { projectpath } = config;
return (
config.dist ||
(/dist\/?$/.test(projectpath) ? projectpath : (projectpath || "") + `/dist`)
);
}
// 將exec轉爲promise類型的函數,方便使用async await
const promisify = require("util").promisify;
let { exec } = require("child_process");
exec = promisify(exec);
複製代碼
這裏介紹一下exec
child_process.exec(command[, options][, callback])
複製代碼
參數 | 類型 | 說明 |
---|---|---|
command | string | The command to run, with space-separated arguments. (須要運行的命令,參數用空格分開) |
options | object | { cwd: "子進程工做目錄,默認爲null", } 其餘參數我沒怎麼用過 |
callback | 否 | 回調函數: (error: Error, stdout: string | Buffer, stderr: string | Buffer) |
spawn和exec的卻別在於,spawn的輸出是實時的,而exec是執行完以後統一返回。前者還得監聽事件略顯麻煩,因此我選擇了exec。
async function open({ projectpath, cli, }) {
return new Promise(async (resolve, reject) => {
log();
log(chalk.green(`打開開發者工具中...`));
const result = await exec(
`cli -o ${projectpath}`,
{
cwd: cli
}
);
const isSuccess = result.stdout;
log(isSuccess ? chalk.green(`打開成功`) : chalk.red(`打開失敗`));
isSuccess ? resolve() : reject();
})
}
複製代碼
async function preview(config) {
await open(config);
const port = getHttpPort();
const { dist, projectpath, time, compile, cli } = config;
log();
log(chalk.blue(`開始監聽文件變更`));
log(`路徑參數: `, compile);
fs.watch(
dist,
debounce(async (evt, filename) => {
log();
console.log(`${filename} ${evt}`);
log(chalk.green(`自動預覽重啓中...`));
log(
`執行命令: cli --auto-preview ${projectpath} --compile-condition ${compile}`
);
const result = await exec(
`cli --auto-preview ${projectpath} --compile-condition ${compile}`,
{
cwd: cli
}
);
const isSuccess = result.stdout;
log(isSuccess ? chalk.green(`自動預覽成功`) : chalk.red(`自動預覽失敗`));
}, time || 1000)
);
}
複製代碼
const fn = {
preview,
upload,
};
function run(config, type) {
if (!fn[type]) {
throw new Error(`type參數不合法,請確保爲preview, upload的一種`);
}
log(chalk.green(`本次啓動類型爲: ${type}`));
fn[type](config);
}
複製代碼
config參數從命令行參數中讀取文件得到,type參數爲命令行參數。
#! /usr/bin/env node
const run = require("../lib/index");
const program = require("commander");
const fs = require("fs");
const path = require("path");
const { getPath, getHttpPort, getDist } = require("../util/index");
program
.option("-c, --config <type>", "config file", "auto.js")
.option("-t, --type <type>", "auto type, etc: preview, upload", "preview")
.parse(process.argv);
// 獲取執行命令時所在的目錄,拼接上配置文件目錄,使用require(ConfigFile)便可得到相關配置
const CD = process.cwd();
const Config = program.config;
const ConfigFile = path.join(CD, Config);
const defaultCompile = {
pathName: `pages/home/index`
};
// 判斷配置文件不存在,則直接報錯
if (!fs.existsSync(ConfigFile)) {
throw new Error(`[ERROR]: ${Config} not found in ${CD}`);
} else {
start();
}
function start() {
let config = require(ConfigFile);
config = { ...config };
config.projectpath = getPath(
config.projectpath,
`配置文件中projectPath字段必須有值`
);
const projectpath = config.projectpath;
config.dist = getDist(config);
config.compile = JSON.stringify(config.compile || defaultCompile).replace(
/\"/g, `\\"`
);
// 這裏可寫可不寫,打開工具後會進行再次獲取
config.port = getHttpPort();
run(config, program.type);
}
複製代碼
至此,該功能已經大體完成了,我已經上傳到了npm,能夠直接進行使用。
微信開發者工具,HTTP調用,自動預覽,提升工做效率
npm i wx-auto -D 或者 yarn add wx-auto -D
複製代碼
npm i wx-auto -g
複製代碼
wxauto
或者
wxauto -t preview -c auto.js
複製代碼
-t, --type 類型,目前支持preview和upload
-c, --config 配置文件名,默認值爲auto.js
複製代碼
文件路徑爲相對路徑,相對於執行命令時所在的路徑
{
cli: "D:/soft/微信web開發者工具", // cli文件所在的目錄
projectpath: `D:/www/react/heywoof-app-frontend`, // 項目地址
compile: {
pathName: `pages/scene/index`, // 自動預覽的頁面路徑
query: `activityId=5d45050569515b000c5b740a` // 查詢參數,微信目前有BUG,只能識別一個參數
},
build: `yarn build-test:weapp`, // 上傳以前須要執行的命令
upload: {
version: "1.0.1",
desc: "測試自動上傳,不要亂動"
}
};
複製代碼
此外還包含了自動打包上傳的功能,配置以後執行wxauto -t upload -c auto.js
,上傳完畢後就會自動打開微信公衆平臺登陸的網站,我的感受仍是挺實用的。
在查看文檔的時候,我發現微信官方推出了一個多端統一開發工具——kbone,這個是基於vue的,就是配置略顯麻煩。
除此以外,微信小程序如今已經支持自動化測試了,感興趣的小夥伴能夠自行嘗試。注意:該功能須要最新版本支持,必定要符合文檔所說的版本,我簡單嘗試了一下,自動化是能夠實現的,更具體的測試就得看工做須要了。