艺灵设计

全部文章
×

uni-app跨端开发微信小程序之手把手带你写一个用程序自动打开微信开发者工具的小插件

作者:艺灵设计 - 来源:http://www.yilingsj.com - 发布时间:2021-05-04 08:57:40 - 阅: - 评:0 - 积分:0

摘要:本文通过获取微信开发者工具安装路径、调用shelljs执行vue-cli编译命令、fs和path组合来读取编译后的目录、动态修改AppId和title这四个方面入手,一步步带领看官制作一个自动打开微信开发者工具的小插件,完美解决日常多环境开发的硬性需求......

注:文章本该于20210503号夜晚发布,但由于发布时突然停电,只好次日发布。

在昨天的文章《uni-app跨端开发微信小程序之HBuilderX项目实现多环境开发》中,我们已经实现了多环境开发的需求。今天接着完结昨天留下的一个小缺陷:如何让程序自动打开微信开发者工具,如果我们能实现这个功能的话,那开发起来简直不要太爽!

文章略长,会涉及到pathfsshelljscli V2等相关的一些操作。我也会尽可能的把自己在实践过程中遇到的一些问题及小坑分享给看官,避免大家继续踩坑。话不多说,开始今天的分享。

一、分析他人源码从而进行优化

首先要感谢@毛学生写的一款插件,插件地址→→open-devtools 让 uni-cli 具有自动打开小程序的能力(戳我访问)。今天的文章是在此插件的基础上进行修改而来,说到这里,可能有看官要问了:既然有人写过插件,那你为啥还要自己再造一个呢?

这个问题问的好,有兴趣的看官可以安装下上面提到的open-devtools插件看看效果。如实说,我在使用过程中发现一些问题,所以才要造一个适合自己项目的插件。

后来我看了下插件的源码,发现有一处逻辑可疑的地方,相关源码见下方。

// 打开微信开发者调试工具, 并运行编译微信小程序
const openWeixinDevTools = () => {
  // 当调试器路径为空时, 给予提示并直接运行程序
  if (!WEIXIN_DEVTOOLS_PATH) {
    shell.echo('当前调试器路径为空, 自动打开调试器功能将失效')
    setTimeout(() => {
      shell.cd(PRESET_PATH)
      shell.exec(EXEC_CODE)
    }, 500)
    return false
  }
  // 先写入, 防止无内容导致调试工具报错
  utils.mkdirsSync(WEIXIN_PRESET_PATH)
  const writeFileStr = JSON.stringify({ appid: 'touristappid', projectname: 'open-devtools' }, null, "\t")
  try {
    fs.writeFileSync(path.resolve(WEIXIN_PRESET_PATH, './project.config.json'), writeFileStr, { flag: 'wx' })
  } catch (error) { }
  // 打开小程序项目
  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)
  })
}

上面的逻辑,乍一看好像并没有什么毛病,但细品的话就有问题了。我个人分析如下:
1、先判断编译目录是否正在,不存在则使用setTimeout延时500ms来处理程序这个操作就显得很鸡肋;
2、原作者是先通过cli命令打开微信开发者工具,在回调中才调用HBuilderX的编译命令;
3、强制手动写入project.config.json文件而非在原文件上修改

我当时的优化方案是:首先把那个延时500毫秒换成一个递归函数,定时执行,找到了就清空定时器。但在实践过程中发现还是有问题呀,于是我思考了一会儿从根源入手。即:为何不先执行编译命令生成目录,再调用V2命令呢?

二、手写插件

这里我们会遇到一些问题,比如:
1、如何读取微信开发者工具安装路径?
2、如何执行vue-cli编译命令?
3、如何动态读取vue-cli命令编译后的源码目录?
4、怎样判断vue-cli编译完成并适时执行V2命令自动打开微信小程序?

伴随着刚提到的4个疑问,我们一步步解答吧!

2.1、先使用vue-cli创建一个uin-app项目

打开命令行,进入日常开发工作目录,然后输入下方代码并回车。

winpty vue.cmd create -p dcloudio/uni-preset-vue my-project

