webpack 高级配置

目录

1. 配置多入口

1.1 entry 配置

1.2 生产环境 output 配置

1.3 plugins 入口 html 文件配置

2. 抽离 CSS 文件

2.1 引入 mini-css-extract-plugin

2.2 使用 MiniCssExtractPlugin.loader

2.3 抽离 CSS 文件 

2.4 压缩 CSS 文件

3. 抽离公共代码和第三方代码

3.1 配置 optimization 下的 splitChunks

3.2 配置 HtmlWebpackPlugin 插件

4. 懒加载

5. 处理 JSX

5.1 安装 babel/preset-react

5.2 配置 .babelrc

5.3 配置 babel-loader 解析 js 语法

6. 处理 Vue

6.1 安装 vue-loader

6.2 配置 vue-loader


1. 配置多入口

1.1 entry 配置

// webpack.common.js

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

1.2 生产环境 output 配置

  • 打包代码时,加上 hash 戳
  • name 即多入口 entry 的 key
  • CleanWebpackPlugin 每次打包前,清理之前打包内容
// 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 入口 html 文件配置

  • 生成多个 HtmlWebpackPlugin 实例
  • chunks 表示该页面要引用哪些 chunk (即 entry 的 index 和 other),默认全部引用
// 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. 抽离 CSS 文件

  • 开发环境下使用 style-loader 通过 <style> 标签注入到页面,没问题 
  • 生产环境下要抽离并压缩 CSS 文件,不然打包会把 CSS 文件打包到 JS 文件中,体积会比较大。(执行这个 JS 再把 CSS 解析出来,塞到 HTML 中,这样性能并不好)
  • mini-css-extract-plugin

2.1 引入 mini-css-extract-plugin

// webpack.prod.js

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

2.2 使用 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 抽离 CSS 文件 

// 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 压缩 CSS 文件

  • 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. 抽离公共代码和第三方代码

  • 公共代码:在多入口文件的情况下,如果在每个入口文件中都引入了相同的模块,那么打包时,就会将这个模块重复打包进去,这是没有必要的。
  • 第三方代码:每次更改了自己的代码,重新打包,生成了新的 hash 文件名,而第三方包(如lodash)并没有改变,不需要重新打包(使用缓存即可)。

3.1 配置 optimization 下的 splitChunks

chunks 有三个选项值 

  1. initial 入口 chunk,对于异步导入的文件不处理
  2. async 异步 chunk,只对异步导入的文件处理
  3. all 全部 chunk
// 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 配置 HtmlWebpackPlugin 插件

  • chunks 表示该页面要引用哪些 chunk,需要哪些引入哪些
// 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. 懒加载

  • import 动态引入,类似 Vue 异步组件
// 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. 处理 JSX

5.1 安装 babel/preset-react

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

5.2 配置 .babelrc

// .babelrc

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

5.3 配置 babel-loader 解析 js 语法

// webpack.common.js

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

6. 处理 Vue

6.1 安装 vue-loader

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

6.2 配置 vue-loader

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值