webpack advanced configuration

Table of contents

1. Configure multiple entries

1.1 entry configuration

1.2 Production environment output configuration

1.3 plugins entry html file configuration

2. Extract CSS files

2.1 Introduce mini-css-extract-plugin

2.2 Using MiniCssExtractPlugin.loader

2.3 Extract CSS files 

2.4 Minify CSS files

3. Separate public code and third-party code

3.1 Configure splitChunks under optimization

3.2 Configure the HtmlWebpackPlugin plugin

4. Lazy loading

5. Processing JSX

5.1 Install babel/preset-react

5.2 Configure.babelrc

5.3 Configure babel-loader to parse js syntax

6. Handling Vue

6.1 Install vue-loader

6.2 Configure vue-loader


1. Configure multiple entries

1.1 entry configuration

// webpack.common.js

entry: {
        index: path.join(srcPath, 'index.js'),
        other: path.join(srcPath, 'other.js')
    },

1.2 Production environment output configuration

  • When packaging the code, add a hash stamp
  • name is the key of multi-entry entry
  • CleanWebpackPlugin cleans up the packaged content before each package
// webpack.prod.js

output: {
        // filename: 'bundle.[contentHash:8].js',  // 打包代码时,加上 hash 戳
        filename: '[name].[contentHash:8].js', // name 即多入口时 entry 的 key
        path: distPath,
    },
plugins: [
        new CleanWebpackPlugin(), // 会默认清空 output.path 文件夹
        new webpack.DefinePlugin({
            // window.ENV = 'production'
            ENV: JSON.stringify('production')
        })
    ]

1.3 plugins entry html file configuration

  • Generate multiple instances of HtmlWebpackPlugin
  • chunks indicates which chunks (namely entry's index and other) to be referenced by the page, and all are referenced by default
// webpack.common.js

plugins: [
        // new HtmlWebpackPlugin({
        //     template: path.join(srcPath, 'index.html'),
        //     filename: 'index.html'
        // })

        // 多入口 - 生成 index.html
        new HtmlWebpackPlugin({
            template: path.join(srcPath, 'index.html'),
            filename: 'index.html',
            // chunks 表示该页面要引用哪些 chunk (即上面的 index 和 other),默认全部引用
            chunks: ['index']  // 只引用 index.js
        }),
        // 多入口 - 生成 other.html
        new HtmlWebpackPlugin({
            template: path.join(srcPath, 'other.html'),
            filename: 'other.html',
            chunks: ['other']  // 只引用 other.js
        })
    ]

2. Extract CSS files

  • In the development environment, use style-loader to inject into the page through the <style> tag, no problem 
  • In the production environment, the CSS file should be extracted and compressed, otherwise the package will package the CSS file into the JS file, and the volume will be relatively large. (Execute this JS and then parse the CSS and stuff it into HTML, which is not good in performance)
  • mini-css-extract-plugin

2.1 Introduce mini-css-extract-plugin

// webpack.prod.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin')

2.2 Using MiniCssExtractPlugin.loader

// webpack.prod.js

module: {
        rules: [
            // 图片 - 考虑 base64 编码的情况
            {
                test: /\.(png|jpg|jpeg|gif)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        // 小于 5kb 的图片用 base64 格式产出
                        // 否则,依然延用 file-loader 的形式,产出 url 格式
                        limit: 5 * 1024,

                        // 打包到 img 目录下
                        outputPath: '/img1/',

                        // 设置图片的 cdn 地址(也可以统一在外面的 output 中设置,那将作用于所有静态资源)
                        // publicPath: 'http://cdn.abc.com'
                    }
                }
            },
            // 抽离 css
            {
                test: /\.css$/,
                loader: [
                    MiniCssExtractPlugin.loader,  // 注意,这里不再用 style-loader
                    'css-loader',
                    'postcss-loader'
                ]
            },
            // 抽离 less --> css
            {
                test: /\.less$/,
                loader: [
                    MiniCssExtractPlugin.loader,  // 注意,这里不再用 style-loader
                    'css-loader',
                    'less-loader',
                    'postcss-loader'
                ]
            }
        ]
    },

2.3 Extract CSS files 

// webpack.prod.js

plugins: [
        new CleanWebpackPlugin(), // 会默认清空 output.path 文件夹
        new webpack.DefinePlugin({
            // window.ENV = 'production'
            ENV: JSON.stringify('production')
        }),

        // 抽离 css 文件
        new MiniCssExtractPlugin({
            filename: 'css/main.[contentHash:8].css'
        })
    ],

2.4 Minify CSS files

  • terser-webpack-plugin
  • optimize-css-assets-webpack-plugin
// webpack.prod.js

const TerserJSPlugin = require('terser-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')

optimization: {
        // 压缩 css
        minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
    }

3. Separate public code and third-party code

  • Common code : In the case of multiple entry files, if the same module is introduced in each entry file, then this module will be packaged repeatedly when packaging, which is unnecessary.
  • Third-party code : Every time you change your own code, repackage and generate a new hash file name, but the third-party package (such as lodash) has not changed, and there is no need to repackage (just use the cache).

3.1 Configure splitChunks under optimization

chunks has three option values 

  1. initial entry chunk, not processed for asynchronously imported files
  2. async asynchronous chunk, only for files imported asynchronously
  3. all all chunks
// webpack.prod.js

optimization: {
        // 压缩 css
        minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],

        // 分割代码块
        splitChunks: {
            chunks: 'all',
            /**
             * initial 入口 chunk,对于异步导入的文件不处理
                async 异步 chunk,只对异步导入的文件处理
                all 全部 chunk
             */

            // 缓存分组
            cacheGroups: {
                // 第三方模块
                vendor: {
                    name: 'vendor', // chunk 名称
                    priority: 1, // 权限更高,优先抽离,重要!!!
                    test: /node_modules/,
                    minSize: 0,  // 大小限制,太小就不用单独打包了
                    minChunks: 1  // 最少复用过几次
                },

                // 公共的模块
                common: {
                    name: 'common', // chunk 名称
                    priority: 0, // 优先级
                    minSize: 0,  // 公共模块的大小限制
                    minChunks: 2  // 公共模块最少复用过几次
                }
            }
        }
    }

3.2 Configure the HtmlWebpackPlugin plugin

  • chunks indicates which chunks are to be referenced by the page, and which ones need to be imported
// webpack.common.js

plugins: [
        // 多入口 - 生成 index.html
        new HtmlWebpackPlugin({
            template: path.join(srcPath, 'index.html'),
            filename: 'index.html',
            // chunks 表示该页面要引用哪些 chunk (即上面的 index 和 other),默认全部引用
            chunks: ['index', 'vendor', 'common']  // 要考虑代码分割
        }),
        // 多入口 - 生成 other.html
        new HtmlWebpackPlugin({
            template: path.join(srcPath, 'other.html'),
            filename: 'other.html',
            chunks: ['other', 'common']  // 考虑代码分割
        })
    ]

4. Lazy loading

  • import Dynamic import, similar to Vue asynchronous components
// index.js

// 引入 css
import './style/style1.css'
import './style/style2.less'

import { sum } from './math'

const sumRes = sum(10, 20)
console.log('sumRes', sumRes)


// 引入动态数据 --- 懒加载
setTimeout(() => {
  import('./dynamic-data.js').then(res => {
    console.log(res.default.message)
  })
}, 1500)

5. Processing JSX

5.1 Install babel/preset-react

npm install --save-dev @babel/preset-react

5.2 Configure.babelrc

// .babelrc

{
    "presets": ["@babel/preset-react"],
    "plugins": []
}

5.3 Configure babel-loader to parse js syntax

// webpack.common.js

module: {
        rules: [
            {
                test: /\.js$/,
                loader: ['babel-loader'],
                include: srcPath,
                exclude: /node_modules/
            }
        ]
    },

6. Handling Vue

6.1 Install vue-loader

npm install -D vue-loader vue-template-compiler

6.2 Configure vue-loader

module: {
        rules: [
            {
                test: /\.vue$/,
                loader: ['vue-loader'],
                include: srcPath
            }
        ]
    },

Guess you like

Origin blog.csdn.net/weixin_39763711/article/details/126886996