网速快的话会瞬间出现项目模板让你选择,慢的话就多等待一会儿。我们可以使用键盘上的上下方向键来选项模板,默认就用第一个好了。选择好了后并回车,接着耐心等待程序运行。当出现Successfully created project xxx字样时,表示项目已经创建成功了。如图:使用vue-cli创建uni-app项目.png使用vue-cli创建uni-app项目

接下来我们要解决获取微信开发者工具安装路径的问题。

2.2、如何读取微信开发者工具安装路径?

如果是个人开发,这个问题非常好解决,直接写死一个变量就行了。但如果是团队开发呢?不同的开发者安装微信开发者工具的路径也不一样,总不能让大家卸载后安装统一路径吧!虽然简单粗暴最可靠,但这个野蛮方法不太好说出口呀!

那怎么办呢?前面提到的毛学生写的插件open-devtools的做法是:在package.json文件中新增一个名为devtoolsConfig的字段。如实说,个人并不建议直接修改package.json。主要原因还是由于这是一个公用的文件,如果大家修改并上传了此文件,别的同事在拉代码时就会覆盖掉自己的。除非这个文件在一开始的时候就不加入到仓库中或者是大家修改完后这个文件不做提交。也可以每个人都在本地创建一个配置文件,这个文件不做提交。但我思来想去,始终没有找到更好的方案。目前暂时使用的是后者,即本地新建一个配置文件,这个文件大家都不要提交,只给自己使用。相关代码如下:

2.2.1、创建json文件

{
  "weixin": {
    "path": "E:\\soft-jieya\\wxtools\\微信web开发者工具"
  }
}

配置文件创建完了,如何读取里面的内容呢?接下来,我们就需要用到node.js中的fs - 文件系统path - 路径这两个API了。

接着我们在项目根目录下创建一个名为openDevTools.js的js文件,里面代码如下:

#!/usr/bin/env node
const fs = require('fs')
const path = require('path')

// 运行项目路径读取
const PRESET_PATH = path.resolve(__dirname)
const PACKAGE_PATH = path.resolve(PRESET_PATH, './openDevTools/config.json')

// 获取开发者工具目录
const PACKAGE_CONFIG = JSON.parse(fs.readFileSync(PACKAGE_PATH).toString())
const DEVTOOLS_CONFIG = PACKAGE_CONFIG.weixin || {}
const WEIXIN_DEVTOOLS_PATH = DEVTOOLS_CONFIG.path

console.log('微信开发者工具的安装路径是:', WEIXIN_DEVTOOLS_PATH)

代码也写完了,这个openDevTools.js文件该如何运行呢?

打开项目根目录中的package.json文件,然后找到"dev:mp-weixin"的位置,将其修改为下面的代码。

// 原代码
"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch",
// 修改后
"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin ./openDevTools.js",

此时我们再在命令行工具中输入npm run dev:mp-weixin并回车,会看到打印信息如下图:在命令行中输入命令后成功打印出微信开发者工具安装路径.png在命令行中输入命令后成功打印出微信开发者工具安装路径

可以看到,读取json的方法非常麻烦,下面也介绍下读取js文件的方法。

2.2.2、创建js文件

在新建的openDevTools目录下创建一个名为config.js的js文件,里面代码如下:

const config = {
  "weixin": {
    "path": "E:\\soft-jieya\\wxtools\\微信web开发者工具"
  }
}
module.exports = config

openDevTools.js中只需要2行代码,具体见下方:

#!/usr/bin/env node
const config = require('./openDevTools/config.js')
const WEIXIN_DEVTOOLS_PATH = config.weixin.path
console.log('微信开发者工具的安装路径是:', WEIXIN_DEVTOOLS_PATH)

此时我们再在命令行工具中输入npm run dev:mp-weixin并回车,同样能获取到我们事先定义好的微信开发者工具安装路径。

2.3、如何执行vue-cli编译命令?

这个时候我们需要使用shelljs了。继续修改openDevTools.js文件,完整代码如下:

