代码拆分
官方文档.
代码拆分是webpack最引人注目的功能之一。此功能允许您将代码拆分为各种捆绑包,然后可以按需或并行加载。它可用于实现更小的捆绑并控制资源负载优先级,如果使用得当,可能会对加载时间产生重大影响。
-
可用的代码拆分有三种通用的方法:
- Entry Points:使用entry配置手动拆分代码。
- Prevent Duplication:使用SplitChunksPlugin重复数据删除和拆分块。
- Dynamic Imports:通过模块内的内联函数调用拆分代码。
以下方法代码示例承自webpack 4 笔记三 输出管理.
一、Entry Points
方法:手动拆分
优点:直观、简单,手动。
缺点:一、如果输入块之间存在任何重复的模块,则它们将包含在两个包中。二、它不够灵活,不能用于使用核心应用程序逻辑动态分割代码。
实现:
1、添加项目文件 src/another-module.js
import _ from 'lodash';console.log(_.join(['Another', 'module', 'loaded!'], ' ')
);
2、配置 webpack.config.js ,添加入口
const path = require('path');module.exports = {mode: 'development',entry: {index: './src/index.js',
+ another: './src/another-module.js'},output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist')}
};
3、命令行运行 npm run build ,构建
以上就是通过 Entry Points 进行的手动代码拆分,仔细观察可以发现,index.js 和 another-module.js 都导入了 loader ,即输入块之间存在任何重复的模块,结果是两个包内都包含了该模块,这与我们的初衷违背。
二、Prevent Duplication
方法:使用SplitChunksPlugin重复数据删除和拆分块
优点:在 Entry Points 的基础上,将共同的依赖提取到一个现有的条目块或一个全新的块。
实现:
1、同以上
2、配置 webpack.config.js ,设置 optimization.splitChunks 选项
const path = require('path');module.exports = {mode: 'development',entry: {index: './src/index.js',
+ another: './src/another-module.js'},output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist')},
+ optimization: {
+ splitChunks: {
+ chunks: 'all'
+ }
+ }
};
3、命令行运行 npm run build ,构建
这里明显可以看到,输出文件大小大大减少,同时生成一个新文件,这是因为已经分离 loader 出一个单独的文件。
三、Dynamic Imports
方法:通过模块内的内联函数调用拆分代码
webpack 提供了两个类似的技术。对于动态导入,第一种,也是优先选择的方式是,使用符合 ECMAScript 提案 的 import() 语法。第二种,则是使用 webpack 特定的 require.ensure。这里仅尝试使用第一种……
实现:
1、配置 webpack.config.js ,设置 chunkFileneme
const path = require('path');module.exports = {mode: 'development',entry: {index: './src/index.js',},output: {filename: '[name].bundle.js',
+ chunk Filename: '[name].bundle.js', //确定非条目块文件的名称path: path.resolve(__dirname, 'dist')},
};
2、通过使用动态导入来分离一个 chunk,而不是使用静态导入 lodash
src/index.js
- import _ from 'lodash';
-
- function component() {
+ function getComponent() {
- var element = document.createElement('div');
-
- // Lodash, now imported by this script
- element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+ return import(/* webpackChunkName: "lodash" */ 'lodash').then(({ default: _ }) => {
+ var element = document.createElement('div');
+
+ element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+
+ return element;
+
+ }).catch(error => 'An error occurred while loading the component');}- document.body.appendChild(component());
+ getComponent().then(component => {
+ document.body.appendChild(component);
+ })
3、命令行运行 npm run build ,构建
lodash分离到单独的包。
4、通过 async 函数简化代码
由于 import() 会返回一个 promise,因此它可以和 async 函数一起使用。但是,需要使用像 Babel 这样的预处理器和Syntax Dynamic Import Babel Plugin。
src/index.js
- function getComponent() {
+ async function getComponent() {
- return import(/* webpackChunkName: "lodash" */ 'lodash').then({ default: _ } => {
- var element = document.createElement('div');
-
- element.innerHTML = _.join(['Hello', 'webpack'], ' ');
-
- return element;
-
- }).catch(error => 'An error occurred while loading the component');
+ var element = document.createElement('div');
+ const { default: _ } = await import(/* webpackChunkName: "lodash" */ 'lodash');
+
+ element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+
+ return element;}getComponent().then(component => {document.body.appendChild(component);});