zzxworld

Webpack 5 项目添加 CSS 打包支持

最近半个月的时间一直在使用 React 重写一个内部进销存系统的前端页面功能。在脱离了 Laravel 框架的前提下,前端的很多基础配置都需要自己来解决。这其中就包括 CSS 代码的打包。

半个月前开始调研使用 React 的时候,我已经实现了基于 React router 的项目框架,包括登录认证。其中的过程我都整理成了如下的三篇文章:

如果你还不了解 React,相信这些文章应该能给你带来一些参考和帮助。不过这三篇文章的主要目的是验证 React 是否能够满足我的喜好,并投入到实际的项目中,所以少了前端样式方面的配置。今天这篇算是一个补充和完善。

作为以上三篇文章的番外篇,本文依然还是延续之前的项目目录和结构,对于这方面不是很清楚的朋友建议先翻阅一下以上文章。

让我们开始。

添加 CSS 支持

首先是给项目添加纯 CSS 代码的打包支持。同样是使用 yarn 命令来安装依赖包:

yarn add css-loader style-loader

然后在 webpack.config.js 文件中补充 CSS 相关的配置:

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    mode: 'development',
    devServer: {
        host: 'localhost',
        port: 8000,
        hot: true
    },
    entry: './src/main.js',
    output: {
        filename: '[name].[hash].js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            },
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'public/index.html'
        })
    ]
}

上面的配置中,添加代码就是 module > rules 节点下,内容包含 test: /\.css$/ 的这部分。现在就可以在项目的 src/ 目录下创建一个 CSS 文件, 然后在 src/main.js 文件中用 import 引用这个 CSS 文件,就能在项目中使用 CSS 样式功能了。

// ...
import './main.css';
// ...

不过这样输出的 CSS 代码是包含在 style 这个 HTML 标签里面的。如果希望 CSS 能输出到一个文件,还需要做一些配置上的调整。

输出 CSS 文件

还是使用 yarn 命令安装一个扩展包:

yarn add mini-css-extract-plugin

然后打开 webpack.config.js 文件,引入新安装的 mini-css-extract-plugin 扩展包,并修改 CSS 的 Rule 配置,完成后的代码如下:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    mode: 'development',
    devServer: {
        host: 'localhost',
        port: 8000,

    },
    entry: './src/main.js',
    output: {
        filename: '[name].[hash].js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].[hash].css',
        }),
        new HtmlWebpackPlugin({
            template: 'public/index.html'
        })
    ]
}

再次重新打包,CSS 代码就输出到单独的文件了。

单从使用 CSS 的目的来说,目前这样就算是完成了项目对 CSS 打包功能的支持。不过如果你和我一样,早已习惯了使用 SASS 来写样式代码,那添加一下 SASS 代码的转译支持也是很有必要的。

添加 SASS 转译支持

同样先引入 SASS 功能依赖的扩展包:

yarn add sass-loader sass

然后再次修改 webpack.config.js 文件:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    mode: 'development',
    devServer: {
        host: 'localhost',
        port: 8000,
        hot: true
    },
    entry: './src/main.js',
    output: {
        filename: '[name].[hash].js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            },
            {
                test: /\.(c|sc|sa)ss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'sass-loader'
                ]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: '[name].[hash].css',
        }),
        new HtmlWebpackPlugin({
            template: 'public/index.html'
        })
    ]
}

这次的调整主要就是 CSS 的 Rule 部分。一是 test 文件名匹配部分把 scss 和 sass 也包含了进来;二是在 use 节点添加了 sass-loader

现在算是真正完成了项目对 CSS 样式的支持。在实际使用时有一个值得注意的关键点,来看看下面这两句 CSS 代码:

@import url('./head.scss');
@import './head.scss';

知道它俩有什么区别吗?

答案就是第一行是 CSS 引入其他文件的语法,如果这样引入一个包含 SASS 格式的文件,里面 SASS 格式的样式代码不会被 Webpack 转译,所以一定要使用最第二行的写法。我就是因为没注意这个细节,结果掉坑里了,导致花费了个把钟头的时间去反复测试 Webpack 的配置项。

最后,目前半个月的 React 使用体验让我感觉非常棒。和 Vue.js 给我的体验相比属于是接触另外一种全新的理念。我也很享受这种理念带来的开发体验,也许等这次项目重写完成后,我会分享一下自己使用 React 开发的感受。如果你还没尝试过 React,我十分建议你体验一下。