#!/usr/bin/env node
// 第一步:获取微信开发者工具安装路径
const config = require('./openDevTools/config.js')
const WEIXIN_DEVTOOLS_PATH = config.weixin.path
console.log('微信开发者工具的安装路径是:', WEIXIN_DEVTOOLS_PATH)
// 第二步:执行vue-cli编译命令
const path = require('path')
const shell = require('shelljs')
// 运行项目路径读取
const PRESET_PATH = path.resolve(__dirname)
const EXEC_CODE = 'npx cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --color=always'

shell.cd(PRESET_PATH) // 先进入项目目录
const childProcess = shell.exec(EXEC_CODE, { async: true }) // 执行编译代码
childProcess.stdout.on('data', function (data) {
  if (data.match('Build complete')) {
    console.log('微信小程序编译成功', Date.now())
  }
})

childProcess.stderr.on('data', function (data) {
  console.log('stderr: ' + data)
})

现在,我们在终端中继续输入npm run dev:mp-weixin 并回车,会发现打印很多信息。而且在项目根目录下会多出dist/dev/mp-weixin目录,这也就表明我们已经成功的编译微信小程序了。如图:使用shelljs的exec方法成功调用并编译微信小程序.png使用shelljs的exec方法成功调用并编译微信小程序

这里需要注意一下,我最先使用的是shell.exec(EXEC_CODE, () => {})这种方法来监听回调,但在真实项目中回调里一直监听不到任何消息。后来看官方文档,换成上面的写法才成功监听到。shelljs exec (戳我访问文档)

2.4、如何动态读取vue-cli命令编译后的源码目录?

虽然我们成功的编译了微信小程序,也知道路径就是dist/dev/mp-weixin,但我们要怎样动态获取这个路径呢?毕竟正式环境时,路径会变成dist/build/mp-weixin

这个时候,我们就需要读取process.env.NODE_ENV的值了。相关代码如下:

......
// 当前运行环境变量与运行命令
const NODE_ENV = process.env.NODE_ENV
// 微信项目源码路径
const EXEC_CODE_TYPE = NODE_ENV === 'development' ? 'dev' : 'build'
const WEIXIN_PROJECT_PATH = `dist/${EXEC_CODE_TYPE}/mp-weixin`
const WEIXIN_PRESET_PATH = path.resolve(PRESET_PATH, WEIXIN_PROJECT_PATH)
console.log('微信小程序编译后的路径是:', WEIXIN_PRESET_PATH)

现在,我们在终端中输入npm run dev:mp-weixinnpm run build:mp-weixin,打印的路径也会跟随变化哈。如图:在终端中中输入不同的命令后会打印编译后的路径.png在控制台中输入不同的命令后会打印编译后的路径

2.5、程序编译完成后如何自动打开微信开发者工具

还记得WEIXIN_DEVTOOLS_PATH这个变量吗?它就是微信开发者工具的安装路径。接下来我们要使用shelljs先进入到这个路径中,然后才能执行V2命令行做一些其他的操作。代码如下:

......
shell.cd(WEIXIN_DEVTOOLS_PATH)
// 打开小程序项目
const openDevToolsShell = `cli open --project ${WEIXIN_PROJECT_PATH} --color=always`
shell.exec(openDevToolsShell, { async: true })

此时再在终端中中输入npm run dev:mp-weixin并回车,稍等片刻后会看到微信开发者工具已经成功的自动打开了!视频演示:自动编译微信小程序并打开开发者工具.mp4自动编译微信小程序并打开开发者工具(友情提示:点击上面的图片即可播放视频)

怎么样,是不是很棒?!麻麻再也不用担心我要手动启动微信开发者工具了!

三、实践到项目中,配置多环境开发

昨天我们提到了多环境开发的方案,那今天既然解决了自动打开微信开发者工具了,何不把多环境也搞进来?

先来完善下昨天的配置文件,我们把AppIdtitle都写进去。完整代码如下:

