在微信小程序中,css是用wxss來表示,但寫法基本一致。須要注意的是wxss擴展了兩個特性,分別是:css
具體可參考wxss,此處不作過多贅述。html
爲了方便打包sass,咱們使用gulp來處理咱們的scss文件,將其轉換爲wxss。gulp
在開發中,咱們通常會有一個src源代碼目錄,一個dist目錄用來輸出咱們打包的代碼。而本次講解用到的目錄結構以下:小程序
src的目錄結構以下:微信小程序
yarn add gulp gulp-sass gulp-rename gulp-replace gulp-tap gulp-clean -D
gulp和gulp-sass爲打包sass必須,gulp-rename則負責把scss後綴改成wxss,gulp-replace負責內容的替換(這個後面會講到),gulp-tap用來處理當前執行的文件,gulp-clean負責清除咱們不須要的文件。sass
gulp配置打包sass很是簡單,代碼以下:bash
const gulp = require('gulp'); const sass = require('gulp-sass'); const rename = require('gulp-rename'); gulp.task('sass', () => gulp.src('./src/**/*.{scss,wxss}') .pipe(sass().on('error', sass.logError)) .pipe(rename({ extname: '.wxss' })) .pipe(gulp.dest('./dist')) );
這樣就能夠完成了sass的配置,可是這樣會有問題。前面講到了wxss是支持樣式導入的,也就是說import語法wxss是支持的,但css不支持,所以sass打包會把import的文件打包到當前文件,從而致使當前文件的體積變大。因爲微信限制單包代碼不能超過2M,所以當css越寫越多的時候,這種打包方式勢必會使樣式文件愈來愈大。微信
那如何解決import的導入問題呢,其實也比較簡單,說白了就是sass處理的時候,讓其不處理import部分的語句就能夠了。有兩種方式能夠作到,第一種是改寫sass處理的源碼,當遇到import語句時跳過。第二種是,在把文件交給sass處理前,咱們先把import語句部分註釋掉,這樣sass處理的時候就會忽略了,當sass處理完成後,再把註釋掉的語句打開便可。顯然第一種成本比較高,也很差維護。咱們採用第二種,代碼以下:xss
const gulp = require('gulp'); const sass = require('gulp-sass'); const replace = require('gulp-replace'); const rename = require('gulp-rename'); const clean = require('gulp-clean'); const tap = require('gulp-tap'); const path = require('path'); const config = require('./build/config'); const hasRmCssFiles = new Set(); gulp.task('sass', () => gulp.src('./src/**/*.{scss,wxss}') .pipe(tap((file) => { // 當前處理文件的路徑 const filePath = path.dirname(file.path); // 當前處理內容 const content = file.contents.toString(); // 找到filter的scss,並匹配是否在配置文件中 content.replace(/@import\s+['|"](.+)['|"];/g, ($1, $2) => { const hasFilter = config.cssFilterFiles.filter(item => $2.indexOf(item) > -1); // hasFilter > 0表示filter的文件在配置文件中,打包完成後須要刪除 if (hasFilter.length > 0) { const rmPath = path.join(filePath, $2); // 將src改成dist,.scss改成.wxss,例如:'/xxx/src/scss/const.scss' => '/xxx/dist/scss/const.wxss' const filea = rmPath.replace(/src/, 'dist').replace(/\.scss/, '.wxss'); // 加入待刪除列表 hasRmCssFiles.add(filea); } }); console.log('rm', hasRmCssFiles); })) .pipe(replace(/(@import.+;)/g, ($1, $2) => { const hasFilter = config.cssFilterFiles.filter(item => $1.indexOf(item) > -1); if (hasFilter.length > 0) { return $2; } return `/** ${$2} **/`; })) .pipe(sass().on('error', sass.logError)) .pipe(replace(/(\/\*\*\s{0,})(@.+)(\s{0,}\*\*\/)/g, ($1, $2, $3) => $3.replace(/\.scss/g, '.wxss'))) .pipe(rename({ extname: '.wxss', })) .pipe(gulp.dest('./dist')));
在處理import的時候,還有個地方是須要注意的。在sass中,import除了能引入css外,也能夠引入變量,函數。所以,咱們在處理的時候也須要注意區分,變量和函數最好有一個獨立的文件目錄存放,而且在import的時候,對於變量和函數,是必須交給sass處理的,也就是不能註釋掉。所以,在上面的代碼中,咱們能夠看到,咱們引入了build目錄下的config,其配置了sass變量和函數存放的位置,這樣咱們在打包的時候,遇到這樣的import語句,咱們就跳過,交給sass處理,不然就表明其是引入了共用的樣式文件,這樣咱們交給sass處理前,就先將其註釋掉,sass處理完成後再把註釋打開。另外,import的多是一個scss文件,但在轉成wxss的時候,已經將其後綴改成了wxss,所以,在將註釋打開的時候也須要更改相應的引入,這也就是gulp-replace包的做用。config的配置以下:函數
module.exports = { cssFilterFiles: ['scss/var.scss'], };
前面講了,咱們在sass中可能會定義一些變量,函數,這些文件一會一併打包到dist目錄,但其內容是空的,這時候咱們就須要對其進行清理,前面在打包過程當中,咱們有一個set變量hasRmCssFiles
記錄了相應的文件,這樣咱們遍歷這個變量便可刪除相應的文件,代碼以下:
gulp.task('clean:wxss', () => { const arr = []; hasRmCssFiles.forEach((item) => { arr.push(item); }); return gulp.src(arr, { read: false }) .pipe(clean({ force: true })); });