为何使用 Sass 和 Webpack
Sass 是 CSS 的超集,在 CSS 的基础上扩展了大量的语法,支持规则嵌套、变量定义、include 等功能,也可以进行数学运算。主要功能可以在官方入门教程中查看。Sass 原先的文件格式扩展名是 sass,其结构类似 yaml,似乎不与传统 CSS 兼容;而目前 Sass 的文件格式是 scss,兼容 CSS 文件。
我使用 Sass 的目的,一是更加清晰的 CSS 规则管理。例如,我有一些 CSS 规则希望只对网站顶栏生效,我就可以将它们全部放到一个代码块中方便管理:
header {
h1 { ... }
}
二是减少网页加载时的 CSS 代码量。虽然我的网站使用了 Bootstrap,但是我只使用了一小部分功能,即 Bootstrap 的栅格系统,导航栏和下拉菜单,其它大部分功能都没有使用,这部分 CSS 就不必加载。同时,我还通过 CSS !important
覆盖的方式对一些
Bootstrap 的颜色、形状进行了自定义,这也引入了额外的代码量。
我在我的 scss 文件中定义了全局的控件颜色、字体大小等,同时自己 include Bootstrap 的 scss 文件,注释掉我不需要的功能,最后产生的 CSS 文件大小也会大幅下降。
另外 Sass 产生的 CSS 是合并成一个缩减过大小(Minify)的,最后将这一个文件传上服务器就好。
我使用 Webpack 也是类似的原因:去除我不需要的 Bootstrap JS 功能,并将 JS 代码压缩并合并成一个文件。
还有一点:Sass 和 Webpack 可以与 npm 共同使用,用 npm 更新 Bootstrap 等框架的最新代码,并在 Sass 和 Webpack 的 JS 文件中共同使用。
在 Hexo 中使用 Sass 和 Webpack
Hexo 作为一款流行的静态网站生成工具,有大量的插件。我使用的插件是 hexo-renderer-sass 和 hexo-webpack:
npm install --save hexo-renderer-sass
npm install --save hexo-webpack
对于 Sass,由于我要 include npm 安装的框架代码,需要在主题的 _config.yml
中加入如下代码,让 Sass 去 node_modules 文件夹下找 npm 安装的模块:
node_sass:
includePaths:
- 'node_modules'
outputStyle: compressed
以 Bootstrap 为例,先用 npm 安装:
npm install --save bootstrap
再在自己的 styles.scss 文件中 include:
@import 'bootstrap/scss/functions';
@import 'bootstrap/scss/variables';
@import 'bootstrap/scss/mixins';
@import 'bootstrap/scss/root';
@import 'bootstrap/scss/reboot';
@import 'bootstrap/scss/type';
// @import "bootstrap/scss/images";
// @import "bootstrap/scss/code";
@import 'bootstrap/scss/grid';
// @import "bootstrap/scss/tables";
// @import "bootstrap/scss/forms";
// @import "bootstrap/scss/buttons";
// @import "bootstrap/scss/transitions";
@import 'bootstrap/scss/dropdown';
// @import "bootstrap/scss/button-group";
// @import "bootstrap/scss/input-group";
// @import "bootstrap/scss/custom-forms";
@import 'bootstrap/scss/nav';
@import 'bootstrap/scss/navbar';
// @import "bootstrap/scss/card";
// @import "bootstrap/scss/breadcrumb";
// @import "bootstrap/scss/pagination";
// @import "bootstrap/scss/badge";
// @import "bootstrap/scss/jumbotron";
// @import "bootstrap/scss/alert";
// @import "bootstrap/scss/progress";
// @import "bootstrap/scss/media";
// @import "bootstrap/scss/list-group";
// @import "bootstrap/scss/close";
// @import "bootstrap/scss/toasts";
// @import "bootstrap/scss/modal";
// @import "bootstrap/scss/tooltip";
// @import "bootstrap/scss/popover";
// @import "bootstrap/scss/carousel";
// @import "bootstrap/scss/spinners";
@import 'bootstrap/scss/utilities';
// @import "bootstrap/scss/print";
对于 Webpack,由于我使用的一些 JS 模块依赖 jQuery,但它们是原生 JS 模块,缺少相应在 Webpack 中加载 jQuery 模块的指令,因此需要修改 Webpack 配置在主题目录(与
_config.yml
同一文件夹)下创建 webpack.config.js
文件,使用 Webpack 的
ProvidePlugin 为它们直接提供 jQuery 环境:
const webpack = require('webpack')
module.exports = {
entry: 'assets/script.js',
output: {
filename: 'script.bundle.js',
path: 'assets',
},
mode: 'production',
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
}),
],
}
上述配置的入口 JS 文件在 assets/script.js
,最后生成文件在
assets/script.bundle.js
。
再以 Bootstrap 为例,在 script.js
中用这一行代码,就可以导入 Bootstrap 的下拉菜单模块,以及它依赖的 jQuery 和 Popper.js:
import 'bootstrap/js/src/dropdown'
其它模块同理。
最后修改主题的 head 区域加载最后生成的 CSS 和 JS 文件:
<link rel="stylesheet" href="<%- url_for('assets/style.css') %>" />
<script src="<%- url_for('assets/script.bundle.js') %>"></script>
hexo generate
即可。