gulp 的使用(四):处理 css

1,411 阅读4分钟

这是我参与更文挑战的第17天,活动详情查看: 更文挑战

前言

在上一篇 gulp 的使用(三):处理 js 文章里介绍了 gulp 如何处理 html。

在这篇文章里将介绍 gulp 如何处理 css。

输出 css

我们在 src 目录里创建一个 css 目录,里面新建一个 index.css 文件,里面写上如下测试代码。

body {
  background: yellowgreen;
}

src/index.html 引入 index.css。

...
<head>
  ...
  <link rel="stylesheet" href="./css/index.css">
</head>
...

gulpfile.js 配置

function css() {
  return src(['src/css/**/*.css'])
    .pipe(changed('dist/css/**/'))
    .pipe(plumber())
    .pipe(dest('dist/css'))
}
function watcher() {
  ...
  watch('src/css/**/*.css', series(css)).on('unlink', function (path) {
    del('dist/css/**/' + Path.basename(path))
  })
}

exports.default = series(clean, html, libJs, js, css, devServer, watcher)
exports.build = series(clean, html, libJs, js, css)

运行 npm run build,可以发现 dist 目录有 css/index.css 目标文件。

压缩 css

gulp-clean-css 是一个用于压缩 css 的插件,接下来安装 gulp-clean-css。

安装

npm i -D gulp-clean-css

gulpfile.js 配置

...

const cleanCss = require('gulp-clean-css')

...

function css() {
  return src(['src/css/**/*.css'])
    .pipe(changed('dist/css/**/'))
    .pipe(plumber())
    .pipe(cleanCss())
    .pipe(dest('dist/css'))
}

...

我们打开 dist/css/index.css,可以看到里面的样式代码被压缩。

image.png

编译 scss

scss 是一种 css 预处理语言,现在都主流使用 scss 来写样式,下面介绍如何使用 gulp 插件编译 scss。

在 src 创建一个 scss 文件夹,里面新建一个 index.scss 文件,里面写上测试代码。

html {
  body {
    background: blanchedalmond;
  }
}

index.html 里引入 scss 目录的 index.css,记得编译出来的文件是 css 文件。

<link rel="stylesheet" href="./scss/index.css">

安装

npm i -D sass node-sass gulp-sass

注意:上面命令安装了 sass (dart sass)和 node-sass 两个编译器,在实际开发中,我们只用其中一个编译器就可以了,选择你自己喜欢的编译器,我建议选择 dart sass,因为 webpack 大佬也是这样推荐 (文章链接)。

image.png

现在 gulp-sass 插件(5.0.0 版本)也推荐使用 dart sass 了,之前是推荐 node-sass。

如果发现安装不了,建议用 cnpm 来安装这一块。

gulp-sass 插件 5.0.0 版本与之前的版本有点不同,这里特别说明一下。

5.0.0 版本之前,这样引入

gulpfile.js

const sass = require('gulp-sass')
sass.compiler = require('sass') // 使用 sass 编译器
// sass.compiler = require('node-sass') // 使用 node-sass 编译器

5.0.0 版本后,这样引入

gulpfile.js

const sass = require('gulp-sass')(require('sass')) // 使用 sass 编译器
// const sass = require('gulp-sass')(require('node-sass')) // 使用 node-sass 编译器

我们这里采用 5.0.0 版本的最新写法

gulpfile.js

const sass = require('gulp-sass')(require('sass'))
// const sass = require('gulp-sass')(require('node-sass')) // 如果是选择 node-sass 编译器,这样写
...

function scss() {
  return src(['src/scss/**/*.scss'])
    .pipe(changed('dist/scss/**/'))
    .pipe(plumber())
    .pipe(sass())
    .pipe(cleanCss())
    .pipe(dest('dist/scss'))
}

...

function watcher() {
  ...
  watch('src/scss/**/*.scss', series(scss)).on('unlink', function (path) {
    var cssName = Path.basename(path).split('.scss')[0] // 请留意一下这里的代码
    del('dist/scss/**/' + cssName + '.css')
  })
}

exports.default = series(clean, html, libJs, js, css, scss, devServer, watcher)
exports.build = series(clean, html, libJs, js, css, scss)

上面的 watch 代码和以往的有一丢丢不同,因为 scss 编译出来的文件后缀是 css 而不是 scss,需要特别处理,务必留意一下。

gulp-sass 的文档(4.x.x 版本)里有说到,如果使用 dart sass 编译器,则会存在一个问题,同步编译的速度是异步编译的速度的两倍,为了解决异步编译开销过大的问题,需要使用 fibers 包,从同步代码路径调用异步导入器(好吧,我是机翻  ̄□ ̄||,具体看下面原文)。

Note that when using Dart Sass, synchronous compilation is twice as fast as asynchronous compilation by default, due to the overhead of asynchronous callbacks. To avoid this overhead, you can use the fibers package to call asynchronous importers from the synchronous code path.

但是,gulp-sass 5.0.0 版本已经不存在这个问题了,如果你使用的是 gulp-sass 5.x 版本,则不需要安装 fibers。

如果是 gulp-sass 4.x 版本,请安装 fibers

npm i -D fibers

同样地,如果 npm 安装不了,使用 cnpm 安装。

修改 gulpfile.js

const fiber = require('fibers') // 变量名命名没 s

...

function scss() {
  return src(['src/scss/**/*.scss'])
    .pipe(changed('dist/scss/**/'))
    .pipe(plumber())
    .pipe(sass({ fiber }))
    .pipe(cleanCss())
    .pipe(dest('dist/scss'))
}

运行 npm run build,可以发现 dist/scss 多了一个 index.css 文件。

image.png

区分 css 开发源码和 css 库

和上一篇文章的 js 一样,我们有时候也会用到第三方的 css 库,因此需要区分 css 开发源码 和 css 库。

在 src 目录新建一个 libCss 目录,里面复制一个第三方样式 animate.min.css。

...

function libCss() {
  return src(['src/libCss/**/*.css'])
    .pipe(changed('dist/libCss/**/'))
    .pipe(plumber())
    .pipe(dest('dist/libCss'))
}

function watcher() {
  ...
  watch('src/libCss/**/*.css', series(libCss)).on('unlink', function (path) {
    del('dist/libCss/**/' + Path.basename(path))
  })
}

exports.default = series(clean, html, libJs, js, css, scss, libCss, devServer, watcher)
exports.build = series(clean, html, libJs, js, css, scss, libCss)

由于写法差不多,不再详细说明。

完整项目

2021.8.30,我重新整理了一遍项目,已放到 gitee 上,大家可以 clone 下来直接用,代码的提交记录顺序和我这个系列文章教程顺序是一致的,大家看到哪一篇文章时,就回滚代码到哪一个版本,这样看项目代码会更直观。

gitee 库链接:gitee.com/only1zhuo/g…

image.png

“gulp 的使用”系列文章