小程序对上传的代码有2M的大小限制,所以通常在小程序中使用icon的时候,要么是用icon-font,要么就是将icon图片上传到cdn再使用,而不会将图片放在本地。可是使用icon-font有一个问题,就是不能使用渐变色,所以,须要渐变色的icon都只能使用图片来完成。若是这样的icon少还能够手动一张张上传到cdn,可是多到10-20张,手动传就是一件耗时费力的事了。所以,咱们须要把咱们的icon整合起来,作成一张雪碧图,而后将其上传到cdn,最后将cdn的地址替换到css中。在小程序中咱们借助gulp来将这一系列步骤自动化,下面谈谈具体的实施方案。javascript
为了使咱们的源码能使用更多的现代特性,咱们将目录分为了src和dist两大目录,src存放咱们的源码,而dist则存放gulp处理事后给小程序执行的代码。以下所示:css
先安装依赖包java
yarn add sprity sprity-sass gulp gulp-if gulp-sass gulp-rename gulp-replace -D
咱们采用sprity这个库来处理雪碧图,而sprity-sass则是针对scss的一个处理器。gulp-sass则是将scss文件处理为css,gulp-rename将其命名为小程序特有的wxss文件。node
首先打开gulpfile编写咱们的雪碧图处理代码,以下:shell
const gulp = require('gulp'); const sass = require('gulp-sass'); const rename = require('gulp-rename'); const sprity = require('sprity'); const gulpif = require('gulp-if'); gulp.task('sprity', () => { return sprity.src({ src: './src/icons/**/*.{png,jpg}', // icon存放目录 style: '_icon.scss', // 生成的icon文件 processor: 'sass', // 处理器 }) .pipe( gulpif('*.png', gulp.dest('./src/sprity/'), // 生成的雪碧图存放路径 gulp.dest('./src/sprity/')) // 生成的icon存放路径 ); });
写完后,咱们执行gulp sprity
,能够发现咱们sprity文件夹下生成了一张sprity.png和_icon.scss文件,其内容以下:gulp
$buy-discount-card: -0px -0px 76px 76px; $buy-product: -0px -76px 76px 76px; $buy-service: -0px -152px 76px 76px; $buy-times-card: -0px -228px 76px 76px; $home: -0px -304px 76px 76px; @mixin sprite-width($sprite) { width: nth($sprite, 3); } @mixin sprite-height($sprite) { height: nth($sprite, 4); } @function sprite-width($sprite) { @return nth($sprite, 3); } @function sprite-height($sprite) { @return nth($sprite, 4); } @mixin sprite-position($sprite) { $sprite-offset-x: nth($sprite, 1); $sprite-offset-y: nth($sprite, 2); background-position: $sprite-offset-x $sprite-offset-y; } @mixin sprite($sprite, $display: block) { @include sprite-position($sprite); background-repeat: no-repeat; overflow: hidden; display: $display; @include sprite-width($sprite); @include sprite-height($sprite); } .icon { background-image: url('../sprity/sprite.png'); }
若是不用上传到cdn,那么咱们就能够直接引用这个文件了,其用法以下:小程序
@import '_icon.scss'; // 引入生成的雪碧图文件 .icon-discount-card { // 编写icon @include sprite($buy-discount-card); // 此处的变量为_icon.scss前面几行定义的变量,这些变量的名称都是根据icon文件名来生成 } .icon-home { @include sprite($home); }
如上代码所示,咱们就写好了咱们的icon文件,到时候直接使用 icon icon-home
便可。你可能会以为还要本身手写图标会很麻烦,sprity也支持直接生成图标,不过得本身手动去写对应的模板,有兴趣的能够网上找一下相关资料,此处不展开。sass
雪碧图文件已经生成了,咱们下一步要作的就是将其上传到cdn,这里咱们的作法是使用node自带的spawn来执行shell命令,而这个shell命令会把咱们的雪碧图上传到cdn上。在有赞内部,咱们使用superman这个工具,若是读者是上传到别的cdn服务器,应该也会有相应的命令上传配置,建议找一下cdn的文档。gulp上传雪碧图代码以下:bash
const replace = require('gulp-replace'); const { spawn } = require('child_process'); gulp.task('cdn', () => { const reg = /\/\/img\.yzcdn\.cn(.+)\.png/g; // 匹配上传的路径 const sm = spawn('superman', ['cdn', './src/sprity/sprite.png']); // 执行上传命令 sm.stdout.on('data', (data) => { const d = reg.exec(data); if(d && d.length > 0) { // 根据返回值来匹配 gulp.src(['./src/sprity/_icon.scss']) .pipe(replace(/\.\.\/sprity\/sprite\.png/g, d[0])) // 替换本地雪碧图 .pipe(gulp.dest('./src/style/')); } }); });
以上步骤作完后,基本就大功告成了。若是更进一步,咱们能够把生成的scss的px改成微信建议的rpx,代码以下:服务器
if(d && d.length > 0) { // 根据返回值来匹配 gulp.src(['./src/sprity/_icon.scss']) .pipe(replace(/\.\.\/sprity\/sprite\.png/g, d[0])) // 替换本地雪碧图 .pipe(replace(/(-?)(\d+)px/g, ($1, $2, $3) => { return $2 + parseInt($3) * 2 + 'rpx'; })) .pipe(gulp.dest('./src/style/')); }
以上,咱们就完成了在小程序中使用雪碧图,为了能让咱们一边写代码,一边能看到相应的输出,咱们能够经过gulp来watch咱们的文件,当检测到变化时就从新生成一份代码到dist中。