webpack4

该系列文章详细介绍了webpack的配置方法,包括升级到webpack5的注意事项,设置多入口,抽离压缩CSS,代码分割,处理React/Vue应用,模块与chunk的区别,Tree-Shaking优化,以及Babel的使用策略。同时,还涵盖了webpack的性能优化技巧,如自动刷新、热更新和DLLPlugin等。
摘要由CSDN通过智能技术生成

系列文章目录


webpack


前言

目录

系列文章目录

前言

一、webpack5

二、webpack配置多入口

三、抽离压缩css/分割代码chunk

四、异步加载JS

五、处理 react/vue

六、module chunk bundle 区别

七、webpack性能优化

 优化 babel-loader

IgnorePlugin 避免引入无用模块

noParse 避免重复打包

happyPack 多进程打包

ParallelUglifyPlugin 多进程压缩JS

自动刷新

热更新

DllPlugin 动态链接库插件

webpack性能优化

八、Tree-Shaking

九、ES6 Module 和 commonjs 区别

 十、Scope Hosting

 十一、babel

babel-polyfill

babel-runtime

总结


一、webpack5

升级webpack5 以及周边插件后,代码需要做出的调整
package.json 的 dev-server 命令改了
"dev": "webpack server --config build/webpack.dev.js"
升级新版本 const {merge} = require('webpack-merge')
升级新版本 const {CleanWebpackPlugin} = require('clean-webpack-plugin')
`module.rules`中 loader:['xx-loader'] 换成 use:['xx-loader']
filename: 'bundle.[contenthasj:8].js' 其中 ‘h’ 小写,不能大写

loader执行顺序是 从后往前

二、webpack配置多入口

webpack.common.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { srcPath } = require('./paths');

module.exports = {
    entry: {
        index: path.join(srcPath, 'index.js'),
        other: path.join(srcPath, 'other.js')
    },
    module: {
        rules: [

        ]
    },
    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 
            chunks: ['index'] // 只引用 index.js
        }),
        // 多入口-生成 other.html
        new HtmlWebpackPlugin({
            template: path.join(srcPath, 'other.html'),
            filename: 'other.html',
            chunks: ['other'] // 只引用 other.js
        }),
    ]
}
webpack.prod.js

const path = require('path');
const webpack  = require('webpack')
const {CleanWebpackPlugin} = requore('clean-webpack-plugin')
const webpackCommonConf = require('./webpack.common.js')
const { smart } = require('webpack-merge');
const {secPath, distPath } = require('./paths');

module.exports = smart(webpackCommonConf, {
    mode: 'production',
    output: {
        // filename: 'bundle.[contentHash:8].js',
        filename: '[name].[contentHash:8].js', // name即多入口时
        path: distPath,
    },
    module: {
        rules: [
            // 图片-考虑 base64 编码的情况
            {
                test: /\.(png|jpg|jpeg|gif)$/,
                use: {
                    loder: 'url-loader',
                    options: {
                        // 小于 5kb 的图片用 base64 格式产出
                        limit: 5*1024,
                        // 打包到 img 目录下
                        outputPath: './img1/',
                    }
                }
            }
        ]
    },
    plugins: [
        new CleanWebpackPlugin(), // 会默认清空 output.path 文件夹
        new webpack.DefinePlugin({
            // window.ENV = 'production'
            ENV: JSON.stringify('production')
        })
    ]
})

三、抽离压缩css/分割代码chunk

webpack.prod.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserJSPlugin = require('terser-weebpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack');

plugins: [
    new CleanWebpackPlugin(),
    new webpack.DefinePlugin({
        ENV: JSON.stringify('production')
    }),

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

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
            }
        }
    }
}

四、异步加载JS

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

五、处理 react/vue

react preset-react
vue vue-loader

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

六、module chunk bundle 区别

  • module: 各个源码文件,webpack中一切皆模块
  • chunk: 多模块合并成的,如 entry import() splitChunk
  • bundle: 最终的输出文件

七、webpack性能优化

 优化 babel-loader

{
    test: /\.js$/,
    use: ['babel-loader?cacheDirectory'], // 开启缓存
    include: path.resolve(__dirname, 'src'), // 明确范围
    // 排除范围, include 和 exclude 两者选一个即可
    // exclude: path.resolve(__dirname, 'node_modules')
}

IgnorePlugin 避免引入无用模块

