小程序代码压缩实践

随着业务的发展,项目不断地迭代,功能模块越加越多,项目代码和静态资源文件体积已经超过了微信小程序限定的 2M 范围。虽说小程序支持分包操作,然而用户进入分包模块时会有一个比较长的加载时间,整体体验还是不友好的,万不得已不要分包。既然不分包,那么我们可以从哪方面来进行项目体积的“瘦身”呢?

文件层

通过分析小程序的项目目录我们可知,小程序的文件主要有 .js .wxs .wxss .wxml .json 后缀的文件和一些图片资源文件,如果对这些文件进行压缩,项目的体积至少能缩减 10%。微信开发者工具有提供代码压缩的配置,只要上传代码前勾选对应配置即可。这对于一般小程序项目来说是挺方便的,然而对于使用了第三方框架(如:wepy、taro)的项目,这些功能基本框架代码编译层面就进行来处理,无需在开发者工具中勾选。

小程序代码压缩实践

既然这么完备了,我们还有必要自行编写代码来对这些文件进行压缩么?其实,实际上上面提到的都会有些不足的地方,如官方提供的压缩做不到图片的压缩,第三方方框架不会对部分文件进行压缩。所以根据我们的需求,自行写一套自动化压缩流程才是最稳妥的。

自动化压缩

要实现自动化压缩流程,可使用 gulp、grunt、webpack 等构建工具来进行构建。由于自己比较熟悉 gulp 故使用它来进行构建流程的编写。gulp 的使用比较简单,只要在项目根目录新建一个 gulpfile.js 文件,安装相关依赖后就能运行。

// 安装 npm install gulp-cli -g npm install --save-dev gulp // 执行(默认执行根目录 gulpfile.js 文件) gulp

因为 gulpfile.js 文件还没写内容,所以打印只能看到 ‘default’ 任务的执行记录。下面我们使用 gulp 4.x 的版本进行开发,旧版本写法可能会有些出入,不过大致原理是一样的。

// gulpfile.js \'use strict\' const { task, dest, src, series } = require(\'gulp\') task(\'js\', function(){ // 压缩 .js }) task(\'wxml\', function(){ // 压缩 .wxml }) // 省略... task( \'default\', series([ \'js\', \'wxml\', //... ]) ) .js 压缩

原本是使用 gulp-uglify 这个库进行压缩的,后发现其不支持 es6语法,所以转用 gulp-uglify-es,两者配置有些出入。小程序的 js 文件因其语法和标准的 JavaScript 语法是一样的,故无需额外配置,直接默认配置压缩即可。

const uglify = require(\'gulp-uglify-es\').default task(\'js\', function () { return src(\'dist/**/*.js\') .pipe(uglify()) .pipe(dest(\'dist/\')) })

第三方框架 wepy 或者 taro 都会对 .js 文件进行压缩,正常情况下我们无需二次压缩。

.wxs 压缩

WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
WXS 与 JavaScript 是不同的语言,有自己的语法,并不和 JavaScript 一致。

正常情况下 .wxs 文件可以和 .js 一样可通过 gulp-uglify-es 来进行压缩,不过由于微信坑爹地搞特殊化,wxs 就像严重阉割版的 js,在压缩后会出现各种问题。

task(\'wxs\', function () { return src([\'dist/**/*.wxs\', \'!dist/components/vant/wxs/add-unit.wxs\']) .pipe(uglify({ compress: { ie8: true, // 支持 ie8,为了禁止 a === undefined 自动转换为 void 0 === a join_vars: false // 禁止合并 var } })) .pipe(dest(\'dist/\')) })

代码中 "!dist/components/vant/wxs/add-unit.wxs" 是排除掉了此文件,原因是暂无方法解决压缩后部分正则无法正常使用的问题。

// 压缩前 var REGEXP = getRegExp(\'^\d+(\.\d+)?$\'); // 压缩后 var REGEXP = getRegExp(\'^d+(.d+)?$\');

微信的 getRegExp 并不像 new RegExp 那样支持双反斜杆进行字符转义,巨坑!!!老实说,如果官方不出专门的压缩库,感觉最好还是不要压缩这个东西。

.wxss 压缩

样式和常规的的 css 文件的差不多,因此可以通过一般的样式工具进行压缩,比如 gulp-clean-css 第三方库。

const cleanCss = require(\'gulp-clean-css\') const replaceimport = require(\'./replaceImport\') task(\'wxss\', function () { return src(\'dist/**/*.wxss\') .pipe(cleanCss({ compatibility: \'*\', inline: false })) .pipe(replaceimport()) .pipe(dest(\'dist/\')) })

由于压缩老版本 wepy 项目样式时,组件引入样式 @import "xxx" 会被转成 @import url(\'xxx\') 在开发者工具中会报错,故写了 replaceimport 转回来,taro 项目无需加。

// replaceimport.js \'use strict\'; /** * 由于使用 gulp-clean-css 进行样式压缩时 * 会将 `@import "xxx";` 转成 `@import url(xxx);` * 而转化后的 import 在小程序开发者工具会报错 * 所以用此方法,将 @import url(xxx) 转回 @import \'xxx\' */ const through = require(\'through2\') module.exports = () => through.obj(function (file, enc, next) { if (file.isNull()) { next(null, file); return; } try { const reg = /(?:^|\s)?(?:@import)(?:\s)(?:url)?(?:(?:(?:\()(["\'])?(?:https?:)?([^"\')]+)\1(?:\))|(["\'])(?:.+)\2)(?:[A-Z\s])*)+(?:;)/ig file.contents = new Buffer.from(file.contents.toString().replace(reg, \'@import "$2";\')) next(null, file) } catch (error) { next(null, file) } }); .wxml 压缩

WXML(WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzwxfd.html