仲灏小栈 仲灏小栈
首页
大前端
后端&运维
其他技术
生活
关于我
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

仲灏

诚意, 正心, 格物, 致知
首页
大前端
后端&运维
其他技术
生活
关于我
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 《前端项目基础建设》
  • HTML&CSS

  • JavaScript&TypeScript

  • Node

  • 构建

    • webpack考点梳理
    • 项目基础建设
    • 自制脚手架
    • webpack高级使用
      • 抽离公共代码和第三方代码
        • 动态数据-懒加载
      • module chunk bundle 的区别
      • webpack 性能优化 - 构建速度
        • 优化 babel-loader
        • IgnorePlugin 避免引入无用模块
        • noParse 避免重复打包
        • happyPack 多进程打包
        • ParallelUglifyPlugin 多进程压缩JS
        • 自动刷新 热更新
        • DllPlugin 动态链接库插件
      • webpack 性能优化 - 产出代码
      • ES6 Module 和 Commonjs 区别
    • babel
    • pnpm 配置
  • Vue

  • React

  • 小程序

  • 跨端

  • Electron

  • WebGL&GIS

  • 浏览器

  • 面经

  • 其他

  • 大前端
  • 构建
仲灏
2022-06-10
目录

webpack高级使用

# 抽离公共代码和第三方代码

    optimization: {
      	...
        // 分割代码块
        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  // 公共模块最少复用过几次
                }
            }
        }
      ...
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 动态数据-懒加载

import('**').then(res => {
	res.default.** // 注意default
})
1
2
3

# module chunk bundle 的区别

image-20220610165948317

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

# webpack 性能优化 - 构建速度

# 优化 babel-loader

{
    test:八.js$/,
    use: ["babel-loader?cacheDirectory'],//开启缓存
    include: path. reso lve(dirname,'src"),//明确范围
    //// 排除范围,include 和 exclude 两者选一个即可
    // exclude: path. resolve(_dirname,'node_ modules")
}
1
2
3
4
5
6
7

# IgnorePlugin 避免引入无用模块

  • import moment from 'moment'
  • 默认会引入所有语言 JS代码,代码过大
  • 如何只引入中文?
// webpack.prod.js

//忽略 moment 下的 / Locale 目录
new webpack.Ignoreplugin(/\.\/locale/, /moment/
1
2
3
4

image-20220610171412874

# noParse 避免重复打包

image-20220610171542388

# happyPack 多进程打包

  • JS单线程,开启多进程打包
  • 提高构建速度(特别是多核 CPU)
// module.rules
  // js
  {
      test: /\.js$/,
      // 把对 .js 文件的处理转交给 id 为 babel 的 HappyPack 实例
      use: ['happypack/loader?id=babel'],
      include: srcPath,
      // exclude: /node_modules/
  },
1
2
3
4
5
6
7
8
9
// plugins
// happyPack 开启多进程打包
new HappyPack({
    // 用唯一的标识符 id 来代表当前的 HappyPack 是用来处理一类特定的文件
    id: 'babel',
    // 如何处理 .js 文件,用法和 Loader 配置中一样
    loaders: ['babel-loader?cacheDirectory']
}),
1
2
3
4
5
6
7
8

# ParallelUglifyPlugin 多进程压缩JS

  • webpack 内置 Uglify 工具压缩 JS
  • JS单线程,开启多进程压缩更快
  • 和 happyPack 同理
// 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,
        }
    }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

开发环境下

# 自动刷新 热更新

热更新需要开启监听范围

// 增加,开启热更新之后的代码逻辑
if (module.hot) {
    module.hot.accept(['./math'], () => {
        const sumRes = sum(10, 30)
        console.log('sumRes in hot', sumRes)
    })
}
1
2
3
4
5
6
7

# DllPlugin 动态链接库插件

  • 前端框架如 vue React,体积大,构建慢

  • 较稳定,不常升级版本

  • 同一个版本只构建一次即可,不用每次都重新构建

  • webpack 已内置 DllPlugin 支持

  • DlPlugin -打包出dll文件

    react.dll.js

    manifest.json // 索引文件

  • DlIlReferencePlugin - 使用 dlll文件

​ index.html 中引入react.dll.js文件

​ 然后配置索引地址

plugins

new DllPlugin({
      // 动态链接库的全局变量名称,需要和 output.library 中保持一致
      // 该字段的值也就是输出的 manifest.json 文件 中 name 字段的值
      // 例如 react.manifest.json 中就有 "name": "_dll_react"
      name: '_dll_[name]',
      // 描述动态链接库的 manifest.json 文件输出时的文件名称
      path: path.join(distPath, '[name].manifest.json'),
    }),
1
2
3
4
5
6
7
8
9
10

使用: 创建webpack.dll.js

const path = require('path')
const DllPlugin = require('webpack/lib/DllPlugin')
const { srcPath, distPath } = require('./paths')

module.exports = {
  mode: 'development',
  // JS 执行入口文件
  entry: {
    // 把 React 相关模块的放到一个单独的动态链接库
    react: ['react', 'react-dom']
  },
  output: {
    // 输出的动态链接库的文件名称,[name] 代表当前动态链接库的名称,
    // 也就是 entry 中配置的 react 和 polyfill
    filename: '[name].dll.js',
    // 输出的文件都放到 dist 目录下
    path: distPath,
    // 存放动态链接库的全局变量名称,例如对应 react 来说就是 _dll_react
    // 之所以在前面加上 _dll_ 是为了防止全局变量冲突
    library: '_dll_[name]',
  },
  plugins: [
    // 接入 DllPlugin
    new DllPlugin({
      // 动态链接库的全局变量名称,需要和 output.library 中保持一致
      // 该字段的值也就是输出的 manifest.json 文件 中 name 字段的值
      // 例如 react.manifest.json 中就有 "name": "_dll_react"
      name: '_dll_[name]',
      // 描述动态链接库的 manifest.json 文件输出时的文件名称
      path: path.join(distPath, '[name].manifest.json'),
    }),
  ],
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# webpack 性能优化 - 产出代码

  • 体积更小

  • 合理分包,不重复加载

  • 速度更快、内存使用更少

  • 小图片 base64 编码

  • bundle 加 hash

  • 懒加载

  • 提取公共代码

  • IngorePlugin

  • 使用cdn 加速

    • publicPath
  • 使用 production

    • 更改mode配置 , production会自动压缩代码
    • Vue React 等会自动删掉调试代码(如开发环境的 warning)
    • 启动 Tree-Shaking
  • Scope Hosting

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

# ES6 Module 和 Commonjs 区别

两个都是模块化解决方案

  • ES6 Module 静态引入,编译时引入
  • Commonjs 动态引入,执行时引入
  • 只有 ES6 Module 才能静态分析,实现 Tree-Shaking
上次更新: 2023/09/17, 16:36:29
自制脚手架
babel

← 自制脚手架 babel→

最近更新
01
vim日常使用记录
04-02
02
滑动窗口最大值
04-02
03
有效的字母异位词
04-02
更多文章>
Theme by Vdoing | Copyright © 2021-2025 izhaong | github | 蜀ICP备2021031194号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式