webpack 详细配置

134 阅读2分钟

webpack 详细配置

1. package.json 目录

{
  "name": "webpack_test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.16.7",
    "@babel/preset-env": "^7.16.8",
    "babel-loader": "^8.2.3",
    "core-js": "^3.20.2",
    "css-loader": "^6.5.1",
    "css-minimizer-webpack-plugin": "^3.3.1",
    "eslint": "^7.32.0",
    "eslint-config-airbnb-base": "^15.0.0",
    "eslint-loader": "^4.0.2",
    "eslint-plugin-import": "^2.25.4",
    "file-loader": "^6.2.0",
    "html-loader": "^3.1.0",
    "html-webpack-plugin": "^5.5.0",
    "less": "^4.1.2",
    "less-loader": "^10.2.0",
    "mini-css-extract-plugin": "^2.4.7",
    "postcss-loader": "^6.2.1",
    "postcss-preset-env": "^7.2.3",
    "style-loader": "^3.3.1",
    "url-loader": "^4.1.1",
    "webpack": "^5.66.0",
    "webpack-cli": "^4.9.1",
    "webpack-dev-server": "^4.7.3"
  },
  "browserslist": {
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ],
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ]
  },
  "eslintConfig": {
    "extends": "airbnb-base"
  }
}

2.webpack 开发环境配置

const { resolve } = require("path");   // 引入 Nodejs  path模块
const HtmlWebpackPlugin = require('html-webpack-plugin');  // 引入打包 HTML 的插件

module.exports = {
    entry: "./src/js/index.js", // 开始打包的入口文件
    output: {
        filename: 'js/main.js',   // 输出文件名
        path: resolve(__dirname, 'build') // 输出文件路径
    },
    module: { // 使用loader处理各种资源
        rules: [
            // 1. 处理 css 资源
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            // 2. 处理 less 资源
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'less-loader']
            },
            // 3. 处理 样式文件中引入 的图片资源
            {
                test: /\.(jpg|png|gif)$/,
                loader: 'url-loader',  // url-loader 依赖于 file-loader
                options: {
                    limit: 8 * 1024,  // 8kb 以下的图片 会被打包成 base64,减少请求服务器的次数
                    esModule: false,  // 关闭 es6 导入语法,使用 commonjs语法
                    name: "[hash:10].[ext]",  // 打包后的文件名: 哈希前10位 + 文件格式
                    outputPath: 'imgs'    // 打包后的输出路径
                },
                type: 'javascript/auto'  // webpack 5.0以上版本  必须加

            },
            // 4. 处理 HTML中引入 的图片资源
            {
                test: /\.html$/,
                use: 'html-loader'
            },
            // 5. 处理其他资源
            {
                exclude: /\.(js|css|less|html|jpg|png|gif)$/,
                loader: 'file-loader',
                options: {
                    name: "[hash:10].[ext]",
                    outputPath: 'media/'
                }
            },
        ]
    },
    plugins: [  //插件
        new HtmlWebpackPlugin({
            template: './src/index.html'  // 打包什么位置的 HTML
        })
    ],
    mode: 'development', // 开发模式

    devServer: {
        static: {
            directory: resolve(__dirname, 'build')
        },
        port: 3000,
        compress: true, // 是否开启 gzip
        open: true,     // 是否自动打开浏览器
        watchFiles: ['./src/index.html']   // 监听该文件的变化,一旦变化全局刷新
    }
}

3.webpack 生产环境配置

const { resolve } = require('path');  // 引入node核心模块 path

// 直接为项目生成一个HTML文件,并将webpack打包后输出的所有脚本文件自动添加到插件生成的HTML文件中
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 提取css成单独文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 压缩css代码插件
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin')


// 复用 loader (css文件 抽离、兼容性处理)
const commonCssLoader = [
    // 'style-loader'创建style标签,将样式放入
    // 这个loader取代style-loader。作用:提取js中的css成单独文件,最终将以link标签注入到HTML中
    MiniCssExtractPlugin.loader, // 将 css从js中单独抽离出来
    // 将css文件整合到js文件中
    'css-loader',
    /* 
   css兼容性处理:postcss -->postcss-loader  postcss-preset-env
   帮postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式
    "browserslist": {
       开发环境 --> 设置node环境变量:process.env.Node_ENV = 'development'
       "development": [
       "last 1 chrome version",
       "last 1 firefox version",
       "last 1 safari version"
       ],
       
       生产环境:默认是看生产环境
       "production": [
       ">0.2%",
       "not dead",
       "not op_mini all"
       ]
   }
   */
    // 使用loader的默认配置
    // postcss-loader
    // 修改loader的配置项
    {
        loader: "postcss-loader",
        // webpack 5.0 配置
        options: {
            postcssOptions: {
                plugins: ['postcss-preset-env']
            }
        }
    }
]

// 设置Nodejs 环境变量
process.env.NODE_ENV = 'development'

module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'js/mini.js',
        path: resolve(__dirname, 'build')
    },
    module: {
        rules: [
            // 处理 css文件
            {
                test: /\.css$/,
                use: [...commonCssLoader]
            },
            // 处理 less文件
            {
                test: /\.less$/,
                use: [...commonCssLoader, 'less-loader']
            },
            // 注意:对同一格式的文件同时只能有一个loader来执行,先eslint-loader后babel-loader
            // js 语法/格式检查(eslint)
            {
                /* 
                  语法检查:eslint-loader eslint
                  注意:只检查自己写的源代码,第三方库不用检查
                  设置检查规则:
                  package.json 中 edlintConfig中设置
                  "eslintConfig": {
                      "extends":"airbnb-base" // eslint的校验规则
                  }
                  airbnb --> eslint-config-airbnb-base  eslint-plugin-import  eslint
                */
                test: /\.js$/,
                exclude: /node_modules/,
                // 优先执行
                enforce: 'pre',
                loader: 'eslint-loader',
                options: {
                    // 自动修复eslint的错误
                    fix: true
                }
            },
            // 处理 js兼容性
            {
                /* 
                    js兼容性处理:babel-loader  @babel/core  @babel/preset-env
                    1. 基本js兼容性处理 --> @babel/preset-env
                        问题:只能转换基本语法,如promise不能转换
                    2. 全部js兼容性处理 --> @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'
                                }
                            }
                        ]
                    ],
                }
            },
            // 处理 样式文件中引入的图片资源
            {
                test: /\.(jpg|png|gif)$/,
                // 下载 url-loader 和 file-loader (前者依赖于后者)
                // 使用单个 loader 时,使用 loader: ''
                loader: 'url-loader',
                options: {
                    // 图片小于 8kb,就会被base64处理
                    // 优点:减少请求数量(减轻服务器压力)
                    // 缺点:图片体积会更大(文件请求速度更慢)
                    limit: 8 * 1024,
                    // 问题: 因为 url-loader 默认使用es6模块化解析,而 webpack 引入图片是 commonjs
                    // 解决: 关闭 url-loader 的es6模块化,使用commonjs
                    esModule: false,
                    // 给图片进行重命名
                    // [hash:10] 取图片的hash的前10位
                    // [ext] 取文件原来的扩展名
                    name: '[hash:10].[ext]',
                    // 打包后的输出路径
                    outputPath: 'imgs'
                },
                // url-loader 和 file-loader  在 webpack 5.0v以上的版本已经被弃用,需要加上以下
                type: 'javascript/auto'
            },
            // 处理html 文件中引入的img图片(负责引入img,从而能被 url-loader进行处理)
            {
                test: /\.html$/,
                use: 'html-loader'
            },
            // 处理其他资源
            {
                exclude: /\.(js|css|less|html|jpg|png|gif)$/,
                loader: 'file-loader',
                options: {
                    name: "[hash:10].[ext]",
                    outputPath: 'media'
                }
            },

        ]
    },
    plugins: [
        // 压缩css
        new CssMinimizerWebpackPlugin(),
        // 抽离css文件
        new MiniCssExtractPlugin({
            // 打包抽离输出的 css文件重命名
            filename: 'css/main.css'
        }),
        // 处理html文件
        new HtmlWebpackPlugin({
            template: './src/inde.html',
            // 压缩html
            minify: {
                // 移除空白行
                collapseWhitespace: true,
                // 删除注释
                removeComments: true
            }
        }),
    ],
    // 开发模式下自动压缩js代码
    mode: 'production'
}