详解如何在微信小程序中愉快地使用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 相关文章推荐
禁止刷新,回退的JS
Nov 25 Javascript
Javascript入门学习资料收集整理篇
Jul 06 Javascript
JS 在指定数组中随机取出N个不重复的数据
Jun 10 Javascript
关于编写性能高效的javascript事件的技术
Nov 28 Javascript
js 左右悬浮对联广告特效代码
Dec 12 Javascript
jQuery实现长按按钮触发事件的方法
Feb 02 Javascript
jquery实现平滑的二级下拉菜单效果
Aug 26 Javascript
AngularJs  Understanding Angular Templates
Sep 02 Javascript
javaScript语法总结
Nov 25 Javascript
[js高手之路]原型式继承与寄生式继承详解
Aug 28 Javascript
Vue 表情包输入组件的实现代码
Jan 21 Javascript
基于原生js实现判断元素是否有指定class名
Jul 11 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递归列出所有文件和目录的代码
2008/09/10 PHP
php下载excel无法打开的解决方法
2013/12/24 PHP
phpStudy访问速度慢和启动失败的解决办法
2015/11/19 PHP
谈谈 PHP7新增功能
2015/12/16 PHP
PHP后门隐藏的一些技巧总结
2020/11/04 PHP
FormValid0.5版本发布,带ajax自定义验证例子
2007/08/17 Javascript
js 上传图片预览问题
2010/12/06 Javascript
javascript:void(0)是什么意思示例介绍
2013/11/17 Javascript
JavaScript实现点击自动选择TextArea文本的方法
2015/07/02 Javascript
JQuery validate插件验证用户注册信息
2016/05/11 Javascript
javascript cookie用法基础教程(概念,设置,读取及删除)
2016/09/20 Javascript
将form表单通过ajax实现无刷新提交的简单实例
2016/10/12 Javascript
基于angular中的重要指令详解($eval,$parse和$compile)
2016/10/21 Javascript
微信小程序  网络请求API详解
2016/10/25 Javascript
原生JS实现图片左右轮播
2016/12/30 Javascript
Vue-Router基础学习笔记(小结)
2018/10/15 Javascript
jQuery ajax仿Google自动提示SearchSuggess功能示例
2019/03/28 jQuery
JS深入学习之数组对象排序操作示例
2020/05/01 Javascript
Vue 监听元素前后变化值实例
2020/07/29 Javascript
Python模块学习 filecmp 文件比较
2012/08/27 Python
Python获取央视节目单的实现代码
2015/07/25 Python
学习python之编写简单简单连接数据库并执行查询操作
2016/02/27 Python
python实现flappy bird游戏
2018/12/24 Python
python+tkinter实现学生管理系统
2019/08/20 Python
python如何从文件读取数据及解析
2019/09/19 Python
Win10下用Anaconda安装TensorFlow(图文教程)
2020/06/18 Python
python爬虫用scrapy获取影片的实例分析
2020/11/23 Python
利用CSS3的特性改变文本选中时的颜色
2013/09/11 HTML / CSS
HTML5新特性之type=file文件上传功能
2018/02/02 HTML / CSS
东芝官网商城:还原日式美学,打造美好生活
2018/12/27 全球购物
Oracle的内存结构(Memory structures)
2015/06/10 面试题
策划助理岗位职责
2013/11/18 职场文书
光盘行动倡议书
2014/02/02 职场文书
中职毕业生自我鉴定范文(3篇)
2014/09/28 职场文书
人事局接收函
2015/01/31 职场文书
Java实现扫雷游戏详细代码讲解
2022/05/25 Java/Android