在微信小程序中,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 })); });