const GLOBALCONFIG = {
  VUE_APP_BASE_API: 'https://api.xxxx.com/api', // api请求地址
  VUE_APP_PREVIEW_PICTURE: 'https://cdn.xxx.com/', // 图片域名
  VUE_APP_TITLE : '当前是开发环境',
  APPID: '建议换成真实AppId,避免运行异常',
  TITLE: '开发环境',
}
if (process.env.NODE_ENV === 'development') {
  // 开发环境
} else if (process.env.NODE_ENV === 'test') {
  GLOBALCONFIG.VUE_APP_TITLE = '当前是测试环境'
  GLOBALCONFIG.APPID = '建议换成真实AppId,避免运行异常'
  GLOBALCONFIG.TITLE = '测试环境'
} else if (process.env.NODE_ENV === 'pre') {
  GLOBALCONFIG.VUE_APP_BASE_API = 'https://xxx.com/api'
  GLOBALCONFIG.VUE_APP_PREVIEW_PICTURE = 'https://cdn.xxx.com/'
  GLOBALCONFIG.VUE_APP_TITLE = '当前是预发布环境'
  GLOBALCONFIG.APPID = '建议换成真实AppId,避免运行异常'
  GLOBALCONFIG.TITLE = '预发布环境'
} else if (process.env.NODE_ENV === 'production') {
  GLOBALCONFIG.VUE_APP_BASE_API = 'https://xxx.com/wxapis'
  GLOBALCONFIG.VUE_APP_PREVIEW_PICTURE = 'https://cdn.xxx.com/'
  GLOBALCONFIG.VUE_APP_TITLE = '当前是正式环境'
  GLOBALCONFIG.APPID = '建议换成真实AppId,避免运行异常'
  GLOBALCONFIG.TITLE = '正式环境'
}
console.log('当前环境:', process.env.NODE_ENV, ';title=', GLOBALCONFIG.VUE_APP_TITLE)
module.exports = GLOBALCONFIG

3.1、动态修改AppId 和 title

配置文件搞完后,接下来是要动态修改AppId和title了,可怎么动态修改呢?

好了,艺灵也不卖关子了。我们只需要想办法修改掉编译目录下的project.config.json这个文件即可。这里需要再次用到fspath这两个API了,具体思路是:先通过path找到文件,然后通过fs.readFileSync读取内容,修改后再通过fs.writeFileSync进行写入

这里有一个坑,因为要修改的文件是json格式,如果在写入时不使用JSON.stringify转换的话写入的内容是有问题的哈。核心代码见下方:

......
  const fs = require('fs')
  const GLOBALCONFIG = require('./src/config') // 获取多环境配置参数
  // 微信项目源码路径
  const EXEC_CODE_TYPE = NODE_ENV !== 'production' ? 'dev' : 'build'
  const EXEC_CODE = `npx cross-env NODE_ENV=${NODE_ENV} UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --color=always`
  const PROJECT = path.resolve(WEIXIN_PRESET_PATH, './project.config.json')
  const PROJECT_CONFIG = JSON.parse(fs.readFileSync(PROJECT).toString())
  PROJECT_CONFIG.appid = GLOBALCONFIG.APPID
  PROJECT_CONFIG.projectname = GLOBALCONFIG.TITLE
  const writeFileStr = JSON.stringify(PROJECT_CONFIG, null, '\t')
  fs.writeFileSync(PROJECT, writeFileStr)

现在,我们已经实现了动态修改appid和title了。为了检测是否成功,需要再修改下package.json,新增测试环境、预上线环境这两个环境。修改如下:

...
  "dev:mp-weixin-test": "cross-env NODE_ENV=test UNI_PLATFORM=mp-weixin ./openDevTools.js",
  "dev:mp-weixin-pre": "cross-env NODE_ENV=pre UNI_PLATFORM=mp-weixin ./openDevTools.js",
  ...

现在,我们在终端中中输入以下四种命令并回车,就可以愉快地玩耍了!

dev:mp-weixin // 开发环境
dev:mp-weixin-pre // 预发布环境
dev:mp-weixin-test // 测试环境
build:mp-weixin // 正式环境

