「使用 webpack 5 从0到1搭建React TypeScript 项目环境」2. 集成 css、less 与 sass
上篇文章带大家使用 webpack 5集成 React 与TypeScript,同时为了提高我们的代码质量,我们会在构建中添加「类型检查」和「代码规范校验」。这次我们在上篇的基础上介绍如何集成 css、less 与sass。
1. 配置 css
1.1 开发环境
为了在 JavaScript 模块中import 一个 CSS 文件,你需要安装 style-loader 和 css-loader,并在 module 配置 中添加这些 loader。
我们需要安装css-loader和style-loader:
yarn add css-loader style-loader -D
修改配置文件:
代码语言:javascript复制module: {
rules: [
...,
{
test: /.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
这样配置后,当 webpack 再遇到.css文件时,它将使用css-loader和style-loader进行处理(use 数组中的加载器从后向前执行)。
css-loader在import语句(在我们的示例中为app.css)中读取引用的CSS文件并解析成JavaScript代码。style-loader将JavaScript代码中的CSS以style标签的形式插入到html文件中。
接下来再通过yarn start开启即可看到我们引入外部.css文件生效。
1.2 生产环境
在生产环境下,我们需要进行压缩CSS,以便在生产环境中节省加载时间,同时还可以将CSS文件抽离成一个单独的文件。实现这个功能,需要 mini-css-extract-plugin 这个插件来帮忙。安装插件:
yarn add mini-css-extract-plugin -D
本插件会将 CSS 提取到单独的文件中,为每个包含 CSS 的JS文件创建一个 CSS文件,并且支持 CSS 和 SourceMaps 的按需加载。
本插件基于 webpack 5 的新特性构建,并且需要webpack 5才能正常工作。
之后将loader 与 plugin 添加到你的 webpack 配置文件中。
在 webpack.config.pred.js中做如下添加如下配置:
const miniCssExtractPlugin = require('mini-css-extract-plugin');
// ...
module.exports = {
// ....
module: {
rules: [
// ...
{
test: /.css$/i,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
]
},
plugins: [
// ...
new MiniCssExtractPlugin({
filename: 'styles/[name].[contenthash].css'
}),
],
mode: 'production',
}
接下来再通过yarn build打包即可看到我们的输出目录多了一个「styles」文件夹,里面是我们抽离出来的CSS文件,但我们却看到CSS文件并没有被压缩,为了压缩输出的CSS文件,我们需要css-minimizer-webpack-plugin这个插件来帮忙。安装插件:
yarn add css-minimizer-webpack-plugin -D
在 webpack.config.pred.js中做如下添加如下配置:
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
// ...
module.exports = {
// ....
// 优化配置
optimization: {
minimizer: [
new CssMinimizerPlugin(),
],
},
}
接下来再通过yarn build打包即可看到我们的输出「styles」文件里面的CSS文件已经被压缩了。
2. 使用 CSS modules
当开发人员命名的类有冲突时,后面的样式会覆盖前面的样式。
那么该如何解决呢?当然你可以选择命名的时候避免冲突,还有一种方法便是使用 CSS modules,这里便不再详细介绍它了,只讲如何配置环境。
首先,我们需要先改变引用的方式:
src/index.module.css
.h1 {
background-color: red;
}
scr/index.tsx
import React from "react";
import ReactDOM from "react-dom";
import index from './index.module.css'
const App = () => (
<h1 className={index.h1}>Hello World!</h1>
)
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
可以看到 import 语句跟原来的略有不同。我们通过引用.module.css后缀的文件,并从中导入为一个变量
这个变量是一个对象,包含了对应样式文件的所有CSS类名称, 然后在组件中引用对应的类名变量。我们还需要将index.css重命名为index.module.css。
但是TypeScript 编译出现错误 “无法找到模块'.module.css'或对应的类型声明”错误,因为 TS 无法解析CSS modules

为了解决这个错误,我们需要创建一个src/typings.d.ts类型声明文件并加入以下内容:
declare module "*.module.css";
之后重启应用,再次查看界面效果,就可以看见正常了:


我们看到 CSS类名称被赋予了一个看起来很随机的名称。因为这样可以确保不同组件中的样式名称不会冲突。
通过上述方法,每次都需要通过 *.module.css的方式实现 CSS modules 不免有些麻烦。其实,我们可以通过修改 Webpack 配置简化 CSS modules 的写法。
在webpack.config.dev.js中我们做如下修改:
module: {
rules: [
...,
{
test: /.css$/i,
use: ["style-loader", {
loader: "css-loader",
options: {
modules: true,
},
}],
},
],
},
在webpack.config.prod.js中我们做如下修改:
module: {
rules: [
...,
{
test: /.css$/i,
use: [MiniCssExtractPlugin.loader, {
loader: "css-loader",
options: {
modules: true,
},
}],
},
],
},
修改typings.d.ts 的配置:
declare module "*.css";
这样,我们就可以以如下方式进行使用了:
代码语言:javascript复制import React from "react";
import ReactDOM from "react-dom";
import index from './index.css'
const App = () => (
<h1 className={index.h1}>Hello World!</h1>
)
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
3. 配置 Less
如果你想在项目中使用less,那么我们就需要less-loader这个工具。
首先,我们先安装一下:
代码语言:javascript复制yarn add less less-loader -D
在webpack.config.dev.js中我们做如下修改:
module: {
rules: [
...,
{
test: /.less$/i,
use: ["style-loader", {
loader: "css-loader",
options: {
modules: true,
},
}, 'less-loader'],
},
],
},
在webpack.config.prod.js中我们做如下修改:
module: {
rules: [
...,
{
test: /.less$/i,
use: [MiniCssExtractPlugin.loader, {
loader: "css-loader",
options: {
modules: true,
},
}, 'less-loader'],
},
],
},
同时,为了配合 CSS modules,我们需要在typings.d.ts 中加入以下内容,否则 Typescript无法识别 Less 类型:
declare module "*.less";
如此,我们就可以在项目中使用Less了。
4. 配置 Sass
接下来我们看看如何配置 Sass,其实与 Less 的设置方式是类似的。
如果你想在项目中使用Sass,那么我们就需要sass-loader这个工具。
首先,我们先安装一下:
代码语言:javascript复制yarn add sass sass-loader -D
在webpack.config.dev.js中我们做如下修改:
module: {
rules: [
...,
{
test: /.s[ac]ss$/i,
use: ["style-loader", {
loader: "css-loader",
options: {
modules: true,
},
}, 'sass-loader'],
},
],
},
在webpack.config.prod.js中我们做如下修改:
module: {
rules: [
...,
{
test: /.s[ac]ss$/i,
use: [MiniCssExtractPlugin.loader, {
loader: "css-loader",
options: {
modules: true,
},
}, 'sass-loader'],
},
],
},
同时,为了配合 CSS modules,我们需要在typings.d.ts 中加入以下内容,否则 Typescript无法识别 sass 和 scss 类型:
declare module "*.sass";
declare module "*.scss";
如此,我们就可以在项目中使用Sass了。
这样以来,我们的项目环境就集成 css、less 与sass,同时还支持css module。


