We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
本系列的主题是 Webpack,每期讲解一个技术要点。如果你还不了解各系列内容,文末点击查看全部文章,点我跳转到文末。
如果觉得本系列不错,欢迎 Star,你的支持是我创作分享的最大动力。
code splitting(代码分割)是 webpack 中最引人注目的特性之一。此特性能够把代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件。
code splitting(代码分割)
作用:代码分割可以用于获取更小的 bundle,以及控制资源加载优先级,如果使用合理,会极大影响加载时间。
常用的代码分割方法有三种:
entry
这是迄今为止最简单直观的分离代码的方式,如何从 main bundle 中分离 another module(另一个模块),即配置多入口:
project
webpack-demo |- package.json |- webpack.config.js |- /dist |- /src |- index.js + |- another-module.js |- /node_modules
another-module.js
import _ from 'lodash'; console.log(_.join(['Another', 'module', 'loaded!'], ' '));
webpack.config.js
const path = require('path'); module.exports = { + mode: 'development', + entry: { + index: './src/index.js', + another: './src/another-module.js', + }, output: { + filename: '[name].[contenthash:10].bundle.js', path: path.resolve(__dirname, 'dist'), }, };
这将生成如下构建结果:
... [webpack-cli] Compilation finished asset index.bundle.js 553 KiB [emitted] (name: index) asset another.bundle.js 553 KiB [emitted] (name: another) runtime modules 2.49 KiB 12 modules cacheable modules 530 KiB ./src/index.js 257 bytes [built] [code generated] ./src/another-module.js 84 bytes [built] [code generated] ./node_modules/lodash/lodash.js 530 KiB [built] [code generated] webpack 5.4.0 compiled successfully in 245 ms
这种方式存在一些隐患:
上述隐患将造成重复引用。
解决方法:
配置 dependOn option 选项,这样可以在多个 chunk 之间共享模块:
dependOn
const path = require('path'); module.exports = { mode: 'development', entry: { + index: { + import: './src/index.js', + dependOn: 'shared', + }, + another: { + import: './src/another-module.js', + dependOn: 'shared', + }, + shared: 'lodash', }, output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist'), }, };
如果我们要在一个 HTML 页面上使用多个入口时,还需设置 optimization.runtimeChunk: 'single',否则还会遇到这里所述的麻烦。
optimization.runtimeChunk: 'single'
const path = require('path'); module.exports = { mode: 'development', entry: { index: { import: './src/index.js', dependOn: 'shared', }, another: { import: './src/another-module.js', dependOn: 'shared', }, shared: 'lodash', }, output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist'), }, + optimization: { + runtimeChunk: 'single', + }, };
构建结果如下:
... [webpack-cli] Compilation finished asset shared.bundle.js 549 KiB [compared for emit] (name: shared) asset runtime.bundle.js 7.79 KiB [compared for emit] (name: runtime) asset index.bundle.js 1.77 KiB [compared for emit] (name: index) asset another.bundle.js 1.65 KiB [compared for emit] (name: another) Entrypoint index 1.77 KiB = index.bundle.js Entrypoint another 1.65 KiB = another.bundle.js Entrypoint shared 557 KiB = runtime.bundle.js 7.79 KiB shared.bundle.js 549 KiB runtime modules 3.76 KiB 7 modules cacheable modules 530 KiB ./node_modules/lodash/lodash.js 530 KiB [built] [code generated] ./src/another-module.js 84 bytes [built] [code generated] ./src/index.js 257 bytes [built] [code generated] webpack 5.4.0 compiled successfully in 249 ms
由上可知,除了生成 shared.bundle.js,index.bundle.js 和 another.bundle.js 之外,还生成了一个 runtime.bundle.js 文件。
SplitChunksPlugin 插件可以将公共的依赖模块node_modules提取到已有的入口 chunk 中,或者提取到一个新生成的 chunk。让我们使用这个插件,将之前的示例中重复的 lodash 模块去除:
SplitChunksPlugin
node_modules
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', + }, + }, };
使用 optimization.splitChunks 配置选项之后,现在应该可以看出,index.bundle.js 和 another.bundle.js 中已经移除了重复的依赖模块。需要注意的是,插件将 lodash 分离到单独的 chunk,并且将其从 main bundle 中移除,减轻了大小。
总结:
1.可以将node_modules中代码单独打包一个chunk最终输出 2.自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk
... [webpack-cli] Compilation finished asset vendors-node_modules_lodash_lodash_js.bundle.js 549 KiB [compared for emit] (id hint: vendors) asset index.bundle.js 8.92 KiB [compared for emit] (name: index) asset another.bundle.js 8.8 KiB [compared for emit] (name: another) Entrypoint index 558 KiB = vendors-node_modules_lodash_lodash_js.bundle.js 549 KiB index.bundle.js 8.92 KiB Entrypoint another 558 KiB = vendors-node_modules_lodash_lodash_js.bundle.js 549 KiB another.bundle.js 8.8 KiB runtime modules 7.64 KiB 14 modules cacheable modules 530 KiB ./src/index.js 257 bytes [built] [code generated] ./src/another-module.js 84 bytes [built] [code generated] ./node_modules/lodash/lodash.js 530 KiB [built] [code generated] webpack 5.4.0 compiled successfully in 241 ms
当涉及到动态代码拆分时,可以使用符合 ECMAScript 提案 的 import() 语法 来实现动态导入。
先从上述示例的配置中移除掉多余的 entry 和 optimization.splitChunks,因为接下来的演示中并不需要它们:
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', - }, - }, };
index.js
function sum(...args) { return args.reduce((p, c) => p + c, 0); } /* 通过js代码,让某个文件被单独打包成一个chunk import动态导入语法:能将某个文件单独打包 */ import(/* webpackChunkName: 'test' */'./test') .then(({ mul, count }) => { // 文件加载成功~ // eslint-disable-next-line console.log(mul(2, 5)); }) .catch(() => { // eslint-disable-next-line console.log('文件加载失败~'); }); // eslint-disable-next-line console.log(sum(1, 2, 3, 4));
查看全部文章
各系列文章汇总:https://github.com/yuanyuanbyte/Blog
我是圆圆,一名深耕于前端开发的攻城狮。
The text was updated successfully, but these errors were encountered:
yuanyuanbyte
No branches or pull requests
本系列的主题是 Webpack,每期讲解一个技术要点。如果你还不了解各系列内容,文末点击查看全部文章,点我跳转到文末。
如果觉得本系列不错,欢迎 Star,你的支持是我创作分享的最大动力。
code splitting
code splitting(代码分割)
是 webpack 中最引人注目的特性之一。此特性能够把代码分离到不同的 bundle 中,然后可以按需加载或并行加载这些文件。作用:代码分割可以用于获取更小的 bundle,以及控制资源加载优先级,如果使用合理,会极大影响加载时间。
常用的代码分割方法有三种:
entry
配置多入口手动地分离代码。多入口手动分离代码
这是迄今为止最简单直观的分离代码的方式,如何从 main bundle 中分离 another module(另一个模块),即配置多入口:
project
another-module.js
webpack.config.js
这将生成如下构建结果:
这种方式存在一些隐患:
上述隐患将造成重复引用。
解决方法:
配置
dependOn
option 选项,这样可以在多个 chunk 之间共享模块:webpack.config.js
如果我们要在一个 HTML 页面上使用多个入口时,还需设置
optimization.runtimeChunk: 'single'
,否则还会遇到这里所述的麻烦。webpack.config.js
构建结果如下:
由上可知,除了生成 shared.bundle.js,index.bundle.js 和 another.bundle.js 之外,还生成了一个 runtime.bundle.js 文件。
SplitChunksPlugin
SplitChunksPlugin
插件可以将公共的依赖模块node_modules
提取到已有的入口 chunk 中,或者提取到一个新生成的 chunk。让我们使用这个插件,将之前的示例中重复的 lodash 模块去除:webpack.config.js
使用 optimization.splitChunks 配置选项之后,现在应该可以看出,index.bundle.js 和 another.bundle.js 中已经移除了重复的依赖模块。需要注意的是,插件将 lodash 分离到单独的 chunk,并且将其从 main bundle 中移除,减轻了大小。
总结:
1.可以将node_modules中代码单独打包一个chunk最终输出
2.自动分析多入口chunk中,有没有公共的文件。如果有会打包成单独一个chunk
构建结果如下:
动态导入
当涉及到动态代码拆分时,可以使用符合 ECMAScript 提案 的 import() 语法 来实现动态导入。
先从上述示例的配置中移除掉多余的
entry
和optimization.splitChunks
,因为接下来的演示中并不需要它们:webpack.config.js
project
index.js
构建结果如下:
参考
查看全部文章
博文系列目录
交流
各系列文章汇总:https://github.com/yuanyuanbyte/Blog
我是圆圆,一名深耕于前端开发的攻城狮。
The text was updated successfully, but these errors were encountered: