webpack 之 一个简单的基本生产环境配置
阅读原文时间:2023年07月09日阅读:2

webpack 之 一个简单的基本生产环境配置

// 用来拼接绝对路径的方法
const {resolve} = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin') 

// 代码复用loader
const commonCssLoader = [
    // 创建 style 标签,将js中的样式资源插入进行,添加到 head 中生效
    // 'style-loader',
    // 这个 loader 取代 style-loader 。作用:提取js中的css成单独文件
    MiniCssExtractPlugin.loader,
    // 将css文件变成commonjs 模块加载js中, 里面内容是样式字符串
    'css-loader'
]

module.exports = {
    // webpack 配置
    // 入口起点
    entry : './src/index.js',
    // 输出
    output : {
        // 输出文件名
        filename : 'js/built.js',
        // 输出路径
        path : resolve(__dirname, 'dist')
    },
    // loader 配置
    module : {
        rules : [
            {
                test : /\.css$/, // 匹配哪些文件
                //使用哪些 loader 进行处理
                use: [
                    // use 数组中的 loader 执行顺序:从右到左,从下到上依次执行
                    ...commonCssLoader
                ]
            },
            {
                test : /\.less$/,
                use: [
                    ...commonCssLoader,
                    'less-loader'
                ]
            },
            /*
                正常来讲,一个文件只能被一个loader 处理。
                当一个文件被多个loader 处理,那么一定要指定loader执行的先后顺序
                    先执行eslint 再执行babel
            */
            /*
                语法检查:eslint-loader eslint
                    注意:只检查自己写的源代码,第三方的库是不用检查的
                    设置检查规则:
                        package.json 中的 eslintConfig 中的设置
                            "eslintConfig": {
                                "extends": "airbnb-base"
                            }
                        airbnb 规则
                        1. eslint eslint-config-airbnb-base  eslint-plugin-import  (without React plugins)
                        2. eslint eslint-plugin-import, eslint-plugin-react, eslint-plugin-react-hooks, and eslint-plugin-jsx-a11y (including ECMAScript 6+ and React)
            */
            {
                test : /\.js$/,
                exclude : /node_modules/,
                loader: 'eslint-loader',
                // 优先执行
                enforce: 'pre',
                options: {
                    // 自动修复 eslint 的错误
                    fix: true
                }
            },
            /*
                js 兼容性处理:babel-loader @babel/core @babel/preset-env
                    1. 基本js兼容性处理 --> @babel/preset-env
                        问题:只能转换基本语法,如Promise不能转换
                    2. 全部js兼容性处理 --> @babel/polyfill   使用时直接在js文件里面引入:import '@babel/polyfill'
                        问题:我只要解决部分兼容性问题,但是将所有兼容性代码全部引入,体积太大了
                    3. 需要做兼容性处理的就做:按需加载 --> core-js
            */
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
                options: {
                    // 预设:指示babel做怎样的兼容性处理
                    presets: [
                        [
                            '@babel/preset-env',
                            {
                                // 按需加载
                                useBuiltIns: 'usage',
                                // 指定 core-js版本
                                corejs: {
                                    version: 3
                                },
                                // 指定兼容性做到哪个版本浏览器
                                targets: {
                                    chrome: '60',
                                    firefox: '60',
                                    ie: '9',
                                    safari: '10',
                                    edge: '17'
                                }
                            }
                        ]
                    ]
                }
            },
            {
                // 问题:默认处理不了 html 中 img 图片
                // 处理图片资源
                test : /\.(jpg | png | gif)$/,
                // 使用一个 loader, 可以不要use数组,可以直接指定
                // 除了要下载 url-loader 还要下载 file-loader
                loader : 'url-loader',
                options : {
                    // 图片大小小于 8kb , 就会被base64 处理
                    // 优点:减少请求数量(减轻服务器压力)
                    // 缺点:图片体积会更大(文件请求速度更慢)
                    limit : 8 * 1024,
                    // 问题:因为url-loader 默认使用es6模块化解析,而html-loader引入图片是commonjs
                    // 解析是会出现问题:[object Module]
                    // 解决:关闭 url-loader 的es6模块化,使用commonjs解析
                    esModule : false,
                    // 给图片进行重命名
                    // [hash:10]取图片的hash的前10位
                    // [ext] 取文件原来拓展名
                    name : '[hash:10].[ext]'
                }
            },
            {
                test : /\.html$/,
                // 处理 html 文件的img图片(负责引入img,从而能被url-loader进行处理)
                loader : 'html-loader'
            },
            {
                exclude: /\.(js | css | less | html | jpg | png | gif)/,
                loader: 'file-loader',
                options: {
                    outputPath: 'media'
                }
            }
        ]
    },
    // plugins 的配置
    plugins : [
        // 详细 plugins 的配置
        // html-webpack-plugin
        // 功能:默认会创建一个空的html文件,自动引入打包输出的所有资源(js/css)
        new HtmlWebpackPlugin({
            // 增加一个配置
            // 复制 './src/index.html' 文件,并自动引入打包输出的所有资源(js/css)
            template : './src/index.html',
            // 压缩html资源
            minify: {
                collapseWhitespace: true,   //去空格
                removeComments: true    // 去注释

            }
        }),
        new MiniCssExtractPlugin({
            // 输出文件名
            filename: 'css/bulit.css'
        }),
        // 压缩css
        new OptimizeCssAssetsWebpackPlugin()
    ],
    //模式
    // mode : 'development', // 开发模式
    mode : 'production' // 生产模式

}