详解如何在微信小程序中愉快地使用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 相关文章推荐
使用JQuery和CSS模拟超链接的用户单击事件的实现代码
May 23 Javascript
获取内联和链接中的样式(js代码)
Apr 11 Javascript
javascript解决innerText浏览器兼容问题思路代码
May 17 Javascript
jQuery 计算iframe 窗口大小的方法
May 13 Javascript
原生JavaScript实现滚动条效果
Mar 24 Javascript
一波JavaScript日期判断脚本分享
Mar 06 Javascript
JS填写银行卡号每隔4位数字加一个空格
Dec 19 Javascript
vue页面使用阿里oss上传功能的实例(二)
Aug 09 Javascript
js使用generator函数同步执行ajax任务
Sep 05 Javascript
node.js基于fs模块对系统文件及目录进行读写操作的方法详解
Nov 10 Javascript
vue的一个分页组件的示例代码
Dec 25 Javascript
解决layer.confirm选择完之后消息框不消失的问题
Sep 16 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
zend Framework中的Layout(模块化得布局)详解
2013/06/28 PHP
php中curl、fsocket、file_get_content三个函数的使用比较
2014/05/09 PHP
利用 fsockopen() 函数开放端口扫描器的实例
2017/08/19 PHP
js中将多个语句写成一个语句的两种方法小结
2007/12/08 Javascript
用JQuery 实现AJAX加载XML并解析的脚本
2009/07/25 Javascript
基于jquery的lazy loader插件实现图片的延迟加载[简单使用]
2011/05/07 Javascript
javaScript(JS)替换节点实现思路介绍
2013/04/17 Javascript
PHP abstract与interface之间的区别
2013/11/11 Javascript
css与javascript跨浏览器兼容性总结
2014/09/15 Javascript
详解nodejs实现本地上传图片并预览功能(express4.0+)
2017/06/28 NodeJs
vue的基本用法与常见指令
2017/08/15 Javascript
MUI 实现侧滑菜单及其主体部分上下滑动的方法
2018/01/25 Javascript
vue2 全局变量的设置方法
2018/03/09 Javascript
vue实现移动端input上传视频、音频
2020/08/18 Javascript
[46:55]LGD vs Liquid 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/19 DOTA
[01:06]DOTA2小知识课堂 Ep.02 吹风竟可解梦境缠绕
2019/12/05 DOTA
[52:40]完美世界DOTA2联赛PWL S2 Magma vs GXR 第一场 11.29
2020/12/02 DOTA
解决已经安装requests,却依然提示No module named requests问题
2018/05/18 Python
使用python根据端口号关闭进程的方法
2018/11/06 Python
Python3 jupyter notebook 服务器搭建过程
2018/11/30 Python
Python 普通最小二乘法(OLS)进行多项式拟合的方法
2018/12/29 Python
CSS3混合模式mix-blend-mode/background-blend-mode简介
2018/03/15 HTML / CSS
css3针对移动端卡顿问题的解决(动画性能优化)
2020/02/14 HTML / CSS
李维斯德国官方网上商店:Levi’s德国
2016/09/10 全球购物
美国时尚大码女装购物网站:Avenue
2019/05/24 全球购物
怎样声明接口
2014/09/19 面试题
ORACLE十问
2015/04/20 面试题
What's the difference between Debug and Trace class? (Debug类与Trace类有什么区别)
2013/09/10 面试题
咖啡馆创业计划书
2014/01/26 职场文书
领导班子四风对照检查材料思想汇报
2014/09/26 职场文书
交通事故赔偿协议书怎么写
2014/10/04 职场文书
2014年城管工作总结
2014/11/20 职场文书
2014年招商工作总结
2014/11/22 职场文书
建党伟业电影观后感
2015/06/01 职场文书
解决Laravel使用验证时跳转到首页的问题
2021/11/17 PHP
MySQL读取JSON转换的方式
2022/03/18 MySQL