从零构建React项目(二):webpack 配置

901 阅读2分钟

上一篇文章中,只是添加了webpack最基本的配置,所以在这片文章中详细的记录一下webpack常见的一些配置及优化内容。

1. loader

1.1 loader的使用

  • test: 匹配处理文件扩展名的的正则表达式;
  • use: 指定处理文件时要使用的模块名称;
  • include: 指定必须要处理的文件夹;
  • exclude: 指定需要屏蔽的文件夹;
  • options: 为loader提供额外的配置选项。
  • 默认的loader执行顺序是从后往前进行执行,也可以通过手动定义顺序。

1.2 css处理相关loader及配置

在js中引入css进行打包时,会提示无法解析,这时需要使用css相关的loader进行处理

  • css-loader—用于打包css文件,使能够使用类似于@importurl(...)的方法实现require()的功能
  • style-loader—用于将编译完成的css插入页面中
  • 两者组合在一起使用实现将样式表嵌入到打包后的js文件中
yarn add style-loader css-loader -D

添加处理配置

// config/webpack.config.base.js
module: {
    rules: [
        {
            test: /\.css$/,
            use: [
                { loader: "style-loader" },
                { 
                    loader: "css-loader",
                    options: {
                        modules: true // 启用css modules
                    }
                },
            ]
        }
    ]
}

1.3 css预处理器配置

在项目使用.scss.less文件时需要使用对应的预处理器

  • sass: sass-loader node-sass
  • less: less-loader less
  • sass-loader---将sass文件编译成css
  • less-loader---将less文件编译成css 安装相关依赖
yarn add sass-loader node-sass less-loader less -D

添加配置

modules: {
    rules: [
        ...,
        {
            test: /\.sass$/,
            use: [
                { loader: 'style-loader', },
                {
                    loader: 'css-loader',
                    options: {
                        modules: {
                            localIdentName: '[hash:base64:6]',
                        }
                    }
                },
                { loader: 'sass-loader', }
            ]
        },
        {
            test: /\.less$/,
            use: [
                { loader: 'style-loader', },
                {
                    loader: 'css-loader',
                    options: {
                        modules: {
                            localIdentName: '[hash:base64:6]',
                        }
                    }
                },
                { loader: 'less-loader', }
            ]
        }
    ]
}

1.4 静态资源处理

对其他静态资源文件需要相应的loader进行处理

  • file-loader—用于打包文件
  • url-loader—用于打包图片 安装依赖
yarn add file-loader url-loader -D

添加loader配置

// config/webpack.config.base.js
        rules: [
            ...,
            {
                test: /\.jpe?g|png|gif/,   //处理图片
                use:{
                    loader: 'file-loader',
                    options:{
                        name: `img/[name].[ext]`
                    }
                }
            },
            {
                test: /woff|ttf|eot|svg|otf/, // 处理icon
                use:{
                    loader:'file-loader'
                }
            },
            {
                test: /\.jpe?g|png|gif/, // 图片在范围内使用url-loader处理,转化成base64,范围外使用file-loader处理
                use:{
                    loader: 'url-loader',
                    options: {
                        limit: 100 * 1024,
                        name: `img/[name].[ext]`
                    }
                }
            }
        ]

2. 安装webpack plugin

与loader专注于处理资源内容不同,plugin功能更广更强大。plugin可以实现那些loader实现不了或者不适合在loader实现的功能,比如自动生成项目的HTML页面、向构建过程中注入环境变量等。

2.1 html-webpack-plugin

html-webpack-plugin这个插件的作用是生成创建html入口文件,并引入外部资源如script。

yarn add html-webpack-plugin -D

在配置文件中添加

plugins:[ // 需要用到的插件是一个数组,可以配置任意个
    new HtmlWebpackPlugin({
        template:'./index.html', // 模版,需要一个现有的html文件作为模版
        filename:'index.html' // 生成的新的html的文件名
    })
]

2.2 uglifyjs-webpack-plugin

uglifyjs-webpack-plugin插件用于压缩优化js文件,至少需要node v6.9.0webpack V4.0.0版本, webpack 4之前的版本是通过webpack.optimize.CommonsChunkPlugin来压缩js,webpack 4版本之后被移除了,使用config.optimization.splitChunks来代替。

  • 安装依赖
yarn add uglifyjs-webpack-plugin -D
  • 优化配置
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = {
    ...
    plugins: [
        new UglifyJsPlugin({
            uglifyOptions: {
                output: {
                    beautify: false, //不需要格式化
                    comments: false //不保留注释
                },
                compress: {
                    drop_console: true,  //去除打印语句
                },
            }
        }),
    ]
}

2.3 mini-css-extract-plugin

此时在打包好的文件中并没有css,但css却可以正常工作,这是因为webpack没有将css样式从js中取出来,为了方便静态资源管理,充分利用缓存,需要将css单独打包。需要用到mini-css-extract-plugin,支持webpack4+版本。一般用于生产环境,不可与style-loader同时使用。

  • 安装依赖
yarn add mini-css-extract-plugin -D
  • css打包配置
// config/webpack.config.prod.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    ...
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    { loader: "style-loader" },
                    {
                        loader: "css-loader",
                        options: {
                            modules: true // 启用css modules
                        }
                    },
                ]
            },
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            // 相对output.path目录
            filename: "css/[name].css"
        })
    ]
}

2.4 optimize-css-assets-webpack-plugin

optimize-css-assets-webpack-plugin可以将提取处理的css文件进行压缩,减小文件的大小。

  • 安装依赖
yarn add optimize-css-assets-webpack-plugin -D
  • css文件压缩配置
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
    ...
    optimization: {
        minimizer: [
          new OptimizeCssAssetsPlugin({
            assetNameRegExp: /\.css$/g,
            cssProcessor: require('cssnano'),
            cssProcessorOptions: { safe: true, discardComments: { removeAll: true } },
            canPrint: true
          }),
        ],
    }
}

2.5 clean-webpack-plugin

clean-webpack-plugin 用于删除打包的文件及文件夹,因为每次都会生成新的文件,随着打包次数的增多,文件夹会越来越大,也不方便手动删除,使用clean-webpack-plugin插件在每次打包的开始删除之前的文件。

  • 安装依赖
yarn add clean-webpack-plugin -D
  • 清理文件配置
const CleanWebpackPlugin = require('clean-webpack-plugin')

module.exports = {
    ...
    plugins: [
        new CleanWebpackPlugin(['dist'], { 
            root: path.resolve(__dirname, '..'),
            dry: false // 启用删除文件
        }),
        ...
    ]
}