每次输完命令后,点开微信开发者工具右侧的详情可以看到appid和title均已被修改。如图:微信开发者工具的appid和title成功被修改.png微信开发者工具的appid和title成功被修改

写到这里时,上面的一些配置基本可以满足日常开发了。如果看官需要实现不同的环境单独创建不同的文件夹,可以继续修改package.json,再传递一个参数,然后使用process.env.xxx来接收。最终的效果可能是这个样子,如图:不同环境对应不同文件夹.png不同环境对应不同文件夹

四、用命令行启动时遇到的一些异常

4.1、IDE service port disabled

详细报错信息见下方,说的很明白。需要手动打开工具 -> 设置 -> 安全设置,将服务端口开启

× initialize

[error] IDE service port disabled. To use CLI Call, please enter y to confirm enabling CLI capability, or manually open IDE -> Settings -> Security Settings, and set Service Port On.
For more details see: https://developers.weixin.qq.com/miniprogram/en/dev/devtools/cli.html
[error] 工具的服务端口已关闭。要使用命令行调用工具,请在下方输入 y 以确认开启,或手动打开工具 -> 设置 -> 安全设置,将服务端口开启。
详细信息: https://developers.weixin.qq.com/miniprogram/dev/devtools/cli.html

4.2、AppID 不合法

报错信息如下,修改project.config.json中的appid即可。

× preparing
[error] {
  code: 10,
  message: 'Error: 错误 Error: AppID 不合法,invalid appid [20210504 07:50:33][](code 10)Error: 错误 Error: AppID 不合法,invalid appid [20210504 07:50:33][] (code 10)\n' +
    '    at Object.GENERIC_ERROR (E:\\soft-jieya\\wxtools\\微信web开发者工具\\code\\package.nw\\core.wxvpkg\\7201d239ccdbdc262e2ecf5fe0c8aca3.js:2:93)\n' +
    '    at E:\\soft-jieya\\wxtools\\微信web开发者工具\\code\\package.nw\\core.wxvpkg\\b3effda444fe34caae1384305e9562c6.js:2:1069'

4.3、请检查 project.config.json 是否存在及是否有效 (code 19)

如果是低版本的微信开发工具,可能会出现code码为19的错误,这个时候多半是因为没有找到project.config.json这个文件。

[error] {
  code: 19,
  error: 'Error: 请检查 project.config.json 是否存在及是否有效 (code 19)'

4.4、启动超时,无法启动

在任务管理器中结束所有微信开发者工具的任务,然后再重新用命令行启动。

其实,在实际的开发中还有遇到很多坑,基本上从报错信息中能够找到答案,这里就不再一一赘述了。

五、源码下载

为了方便看官研究代码,艺灵已经将相关文件打包到了网站上,有需要的看官可以点击右侧链接进行免费下载→→
[源码]自动编译并打开微信开发者工具.zip
github下载:分支:dev-uni-app-vue-cli-openDevTools-20210523

六、最后

今天一天啥也没干,全用来写这篇文章了,看官点个赞再走呗~

转载声明:
  若亲想转载本文到其它平台,请务必保留本文出处!
本文链接:http://www.yilingsj.com/xwzj/2021-05-04/uni-app-vue-cli-openDevTools.html

若亲不想直保留地址,含蓄保留也行。艺灵不想再看到有人拿我的技术文章到他的地盘或者是其它平台做教(装)程(B)而不留下我的痕迹。文章你可以随便转载,随便修改,但请尊重艺灵的劳动成果!谢谢理解。

亲,扫个码支持一下艺灵呗~
如果您觉得本文的内容对您有所帮助,您可以用支付宝打赏下艺灵哦!

Tag: uni-app 跨端开发 微信小程序 shelljs fs path 自动打开开发者工具 自动编译 vue-cli HBuilderX 多环境开发

上一篇: uni-app跨端开发微信小程序之HBuilderX项目实现多环境开发   下一篇: uni-app跨端开发微信小程序之nodejs与后端通信并动态打包项目以适应多环境开发

评论区