如何讓 uni-cli 建立的項目擁有運行自動打開開發者調試工具的能力

前言:

關於前端的IDE,流行的無非也就那麼幾款,但若要問那款編輯器最好用,那無疑是vscode開發的最溫馨了,不得不說vscode的代碼提示,引入跳轉,自動補全引入語句等功能,而且git支持很不錯,加上typescript後開發體驗真的是提高到了一個很高的檔次。html

HBuilderX 在這些方面的支持真是太差了,只有內置的代碼提示,沒有d.ts文件的支持,自定義擴展功能少,使用typescript開發徹底丟失了類型提示,使得typescript在編寫時發現問題的這個優點徹底丟失。前端

因此咱們公司的多端程序都使用了uni-cli腳手架搭建的項目運行,在vscode中運行,但相比HBuilderX卻缺乏了運行後自動打開小程序的功能,那麼問題來了,HBuilderX都能作到,爲何咱們vscode作不到呢!vue

其實作這個很簡單,致使我一度懷疑HBuilderX爲了推廣他自家的編譯器而不作這個功能...(事實上確實如此)目前我已經作成了一個第三方插件,直接使用便可,該文章的主要目的是記錄當中所用到的技術,如怎麼本身作一個腳手架程序等。node

我的博客:gitee.io/mao-bloggit

腳手架自動打開小程序:open-devtoolsgithub

微信小程序命令行v2

微信開發者工具提供了cli命令,可用於在外部使用cmd打開和操控項目,這裏只使用部分指令,感興趣的同窗能夠去看官網文檔web

首先找到開發者工具的目錄下,cmd打開當前目錄,咱們建立一個小程序項目放在開發者工具的根目錄下,而後試着使用命令行打開項目。vue-cli

cd F:softs微信web開發者工具
cli open --project F:softs微信web開發者工具demo

那麼運行以後,就會發現開發者工具自動打開了程序,這裏須要注意,運行的路徑必選得是絕對路徑,否則是會報錯的。typescript

npm 命令行調用 node 工具

這裏只記錄了我使用的方式,說的可能不是很全面,建議去看一下這篇文章,從0開始用node寫一個本身的命令行程序shell

# 初始化項目
npm init

# 修改 package.json 中bin字段
"bin": {
    "open-dev": "./index.js"
}

# 新建 index.js
#!/usr/bin/env node
console.log('open-dev')
# `#!/usr/bin/env node` 的意思是讓系統本身去找node的執行程序,該行必不可少。

# 執行 npm link
npm link

# 運行腳手架工具
git-tool

# index.js 中 process.argv 可用來獲取命令行參數
# 注意 #!/usr/bin/env node 爲是必須的
#!/usr/bin/env node
console.log('open-dev')
console.log(process.argv) # ['...', '...', ....]

使用 shelljs 調用 cmd 命令

ShellJS是在Node.js API之上的Unix shell命令的可移植(Windows / Linux / macOS)實現。是基於Node.js API的封裝。其餘API能夠查看官網:shelljs

const shell = require('shelljs')
// 進入目錄
shell.cp('F:\\softs\\微信web開發者工具')
// 調用命令, 這裏須要注意, 調用命令時須要在後面加上 --color=always 否則就沒有命令行顏色了
shell.exec('cli open --project F:\softs\微信web開發者工具\demo --color=always')

獲取當前執行環境

咱們來仔細的觀察一下 uni-cli 自帶的命令中,前面存在很長一大串的命令,那這個命令具體做用就是用於區分當前運行環境和類型的。若是想了解更多,能夠去看一下 cross-env 的官方文檔。

運行命令攜帶參數cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin

"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin open-devtools",

將至關於在咱們的命令jsprocess.env環境變量裏添加了兩個參數

const NODE_ENV = process.env.NODE_ENV // development
const UNI_PLATFORM = process.env.UNI_PLATFORM // mp-weixin

獲取 pageage.json 中的字段

咱們須要知道,微信開發者工具的路徑是不肯定的,那麼須要在一開始先肯定下來,個人思路是放在項目中的pageage.json儲存。

{
 "devtoolsConfig":{
    "weixin": "F:softs微信web開發者工具"
 }
}

腳手架實開發

那麼有了這些基本的東西,基本的思路已經有了,實現功能具體路線爲

基本路徑與開發者工具的路徑 》》運行開發者工具》》調用對應自身項目運行命令

// index.js
#!/usr/bin/env node
const fs = require("fs")
const path = require("path")
const shell = require('shelljs')
const utils = require(path.resolve(__dirname, './src/utils'))

// 運行項目路徑讀取, 這裏須要注意當安裝依賴時, 當前路徑爲xxx/node_module/xxx, 因此須要回退兩層
const PRESET_PATH = path.resolve(__dirname, '../../')
const PACKAGE_PATH = path.resolve(PRESET_PATH, './package.json')

// 當前運行環境變量與運行命令, getRunPresetExec是我封裝的方法, 能夠獲取當前對應的運行命令
// 例如 development|mp-weixin 則對應 -> npx cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --color=always
const NODE_ENV = process.env.NODE_ENV
const UNI_PLATFORM = process.env.UNI_PLATFORM
const EXEC_CODE = utils.getRunPresetExec(NODE_ENV, UNI_PLATFORM)

// 微信項目源碼路徑, 這裏對於項目中的小程序源碼路徑
const EXEC_CODE_TYPE = NODE_ENV === 'development' ? 'dev' : 'build'
const WEIXIN_PRESET_PATH = path.resolve(PRESET_PATH, `dist/${EXEC_CODE_TYPE}/mp-weixin`)

// 獲取開發者工具目錄(pageage.json)
const PACKAGE_CONFIG = JSON.parse(fs.readFileSync(PACKAGE_PATH).toString())
const DEVTOOLS_CONFIG = PACKAGE_CONFIG.devtoolsConfig || {}
const WEIXIN_DEVTOOLS_PATH = DEVTOOLS_CONFIG.weixin

// 若是調用環境是微信
if (UNI_PLATFORM === 'mp-weixin') {
  // 先遞歸寫入, 防止無內容致使調試工具報錯
  // 這裏須要注意, 不能直接寫入文件, 須要先建立好完整的目錄
  // 否則會直接報錯, 這裏的mkdirsSync是我封裝的遞歸建立目錄的方法
  utils.mkdirsSync(WEIXIN_PRESET_PATH)
  const writeFileStr = JSON.stringify({ appid: 'touristappid', projectname: 'open-devtools' }, null, "\t")
  fs.writeFileSync(path.resolve(WEIXIN_PRESET_PATH, './project.config.json'), writeFileStr, { flag: 'w' })
  // 打開小程序項目
  const openDevToolsShell = `cli open --project ${WEIXIN_PRESET_PATH} --color=always`
  shell.cd(WEIXIN_DEVTOOLS_PATH)
  // 打開完畢後, 運行編譯工具
  shell.exec(openDevToolsShell, () => {
    shell.cd(PRESET_PATH)
    shell.exec(EXEC_CODE)
  })
  // 返回當前條件, 阻止代碼運行
  return false;
}

// 如上方代碼沒有執行, 則直接執行運行項目命令
shell.cd(PRESET_PATH)
shell.exec(EXEC_CODE)
相關文章
相關標籤/搜索