代码拆分能够将代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件。代码拆分可以用于获取更小的 bundle,以及控制资源加载优先级,会影响加载时间。

常用的代码拆分方法:

  • 入口起点:使用 entry 配置手动地分离代码。
  • 防止重复:使用 CommonsChunkPlugin去重和分离 chunk。
  • 动态导入:通过模块的内联函数调用来分离代码。

入口起点

最简单、最直观的分离代码的方式。但手动配置较多,并有一些陷阱。

const path = require('path');

module.exports = {
entry: {
index: './src/index.js',
print: './src/print.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};

构建结果会生成 index.bundle.js print.bundle.js

  • 入口 chunks 之间包含的重复的模块,都会被引入到各个 bundle 中。
  • 该方法不够灵活,且不能将核心应用程序逻辑进行动态拆分代码。

防止重复

SplitChunksPlugin插件可以将公共的依赖模块提取到已有的入口 chunk 中,或者提取到一个新生成的 chunk:

CommonsChunkPlugin在 webpack v4 中删除。

RemovedPluginError: webpack.optimize.CommonsChunkPlugin has been removed, please use config.optimization.splitChunks instead.

// ./src/index.js
import _ from 'lodash';
console.log(
_.join(['index', 'module', 'loaded!'], ' ')
); // ./src/print.js
import _ from 'lodash';
console.log(
_.join(['print', 'module', 'loaded!'], ' ')
);
const path = require('path');

module.exports = {
entry: {
index: './src/index.js',
print: './src/print.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
optimization: {
splitChunks: {
chunks: 'all',
name:'common'
},
},
};

构建结果会生成 index.bundle.js print.bundle.js common.bundle.js, 将 lodash 分离到单独的 chunk,并且将其从主包中移除,减轻了大小。

动态导入(dynamic imports)

使用符合 ECMAScript 提案的 import() 语法。import() 调用会在内部用到 promises。如果在旧版本浏览器中使用,需要使用 polyfill 库(如 es6-promise或 promise-polyfill)。

const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin'); module.exports = {
entry: {
index: './src/index.js'
},
plugins: [
new HTMLWebpackPlugin({
title: 'Code Splitting'
})
],
output: {
filename: '[name].bundle.js',
chunkFilename: '[name].bundle.js', // 决定非入口 chunk 的名称
path: path.resolve(__dirname, 'dist')
}
};

== ./src/index.js==:注释中使用了 webpackChunkName。这样做 bundle 被命名为 lodash.bundle.js

vendors 缓存组的配置可以检测第三方模块是否在 node_modules 中,如果存在则该 splitChunks 生效,将会分离到 vendors~... 这样的文件中,因此此处我生成的文件名 为 vendors~lodash.bundle.js

function getComponent() {
return import( /* webpackChunkName: "lodash" */ 'lodash').then( _ => {
var element = document.createElement('div');
element.innerHTML = _.join(['Hello', 'webpack'], ' ');
return element;
}).catch(error => 'An error occurred while loading the component');
}
getComponent().then(component => {
document.body.appendChild(component);
})

webpack4.15.1 学习笔记(六) — 代码拆分(Code Splitting)的更多相关文章

  1. java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)

    java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...

  2. # go微服务框架kratos学习笔记六(kratos 服务发现 discovery)

    目录 go微服务框架kratos学习笔记六(kratos 服务发现 discovery) http api register 服务注册 fetch 获取实例 fetchs 批量获取实例 polls 批 ...

  3. Typescript 学习笔记六:接口

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  4. python3.4学习笔记(六) 常用快捷键使用技巧,持续更新

    python3.4学习笔记(六) 常用快捷键使用技巧,持续更新 安装IDLE后鼠标右键点击*.py 文件,可以看到Edit with IDLE 选择这个可以直接打开编辑器.IDLE默认不能显示行号,使 ...

  5. Go语言学习笔记六: 循环语句

    Go语言学习笔记六: 循环语句 今天学了一个格式化代码的命令:gofmt -w chapter6.go for循环 for循环有3种形式: for init; condition; increment ...

  6. 【opencv学习笔记六】图像的ROI区域选择与复制

    图像的数据量还是比较大的,对整张图片进行处理会影响我们的处理效率,因此常常只对图像中我们需要的部分进行处理,也就是感兴趣区域ROI.今天我们来看一下如何设置图像的感兴趣区域ROI.以及对ROI区域图像 ...

  7. Linux学习笔记(六) 进程管理

    1.进程基础 当输入一个命令时,shell 会同时启动一个进程,这种任务与进程分离的方式是 Linux 系统上重要的概念 每个执行的任务都称为进程,在每个进程启动时,系统都会给它指定一个唯一的 ID, ...

  8. Spring Boot 学习笔记(六) 整合 RESTful 参数传递

    Spring Boot 学习笔记 源码地址 Spring Boot 学习笔记(一) hello world Spring Boot 学习笔记(二) 整合 log4j2 Spring Boot 学习笔记 ...

  9. Java IO学习笔记六:NIO到多路复用

    作者:Grey 原文地址:Java IO学习笔记六:NIO到多路复用 虽然NIO性能上比BIO要好,参考:Java IO学习笔记五:BIO到NIO 但是NIO也有问题,NIO服务端的示例代码中往往会包 ...

  10. Learning ROS for Robotics Programming Second Edition学习笔记(六) indigo xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

随机推荐

  1. linux 文件扩展权限ACL(访问控制列表)

    目录 一.关于文件扩展权限ACL 二.给文件加扩展权限 三.给目录加扩展权限 四.给目录下所有文件都加扩展权限 五.去掉单个acl权限 六.去掉所有acl权限 一.关于文件扩展权限ACL 在linux ...

  2. C# Datagridview combox列 初始化颜色

    DataGridView 初始化完成后,在combox里显示颜色,如这样: DataGridView 注册 cellPainting事件: private void m_dataGridView_Ce ...

  3. 源码分析——MyBatis核心接口SqlSession的实现原理

    在上一篇文章中(<MyBatis动态代理调用过程源码分析>),我们知道了MyBatis动态代理的核心是MapperProxy,在它内部封装了动态代理的调用逻辑,而我们也知道了在使用动态代理 ...

  4. .NET6之MiniAPI(九):基于角色的身份验证和授权

    身份验证是这样一个过程:由用户提供凭据,然后将其与存储在操作系统.数据库.应用或资源中的凭据进行比较. 在授权过程中,如果凭据匹配,则用户身份验证成功,可执行已向其授权的操作. 授权指判断允许用户执行 ...

  5. Oracle优化神技之临时表

    Oracle临时表在处理临时数据.会话数据隔离和复杂查询优化方面非常有用. 其底层逻辑是通过Oracle特殊的临时表来减少I/O操作和日志开销,提高了数据库性能和查询效率.开发者可以根据具体需求和场景 ...

  6. 如何发现及处理 MySQL 主从延迟问题

    在 Percona MySQL 支持团队中,我们经常看到客户抱怨复制延迟的问题.当然,这对 MySQL 用户来说并不是什么新鲜事,多年来我们在 MySQL 性能博客上发表过一些关于这个主题的文章(过去 ...

  7. C程序函数调用&系统调用

    理解程序的执行 我们要知道CPU可以自由地访问寄存器.内存.另外,程序是由操作系统执行的,所以操作系统能够控制程序的所有执行情况,限制程序的行为. 程序地执行过程: 程序是一个二进制文件,包含程序的代 ...

  8. Javascript高级程序设计第三章 | ch3 | 阅读笔记

    语言基础 语法 标识符 注释 // /* */ 严格模式 // 也可以单独指定在一个函数中进行 'use strict' 语句 语句末尾分号不是必须的,但是最好加上 加上分号方便开发者删除空行压缩代码 ...

  9. 串口收发UART(Verilog HDL)

    UART(Universal Asynchronous Receiver Transmitter,通用异步收发器)是一种异步串行通信协议,主要用于计算机和嵌入式系统之间的数据交换. 实现UART通信的 ...

  10. SDL3 入门(2):第一个窗口

    在上一篇文章中我们已经利用 SDL 的日志接口实现了简单的字符串输出,实际上是解决了开发环境搭建问题,接下来我们将在已有代码的基础上继续开发,实现第一个窗口的创建和背景色绘制. 初始化 首先设置日志输 ...