webpack优化环境配置 - 20.oneOf

oneOf的作用
提升构建速度,避免每个文件都被所有loader过一遍,
因为任何一个文件,构建过程中,在遇到第一个与之对应的loader后,不会再往下进行。
在webpack.config.js 中配置 oneOf

 

 1.文件结构

 

 

 2.代码

webpack.config.js

const {resolve} = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
//提取 js 中的 css 成单独文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

//压缩css
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')

// 定义nodejs环境变量:决定使用browserslist的哪个环境
process.env.NODE_ENV = 'production';

//复用 loader
const commonCssLoader = [
    // 这个 loader 取代 style-loader。作用:提取js中的css成单独文件
    //MiniCssExtractPlugin.loader 加载不了 less文件中的图片,记录一下坑,使用"style-loader"可以加载。。。
    MiniCssExtractPlugin.loader,
    //如果只使用loader的默认配置,就直接写字符串,会默认加载。
    'css-loader',

    // css兼容性处理
    //如果要修改配置,就使用对象的形式
    {
        // 还需要在package.json中定义browserslist
        loader: "postcss-loader",
        options: {
            ident: "postcss",
            plugins: () => [
                // postcss的插件
                require('postcss-preset-env')()
            ]

        }
    }
]
module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: "js/built.js",
        path: resolve(__dirname, "build")
    },
    module: {
        rules: [
            /*
                但是,实际开发过程中,同样会有一个文件需要匹配多个loader的场景,
                比如js文件同时需要eslint-loader和babel-loader,这样的话就不能将两个loader都放到oneOf里面,
                因为一旦匹配了第一个loader就不会再继续执行第二个loader,解决办法也很简单,只需要放到oneOf外面即可。
            */
            // js语法检查(eslint)
            {
                // 在package.json中eslintConfig --> airbnb
                test: /\.js$/,
                exclude: /node_modules/,
                //当一个文件要被多个loader处理,添加 enforce: "pre",会被优先执行
                enforce: "pre",
                loader: "eslint-loader",
                options: {
                    //自动修复eslint的错误
                    fix: true,
                }
            },
            {
                /*
                    在webpack对文件打包或者构建的时候,都会将rules里所有的规则都过一遍,这样会影响构建性能,
                    因为单个文件只会匹配rules里的单条规则,匹配上了就没必要继续匹配,所以这里就用到了oneOf来处理这个问题。

                    oneOf的作用
                        提升构建速度,避免每个文件都被所有loader过一遍,
                        因为任何一个文件,构建过程中,在遇到第一个与之对应的loader后,不会再往下进行。
                */
                oneOf: [
                    {
                        test: /\.css$/,
                        use: [...commonCssLoader]
                    },
                    {
                        test: /\.less$/,
                        use: [...commonCssLoader, 'less-loader']
                    },
                    /*
                        正常来讲,一个文件只能被一个loader处理。
                        当一个文件要被多个loader处理,那么一定要指定loader执行的先后顺序:
                          先执行eslint 再执行babel
                      */
                    //js兼容性处理
                    {
                        test: /\.js$/,
                        exclude: /node_modules/,
                        loader: "babel-loader",
                        options: {
                            presets: [
                                [
                                    //@babel/preset-env: 基本js兼容性处理
                                    '@babel/preset-env',
                                    {
                                        //按需处理
                                        //按需加载
                                        useBuiltIns: 'usage',
                                        //指定 core-js 版本
                                        corejs: {
                                            version: 3
                                        },
                                        //指定兼容性做到哪个版本
                                        targets: {
                                            chrome: '60',
                                            firefox: '60',
                                            ie: '9',
                                            safari: '10',
                                            edge: '17'
                                        }
                                    }
                                ]
                            ]
                        }
                    },
                    // 打包图片资源
                    {
                        test: /\.(jpg|png|gif)$/,
                        loader: 'url-loader',
                        options: {
                            limit: 8 * 1024,
                            name: '[hash:10].[ext]',
                            outputPath: 'imgs',
                            esModule: false
                        }
                    },
                    // 打包html资源
                    {
                        test: /\.html$/,
                        loader: 'html-loader'
                    },
                    // 打包其它资源
                    {
                        exclude: /\.(js|css|less|html|png|jpg|gif)$/,
                        loader: "file-loader",
                        options: {
                            outputPath: "media"
                        }
                    }
                ]
            }
        ]
    },
    plugins: [
        //提取 js 中的 css 成单独文件
        new MiniCssExtractPlugin({
            //对输出文件名进行重命名
            filename: 'css/built.css'
        }),
        //压缩 css
        new OptimizeCssAssetsWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: "./src/index.html",
            //压缩 html 代码
            minify: {
                // 移除空格
                collapseWhitespace: true,
                // 移除注释
                removeComments: true
            }
        })
    ],
    mode: 'production'
}

end~

 

 

 

 

 
posted @ 2022-09-08 16:47  Evengod  阅读(174)  评论(0编辑  收藏  举报