// 例如 moment 只引入中文
import moment from 'moment';
import 'moment/locale/zh-cn'; // 手动引入中文语言包
moment.lacale('zh-cn')
console.log('locale', moment.locale())
console.log('locale', moment.format('ll'))

webpack.prod.js

// 忽略 moment 下的 /locale 目录
new webpack.IgnorePlugin(/\.\/locale/, /moment/)

noParse 避免重复打包

module.exports = {
    module: {
        // 独立完整的‘react.min.js’ 文件就没有采用模块化
        // 忽略对‘react.min.js’ 文件的递归解析处理
        noParse: [/react\.min\.js$/],
    }
}

happyPack 多进程打包

  • JS单线程,开启多进程打包
  • 提高构建速度(特别是多核CPU)
const HappyPack = require('happypack');

module.export = smart(webpackCommonConf, {
    mode: 'xxxx', // 开发、生产
    output: {
        filename: '[name].[contentHash:8].js',
        path: disPatch,    
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                use: ['happypack/loader?id=babel'],
                include: srcPath,
            }
        ]
    },
    plugins: [
        new HappyPack({
            // 用唯一的标识符 id 来代表当前的 HappyPack 是用来处理一类特定的文件
            id: 'babel',
            // 如何处理 .js 文件,用法和 Loader 配置中一样
            loaders: ['babel-loader?cacheDirectory']
        })
    ]
})

ParallelUglifyPlugin 多进程压缩JS

  • webpack 内置 Uglify 工具压缩JS
  • JS 单线程,开启多进程压缩更快
  • 和happyPack 同理
module.export = smart(webpackCommonConf, {
    mode: 'xxxx', // 开发、生产
    output: {
        filename: '[name].[contentHash:8].js',
        path: disPatch,    
    },
    module: {
        rules: []
    },
    plugins: [
        // 使用 ParallelUglifyPlugin 并行压缩输出的JS代码
        new ParallelUglifyPlugin({
            // 传递给 UglifyJS 的参数
            // (还是使用 UglifyJS 压缩,只不过帮助开启了多进程)
            uglifyJS: {
                output: {
                    beautify: false, // 最紧凑的输出
                    comments: false, // 删除所有的注释
                },
                compress: {
                    // 删除所有 console 语句,可以兼容 ie 浏览器
                    drop_console: true,
                    // 内嵌定义了但是只用到一次的变量
                    collapse_vars: true,
                    // 提取出出现多次但是没有定义成变量去引用的静态值
                    reduce_vars: true
                }
            }
        })
    ]
})

自动刷新

热更新

  • 自动刷新:整个网页全部刷新,速度较慢
  • 自动刷新:整个网页全部刷新,状态会丢失
  • 热更新:新代码生效,网页不刷新,状态不丢失

DllPlugin 动态链接库插件

  • webpack已内置 DllPlugin 支持
  • DllPlugin - 打包出dll文件
  • 通过DllRefercePlugin - 使用 dll 文件

webpack性能优化

  • 小图片 base64 编码
  • bundle加hash
  • 懒加载
  • 提取公共代码
  • IngorePlugin
  • 使用 CDN 加速
  • 使用 production(1.自动开启代码压缩 2.vue/react等会自动删掉调试代码 3.启动 Tree-Shaking)
  • Scope Hosting

八、Tree-Shaking

mode: "production" 自动 Tree-Shaking 不打包无用代码

ES6 Module 才能让 Tree-Shaking 生效

commonjs 不行

九、ES6 Module 和 commonjs 区别

  • ES6 Module 静态引入,编译时引入
  • commonjs 动态引入,执行时引入
  • 只有 ES6 Module 才能静态分析,实现 Tree-Shaking

 

 十、Scope Hosting

多个函数合并成一个函数,作用域减少

  • 代码体积更好
  • 创建函数作用域更少
  • 代码可读性更好

 十一、babel

preset 作为 Babel 插件的组合

plugins 补充插件

babel-polyfill

是 core.js(标准库,集合了es6/es7) 和 regenerator (generator异步函数)两个集合

Babel 7.4 之后弃用babel-polyfill 推荐直接使用core.js regenerator

babel-polyfill会污染全局环境

按需引入

babel-runtime

开发第三方库要用babel-runtime,重新取变量名 不会污染全局环境


总结

webpack知识点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值