关于近期小程序代码优化的总结

最近我开发小程序也有三四个月,针对开发过程中遇到的错误调试、代码优化或项目自动化构建进行总结。

代码检查

在梳理代码逻辑时发现很多代码不规范的地方,包括简单的js问题以及代码格式化的问题,造成了代码可读性下降,所以项目优化的第一步就是对代码风格做统一化处理。主要用到eslintprettier

关于rpx

rpx是小程序官方提供的一种像素单位,可按照屏幕宽度进行自适应,小程序开发过程中建议使用rpx。但对于一些第三方框架,如vant,用的是px。所以需将对应的px换算为rpx(按照750px的设计稿是1px:2rpx

因为用到miniprogram-ci作为构建工具(下文有提及),所以在自动化构建的过程中需要对vant组件库进行转换,转换具体是依赖gulpgulp-postcsspostcss-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插件

  1. 在package.json中增加配置

{
  "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作为官方的构建工具,我们可使用该工具提供的命令行模式,具体如下:

  1. 在package.json中加上

 "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举例:

  1. 安装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/),具体步骤如下:

  1. 在企业微信建一个用于通知的群,然后管理员身份配置群机器人

2. 在上述网站中配置一个转发

3. 在sentry中增加webhook插件

4. 配置dinglingdingling生成的链接

5. 点击test触发通知

以上接入同样可以应用在项目构建完成、错误的提醒,定时构建的通知等。

Last updated

Was this helpful?