写在前面
有过小程序开发经验的都知道,在小程序的生态环境中,是很难做到像其他项目那样完全的CI的,因为我们的上传代码是只能在IDE中操作且代码是提交到微信服务器的,微信并没有提供接口让我们可以自动化部署代码。
一个我们项目中比较常见的问题是,我们本地开发好后,如果想上传代码到腾讯服务器上,需要将本地的一些配置项修改成线上的版本,比如我们的接口地址,项目配置信息等。当然你可以手动去维护,但是不提倡,因为项目如果逐渐增大,业务逻辑变得复杂的话,涉及到的修改项会逐渐增多,手动维护,很难保证不会出错,更有甚者会有人忘记修改直接提交然后苦苦找错,很浪费时间。
这里给大家提供的方案,是我自己根据微信小程序有限的开放能力整理出来的。
废话不多说,入题吧。
你需要会的
- node的基础知识,这里主要用到的是文件的读写
- npm scripts
- 微信小程序的配置(
project.config.json )
项目结构
项目初始化
如果你是使用IDE搭建的一个quick-start的小程序,那么你的目录结构不是像我上面那样的。你需要将你的项目调整为我上面的那样,其中可以通过npm init -y 来直接生成package.json 文件。修改好以后,别忘了修改你的项目根目录下的project.config.json ,添加下面的配置项以指定你的源码目录,否则会编译不会通过:
"miniprogramRoot": "src/",
添加npm脚本
在你的package.json 中添加npm scripts ,我这里只做演示,只添加了两个环境的切换脚本,如下:
"scripts": {
"switch:dev": "node switch.js --dev",
"switch:prod": "node switch.js --prod"
},
可以看到,我们实际运行的是,项目根目录下的switch.js 文件来实现的,接下来我们来实现这个命令脚本。
实现脚本
实现的思路:
- 获取命令行的参数,判断是什么环境
- 根据环境的不同,选择对应的dev目录下的配置文件
- 进行文件的读写,将应该使用的配置文件中的配置写入到/src/config.js下来
接下来是代码实现,注释写的很详细:
const fs = require('fs')
const path = require('path')
const sourceFiles = {
prefix: '/config/env/',
dev: 'dev.json',
prod: 'prod.json'
}
const targetFiles = [{
prefix: '/src/',
filename: 'config.js'
}]
const preText = 'module.exports = '
const cliArgs = process.argv.splice(2)
const env = cliArgs[0]
const isProd = env.indexOf('prod') > -1 ? true : false
const sourceFile = isProd ? sourceFiles.prod : sourceFiles.dev
fs.readFile(__dirname + sourceFiles.prefix + sourceFile,
(err, data) => {
if (err) {
throw new Error(`Error occurs when reading file ${sourceFile}.\nError detail: ${err}`)
process.exit(1)
}
const targetConfig = JSON.parse(data)
const {
baseUrl
} = targetConfig
targetFiles.forEach(function(item, index) {
let result = null
if (item.filename === 'config.js') {
let config = {
baseUrl: baseUrl
}
result = preText + JSON.stringify(config, null, 2)
}
fs.writeFile(__dirname + item.prefix + item.filename, result, 'utf8', (err) => {
if (err) {
throw new Error(`error occurs when reading file ${sourceFile}. Error detail: ${err}`)
process.exit(1)
}
})
})
})
运行测试
我们先用一个简单的配置来测试一下,假设我们本地开发和实际上线的项目中的请求的接口地址前缀是不一样的,我们需要为dev 和prod 环境各提供一个baseUrl 的配置项,修改配置文件:
/config/env/dev.json 文件:
{
"baseUrl": "dev server"
}
/config/env/prod.json 文件:
{
"baseUrl": "prod server"
}
此时假设我们/src/config.json 文件中的代码:
module.exports = {
"baseUrl": "dev server"
}
当我们项目需要上传到腾讯服务器的时候,此时在项目根目录下运行脚本:
npm run switch:prod
此时我们的/src/config.json 文件会被修改成:
module.exports = {
"baseUrl": "prod server"
}
补充:我们可以在app.js 中引入config.js 文件,然后作为一个全局变量暴露出去,这样我们就可以在每个page中通过getApp().globalData.config 来获取这里的各项配置信息了。代码:
const config = require('./config')
App({
onLaunch: function () { },
globalData: {
userInfo: null,
config: config
}
})
与小程序配置文件中的钩子(hooks)集合使用实现上传时的配置信息自动修改
由于每次上传代码时都要自己运行npm脚本来切换环境配置,可能也会有点不方便,所以我们可以使用小程序给我提供的一些钩子来实现自动运行脚本。
首先我们先打开配置项,输入我们要运行的脚本:
这会在我们的project.config.json 中生成如下的脚本,当然难你也可以手动的在这个文件中修改:
"scripts": {
"beforeCompile": "node switch --dev",
"beforePreview": "",
"beforeUpload": "node switch --prod"
}
这三个钩子的对应含义可以在小程序官方文档找到,可以自行参考。不过感觉很多开发者没有用到过。汗。
这是我自己在项目中配置,虽然本地编译的时候每次都会运行一下这个脚本,但是这一点的性能损失还是很微小的,不用care。
github
项目已经上传至github,地址:https://github.com/JerryYuanJ/Jmemo。欢迎issue,如果对你有帮助,欢迎star。
|
请发表评论