这节课讲解webpack4中打包css的应用。v4 版本和 v3 版本并没有特别的出入。
1. 准备工作
众所周知,CSS 在 HTML 中的常用引入方法有<link>标签和<style>标签两种,所以这次就是结合webpack特点实现以下功能:
将 css 通过 link 标签引入
将 css 放在 style 标签里
动态卸载和加载 css
页面加载 css 前的transform
下图展示了这次的目录代码结构:
这次我们需要用到css-loader,file-loader等 LOADER,package.json如下:
{ "devDependencies": { "css-loader": "^1.0.0", "file-loader": "^1.1.11", "style-loader": "^0.21.0" } }
其中,base.css代码如下:
*, body { margin: 0; padding: 0; } html { background: red; }
index.html代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <script src="https://www.jb51.net/article/dist/app.bundle.js"></script> </body> </html>
2. CSS通过<link>标签引入
link 标签通过引用 css 文件,所以需要借助file-loader来将 css 处理为文件。
webpack.config.js:
const path = require("path"); module.exports = { entry: { app: "./src/app.js" }, output: { publicPath: __dirname + "/dist/", path: path.resolve(__dirname, "dist"), filename: "[name].bundle.js" }, module: { rules: [ { test: /\.css$/, // 针对CSS结尾的文件设置LOADER use: [ { loader: "style-loader/url" }, { loader: "file-loader" } ] } ] } };
为了让效果更显著,编写如下app.js:
let clicked = false; window.addEventListener("click", function() { // 需要手动点击页面才会引入样式!!! if (!clicked) { import("./css/base.css"); } });
3. CSS放在<style>标签里
通常来说,css放在style标签里可以减少网络请求次数,提高响应时间。需要注意的是,在老式 IE 浏览器中,对style标签的数量是有要求的。
app.js和第二部分一样,webpack.config.js配置修改如下:
const path = require("path"); module.exports = { entry: { app: "./src/app.js" }, output: { publicPath: __dirname + "/dist/", path: path.resolve(__dirname, "dist"), filename: "[name].bundle.js" }, module: { rules: [ { test: /\.css$/, // 针对CSS结尾的文件设置LOADER use: [ { loader: "style-loader", options: { singleton: true // 处理为单个style标签 } }, { loader: "css-loader", options: { minimize: true // css代码压缩 } } ] } ] } };
4. 动态卸载和加载CSS
style-loader为 css 对象提供了use()和unuse()两种方法,借助这两种方法,可以方便快捷地加载和卸载 css 样式。
首先,需要配置webpack.config.js:
const path = require("path"); module.exports = { entry: { app: "./src/app.js" }, output: { publicPath: __dirname + "/dist/", path: path.resolve(__dirname, "dist"), filename: "[name].bundle.js" }, module: { rules: [ { test: /\.css$/, use: [ { loader: "style-loader/useable" // 注意此处的style-loader后面的 useable }, { loader: "css-loader" } ] } ] } };
然后,我们修改我们的app.js,来实现每 0.5s 换一次背景颜色:
import base from "./css/base.css"; // import cssObj from '...' var flag = false; setInterval(function() { // unuse和use 是 cssObj上的方法 if (flag) { base.unuse(); } else { base.use(); } flag = !flag; }, 500);
打包后打开index.html即可看到页面背景颜色闪动的效果。
5. 页面加载css前的transform
对于css的transform,简单来说:在加载 css 样式前,可以更改 css。这样,方便开发者根据业务需要,对 css 进行相关处理。
需要对style-loader增加options.transform属性,值为指定的 js 文件,所以, webpack.config.js配置如下:
const path = require("path"); module.exports = { entry: { app: "./src/app.js" }, output: { publicPath: __dirname + "/dist/", path: path.resolve(__dirname, "dist"), filename: "[name].bundle.js" }, module: { rules: [ { test: /\.css$/, use: [ { loader: "style-loader", options: { transform: "./css.transform.js" // transform 文件 } }, { loader: "css-loader" } ] } ] } };
下面,我们编写css.transform.js,这个文件导出一个函数,传入的参数就是 css 字符串本身。