最近我开发小程序也有三四个月,针对开发过程中遇到的错误调试、代码优化或项目自动化构建进行总结。
代码检查
在梳理代码逻辑时发现很多代码不规范的地方,包括简单的js问题以及代码格式化的问题,造成了代码可读性下降,所以项目优化的第一步就是对代码风格做统一化处理。主要用到eslint
和prettier
。
关于rpx
rpx
是小程序官方提供的一种像素单位,可按照屏幕宽度进行自适应,小程序开发过程中建议使用rpx。但对于一些第三方框架,如vant
,用的是px
。所以需将对应的px
换算为rpx
(按照750px
的设计稿是1px:2rpx
)
因为用到miniprogram-ci作为构建工具(下文有提及),所以在自动化构建的过程中需要对vant
组件库进行转换,转换具体是依赖gulp
、gulp-postcss
、postcss-pxtransform
对项目中的px
进行转换。在gulpfile.js中增加以下代码:
function formatCSS(cb) {
const processors = [
pxtorem({
platform: 'weapp',
designWidth: 750
})
]
gulp
.src(['./miniprogram_npm/**/*.wxss'])
.pipe(postcss(processors))
.pipe(gulp.dest('./miniprogram_npm'))
gulp
.src(['./pages/**/*.wxss'])
.pipe(postcss(processors))
.pipe(gulp.dest('./pages'))
gulp
.src(['./pages/**/*.less'])
.pipe(postcss(processors))
.pipe(gulp.dest('./pages'))
cb()
}
注意这里的pxtorem配置有误,因而需要单独引用一份出来修改deviceRatio
const deviceRatio = {
640: 2.34,
750: 2,
828: 1.81
}
如何在提交前触发格式检查
为避免开发时,开发人员的风格各自不同,不符合代码规范,因而需要对代码格式进行eslint检查并自动格式化,这里主要用到husky、lint-staged、eslint以及prettier
插件
{
"scripts": {
"precommit": "lint-staged"
},
"lint-staged": {
"pages/**/*.{js,wxs}": [
"eslint --fix --ext .js",
"prettier ./ --write",
"git add"
]
},
"devDependencies": {
"eslint": "^5.0.0",
"eslint-config-ali": "^2.0.1",
"eslint-plugin-import": "^2.6.0",
"eslint-plugin-react": "^7.1.0",
"husky": "^0.14.2",
"babel-eslint": "^8.1.1",
"lint-staged": "^4.0.0",
"prettier":"^1.16.4",
"eslint-plugin-prettier":"^3.0.1",
"eslint-config-prettier":"^4.0.0"
},
}
2. 在.eslintrc.js
增加eslint扫描配置
module.exports = {
"extends": ["eslint-config-ali","prettier", "plugin:prettier/recommended"],
"parser": "babel-eslint",
"rules": {
"prettier/prettier": "error",
"strict": "off",
"no-console": "off",
"import/no-dynamic-require": "off",
"global-require": "off",
"require-yield": "off",
"eqeqeq": "off",
"new-cap": "off",
"no-nested-ternary": "off",
"array-callback-return": "off"
},
"plugins": ["prettier"],
"globals": {
"React": "readable",
"wx": true,
"App": true,
"Page": true,
"Component": true,
"getApp": true,
"toast": true
}
};
3. 增加.prettierrc.js
文件,用于在扫描通过后格式化代码
module.exports = {
printWidth: 100,
semi: false,
singleQuote: true,
trailingComma: 'none',
bracketSpacing: true,
jsxBracketSameLine: false,
arrowParens: 'avoid',
requirePragma: false,
proseWrap: 'preserve'
};
这里如果要忽略掉某一目录,可增加.prettierignore
文件
.vscode
node_modules
miniprogram_npm
helper
pages/api/sdk/wxsdk3.2.0.js
pages/utils/
typings/
这样在commit的时候就会自动触发lint-staged
,如果代码不合规范就会不让提交
自动化构建
之前构建都是在微信开发工具中手动发布,每次都需要手动输入版本号,很不方便,因而需要。而小程序正好提供miniprogram-ci作为官方的构建工具,我们可使用该工具提供的命令行模式,具体如下:
"devDependencies": {
"miniprogram-ci": "^1.0.79",
"dayjs": "^1.8.36",
"execa": "^4.0.3"
}
2. 因为用到vant组件库,所以需要自动化构建npm
async function buildNPM(cb) {
await ci.packNpm(project, {
reporter: infos => {
console.log(infos)
}
})
cb()
}
3. 在CI.js中增加以下代码,用于自动化构建并上传
async function uploadCI(cb) {
await ci.upload({
project,
version: getVersion(),
desc: getGitCommit(),
setting: {
es6: true,
es7: true,
minify: true
},
onProgressUpdate: console.log
})
cb()
}
4. 在微信后台生成一个代码上传密钥,重命名为private.key,保存到根目录下
5. 在Jenkins中配置自动化构建项目,Jenkins搭建教程很多,这里不再阐述。在这过程中会先构建npm,然后执行rpx转换,最后构建程序并上传,构建脚本如下:
node -v
rm -rf node_modules
npm i
npm i gulp -g
gulp default --branch $giteeSourceBranch
6. 等待构建完成后就会自动上传到小程序那边
PS:详细的构建脚本如下(gulpfile.js):
const ci = require('miniprogram-ci')
const dayjs = require('dayjs')
const execa = require('execa')
const gulp = require('gulp')
const postcss = require('gulp-postcss')
const pxtorem = require('./helper/pxtransform')
const app = require('./package.json')
const config = require('./project.config.json')
const project = new ci.Project({
appid: config.appid, // 小程序的appId
type: 'miniProgram',
projectPath: './', // 打包路径
privateKeyPath: './private.key', // 密钥位置
ignores: ['node_modules/**/*', 'CI.js', 'private.key'] // 打包时忽略的文件
})
function getVersion() {
const branch = process.argv[2]
const date = dayjs().format('YYYYMMDD')
return `${app.version}.${date}.${branch == 'master' ? 'release' : 'beta'}`
}
function getGitCommit() {
const commit = execa.commandSync('git log -1')
return `【${process.argv[2]}】${commit.stdout}`
}
async function buildNPM(cb) {
await ci.packNpm(project, {
reporter: infos => {
console.log(infos)
}
})
cb()
}
function formatCSS(cb) {
const processors = [
pxtorem({
platform: 'weapp',
designWidth: 750
})
]
gulp
.src(['./miniprogram_npm/**/*.wxss'])
.pipe(postcss(processors))
.pipe(gulp.dest('./miniprogram_npm'))
gulp
.src(['./pages/**/*.wxss'])
.pipe(postcss(processors))
.pipe(gulp.dest('./pages'))
gulp
.src(['./pages/**/*.less'])
.pipe(postcss(processors))
.pipe(gulp.dest('./pages'))
cb()
}
async function uploadCI(cb) {
await ci.upload({
project,
version: getVersion(),
desc: getGitCommit(),
setting: {
es6: true,
es7: true,
minify: true
},
onProgressUpdate: console.log
})
cb()
}
exports.default = gulp.series(buildNPM, formatCSS, uploadCI)
真机远程调试
小程序不像webview一样可以通过chrome或safari远程调试,因而需要通过抓包去捕捉真机中的请求错误,一般抓包工具都可以,以下用charles举例:
2. 保证手机和pc在同一网络下,在无线局域网-配置代理中输入pc端的无线地址、charles端口
3. 这样charles中就会显示对应的请求
4. 对于SSL请求,是看不到内容的,所以需要安装代理证书。
在手机端打开 chls.pro/ssl 下载安装证书
需要在 设置→通用→关于本机→证书信任设置里面启用完全信任Charles证书,打开信任按钮
在charles中打开Proxy -> SSL Proxying Settings,勾选Enable SSL Proxying并配置域名
错误搜集
小程序自身就有一个错误搜集的机制,当线上版本或测试版本出错时,就会传到后台。但这种错误一是对于接口调用的错误没有搜集,二是错误发生时没有提醒。因而需要接入一个第三方的错误监控系统。
接入其实也很简单,sentry 是一个开源的实时错误监控的项目,它支持很多端的配置,包括 web 前端、服务器端、移动端及其游戏端。支持各种语言,例如 python、oc、java、node、javascript 等。对于主流框架vue、angular、react等也支持。安装方式参照docker安装方式即可,网上的教程很多,这里就不再阐述。
这里主要说下怎么接入到小程序中,其实已经有有赞开发的插件 raven-weapp
引入文件
由于目前小程序不支持从node_modules中引入文件,因此以npm方式安装的话只能手动将raven-weapp/dist目录下需要的文件拷贝到其他文件中,在app.js中引入,例如:
var Raven = require('./utils/raven-weapp/build/raven')
初始化Raven
在sentry中创建一个项目,选择JavaScript类型,创建完会生成对应的服务器链接(http://36887e0d8a0b48ea9ae3738204a358ef@sentry.nerochen.wang:9000/4),在app.js中onLaunch时初始化Raven,
Raven.config('http://36887e0d8a0b48ea9ae3738204a358ef@sentry.nerochen.wang:9000/4', {
release: '1.2.0', // 版本号
environment: 'production', //指定某个环境下才会上报
allowDuplicates: true, // 允许相同错误重复上报
sampleRate: 0.5 // 采样率
}).install()
这样当前端报错时就会上传对应的错误
接口调用的错误
Raven也支持自定义上传错误信息,我们可以在封装request的时候,将接口调用错误信息用Raven上传
Raven.captureMessage(url:${url}\nresult:${JSON.stringify(error)}, { level: 'error' });
关于错误通知
除了sentry自带的邮件通知(配置),我们使用企业微信的也可以通过配置webhook,触发企业微信机器人通知到我们(https://dinglingdingling.com/),具体步骤如下:
在企业微信建一个用于通知的群,然后管理员身份配置群机器人
2. 在上述网站中配置一个转发
3. 在sentry中增加webhook插件
4. 配置dinglingdingling生成的链接
5. 点击test触发通知
以上接入同样可以应用在项目构建完成、错误的提醒,定时构建的通知等。