本文详细介绍在 Webpack 4 环境下处理 CSS 的四种核心方法。通过配置 file-loader 和 style-loader,分别实现将 CSS 以 link 标签引入、注入 style 标签、动态加载卸载样式以及使用 transform 预处理 CSS 字符串。文章包含具体的 webpack.config.js 配置代码与 app.js 示例,帮助开发者优化样式加载性能与灵活性。
Webpack 4 处理 CSS 概述与准备工作
本节内容主要讲解在 Webpack 4 环境中打包 CSS 的具体应用。需要指出的是,Webpack v4 版本在处理 CSS 方面的机制与 v3 版本相比,并没有显著的区别或特殊的差异。
1. 准备工作
在 HTML 中,CSS 的常用引入方式通常包括使用 <link> 标签引入外部样式表,或者在 <style> 标签中直接编写内部样式。基于 Webpack 的模块化特性,本次教程将结合其特点实现以下四种功能:
- 通过 link 标签引入 CSS 文件
- 将 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;
}
入口 HTML 文件 index.html 的代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="./dist/app.bundle.js"></script>
</body>
</html>
通过 Link 标签引入 CSS
2. 通过 <link> 标签引入 CSS
当希望将 CSS 以 <link> 标签的形式引入页面时,需要借助 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");
}
});
将 CSS 注入 Style 标签
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代码压缩
}
}
]
}
]
}
};
动态加载与卸载 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.5 秒切换一次背景颜色的效果:
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 即可看到页面背景颜色不断闪动的效果。
CSS 加载前的 Transform 预处理
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 字符串本身。
module.exports = function(css) {
console.log(css); // 查看css
return window.innerWidth < 1000 ? css.replace("red", "green") : css; // 如果屏幕宽度 < 1000, 替换背景颜色
};
在 app.js 中引入 CSS 文件即可生效:
import base from "./css/base.css";
打开浏览器控制台,如下图所示,当屏幕宽度小于 1000 像素时,CSS 中的 red 颜色已被替换为 green。

需要特别注意:transform 是在 CSS 引入前根据当前条件进行修改的,因此修改后的结果是固定的,不会随窗口大小变化而改变。这意味着上述代码并非响应式,当将屏幕宽度拉大到大于 1000 像素时,颜色依然保持为绿色。只有重新刷新页面,才会重新执行 transform 并显示红色。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。