详解如何在微信小程序中愉快地使用sass


Posted in Javascript onJuly 30, 2018

前言

在微信小程序中,css是用wxss来表示,但写法基本一致。需要注意的是wxss扩展了两个特性,分别是:

  • 尺寸单位
  • 样式导入

具体可参考wxss,此处不做过多赘述。

为了方便打包sass,我们使用gulp来处理我们的scss文件,将其转换为wxss。

目录结构

在开发中,我们一般会有一个src源代码目录,一个dist目录用来输出我们打包的代码。而本次讲解用到的目录结构如下:

详解如何在微信小程序中愉快地使用sass

  • build目录用来配置我们的打包参数,目前里面只有一个config.js文件
  • dist目录为打包输出的目录,也是小程序运行的目录
  • gulpfile.js配置打包的任务
  • src就是我们的源代码目录

src的目录结构如下:

详解如何在微信小程序中愉快地使用sass

安装依赖

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非常简单,代码如下:

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导入问题

那如何解决import的导入问题呢,其实也比较简单,说白了就是sass处理的时候,让其不处理import部分的语句就可以了。有两种方式可以做到,第一种是改写sass处理的源码,当遇到import语句时跳过。第二种是,在把文件交给sass处理前,我们先把import语句部分注释掉,这样sass处理的时候就会忽略了,当sass处理完成后,再把注释掉的语句打开即可。显然第一种成本比较高,也不好维护。我们采用第二种,代码如下:

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'],
};

清理无用的wxss文件

前面讲了,我们在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 }));
});

总结

  • wxss的特性
  • sass打包配置以及如何处理import语句
  • sass变量、函数的文件清理

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
判断用户的在线状态 onbeforeunload事件
Mar 05 Javascript
Js+Jq获取URL参数的集中方法示例代码
May 20 Javascript
推荐10 个很棒的 jQuery 特效代码
Oct 04 Javascript
全面解析Bootstrap表单使用方法(表单控件状态)
Nov 24 Javascript
Javascript之BOM(window对象)详解
May 25 Javascript
将json转换成struts参数的方法
Nov 08 Javascript
Vuejs实现带样式的单文件组件新方法
May 02 Javascript
vue-cli整合vuex的时候,修改actions和mutations,实现热部署的方法
Sep 19 Javascript
JS/HTML5游戏常用算法之碰撞检测 像素检测算法实例详解
Dec 12 Javascript
VUE+Element环境搭建与安装的方法步骤
Jan 24 Javascript
详解基于iview-ui的导航栏路径(面包屑)配置
Feb 22 Javascript
在Webpack中用url-loader处理图片和字体的问题
Apr 28 Javascript
详解JSON Web Token 入门教程
Jul 30 #Javascript
JS中Promise函数then的奥秘探究
Jul 30 #Javascript
浅析java线程中断的办法
Jul 29 #Javascript
还不懂递归?读完这篇文章保证你会懂
Jul 29 #Javascript
如何在js代码中消灭for循环实例详解
Jul 29 #Javascript
Vue-cli3项目配置Vue.config.js实战记录
Jul 29 #Javascript
vue权限路由实现的方法示例总结
Jul 29 #Javascript
You might like
PHP 开发环境配置(测试开发环境)
2010/04/28 PHP
fleaphp crud操作之findByField函数的使用方法
2011/04/23 PHP
解决PhpMyAdmin中导入2M以上大文件限制的方法分享
2014/06/06 PHP
学习php设计模式 php实现观察者模式(Observer)
2015/12/09 PHP
教你php如何实现验证码
2016/01/20 PHP
功能强大的PHP发邮件类
2016/08/29 PHP
Yii2中使用asset压缩js,css文件的方法
2016/11/24 PHP
Laravel 实现Controller向blade前台模板赋值的四种方式小结
2019/10/22 PHP
Dojo之路:如何利用Dojo实现Drag and Drop效果
2007/04/10 Javascript
JavaScript 申明函数的三种方法 每个函数就是一个对象(一)
2009/12/04 Javascript
用JQuery 判断某个属性是否存在hasAttr的解决方法
2013/04/26 Javascript
JavaScript中检测变量是否存在遇到的一些问题
2013/11/11 Javascript
jquery实现当滑动到一定位置时固定效果
2014/06/17 Javascript
vue 组件使用中的一些细节点
2018/04/25 Javascript
微信小程序MUI导航栏透明渐变功能示例(通过改变rgba的a值实现)
2019/01/24 Javascript
Paypal支付不完全指北
2020/06/04 Javascript
[02:08]什么藏在DOTA2 TI9“小紫本”里?斧王历险记告诉你!
2019/05/17 DOTA
Python实现网站文件的全备份和差异备份
2014/11/30 Python
Python EOL while scanning string literal问题解决方法
2020/09/18 Python
python 读写txt文件 json文件的实现方法
2016/10/22 Python
简述:我为什么选择Python而不是Matlab和R语言
2017/11/14 Python
简单实现python画圆功能
2018/01/25 Python
Python实现发送与接收邮件的方法详解
2018/03/28 Python
Python3按一定数据位数格式处理bin文件的方法
2019/01/24 Python
python绘制无向图度分布曲线示例
2019/11/22 Python
如何使用pandas读取txt文件中指定的列(有无标题)
2020/03/05 Python
Python PyQt5运行程序把输出信息展示到GUI图形界面上
2020/04/27 Python
使用phonegap查找联系人的实现方法
2017/03/31 HTML / CSS
大课间活动实施方案
2014/03/06 职场文书
校庆接待方案
2014/03/18 职场文书
乡镇综治宣传月活动总结
2014/07/02 职场文书
护士2014年终工作总结
2014/11/11 职场文书
个人借款协议书范本
2014/11/17 职场文书
2014年文秘工作总结
2014/11/25 职场文书
安阳殷墟导游词
2015/02/10 职场文书
公司出纳岗位职责
2015/03/31 职场文书