小程序對上傳的代碼有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中。