用源码做网站步骤,百度云盘资源,网站开发知识产权,红动中国免费素材网站webpack学习-5.代码分离 1.入口起点2.防止重复2.1 入口依赖2.2 SplitChunksPlugin 3.动态导入3.1 使用符合 ECMAScript 提案 的 import() 语法3.2 使用 webpack 特定的 require.ensure 4.预获取/预加载模块5.分析bundle6.总结 1.入口起点
代码分离是 webpack 中最引人注目的特… webpack学习-5.代码分离 1.入口起点2.防止重复2.1 入口依赖2.2 SplitChunksPlugin 3.动态导入3.1 使用符合 ECMAScript 提案 的 import() 语法3.2 使用 webpack 特定的 require.ensure 4.预获取/预加载模块5.分析bundle6.总结 1.入口起点
代码分离是 webpack 中最引人注目的特性之一。此特性能够把代码分离到不同的 bundle 中然后便能按需加载或并行加载这些文件。代码分离可以用于获取更小的 bundle、控制资源加载优先级如果使用合理会极大减小加载时间。 常用的代码分离方法有三种 入口起点使用 entry 配置手动地分离代码。 防止重复使用 入口依赖 或者 SplitChunksPlugin 去重和分离 chunk。 动态导入通过模块的内联函数调用分离代码。 入口起点,这是迄今为止最简单直观的实现代码分离的方式。不过这种方式手动配置较多并有一些隐患。不过我们将会介绍如何解决这些隐患。先来看看如何从 main bundle 中分离另一个模块 项目目录结构: 其他跟着官网例子来。这种方式存在一些隐患 1.如果入口 chunk 之间包含一些重复的模块那么这些重复模块会被引入到各个 bundle 中。(例子中的两个js文件都引入了lodash) 2.这种方法不够灵活并且不能动态地拆分应用程序逻辑中的核心代码。(后面没怎么懂暂时) 以上两点中第一点所对应的问题已经在我们上面的实例中体现出来了。除了 ./src/another-module.js我们也曾在 ./src/index.js 中引入过 lodash这就导致了重复引用。
2.防止重复
2.1 入口依赖
在配置文件中配置 dependOn 选项以在多个 chunk 之间共享模块 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’否则会遇到 此处 所述的麻烦。 我们这里是多入口起点所以要设置: 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,},};构建结果如下 可以看到除了 shared.bundle.jsindex.bundle.js 和 another.bundle.js 之外还生成了一个 runtime.bundle.js 文件。
存在四个打包文件的原因如下 index.js 和 another-module.js 分别作为两个独立的入口点index 和another进行打包因此会生成两个对应的 bundle 文件。 lodash 被指定为共享的依赖模块sharedWebpack将其提取到一个单独的共享块中。 此外Webpack 还会生成一个额外的运行时文件其中包含了模块加载和执行的逻辑。 因此根据上述配置最终会生成四个打包文件 index.js包含 ./src/index.js 的代码。 another.js包含 ./src/another-module.js 的代码。 shared.js包含 lodash 的代码。 runtime.js包含 Webpack 运行时代码。 这种是可以将重复的依赖防止重复的但是我就还不清楚重复的依赖在哪个文件里了暂时。
尽管 webpack 允许每个页面使用多个入口起点但在可能的情况下应该避免使用多个入口起点而使用具有多个导入的单个入口起点entry: { page: [‘./analytics’, ‘./app’] }。这样可以获得更好的优化效果并在使用异步脚本标签时保证执行顺序一致。 (这句话的意思是尽管 Webpack 允许在配置中使用多个入口起点但在可能的情况下最好使用具有多个导入的单个入口起点以获得更好的优化效果并确保异步脚本标签的执行顺序一致。
在 Webpack 中每个入口起点都会生成一个输出文件这意味着如果你使用多个入口起点就会生成多个输出文件。这种情况下每个输出文件都需要加载并执行会增加额外的网络请求和加载时间。
相比之下使用具有多个导入的单个入口起点可以将所有的代码逻辑打包到一个输出文件中从而减少了网络请求和加载时间。这样可以提高应用程序的性能和加载速度。
另外当你使用异步脚本标签
而当你使用具有多个导入的单个入口起点时所有的代码逻辑都被打包到一个输出文件中保证了代码的执行顺序一致性避免了潜在的依赖问题。
因此为了获得更好的优化效果和保证执行顺序的一致性建议在可能的情况下使用具有多个导入的单个入口起点。
需要注意的是这并不是绝对的规则而是在一般情况下的最佳实践。在某些特殊情况下使用多个入口起点可能是合理的例如需要将应用程序分割成多个模块或按需加载某些功能模块。)
2.2 SplitChunksPlugin
SplitChunksPlugin 插件可以将公共的依赖模块提取到已有的入口 chunk 中或者提取到一个新生成的 chunk。让我们使用这个插件去除之前示例中重复的 lodash 模块 在webpack的配置文件中配置:
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),clean: true,},optimization: {splitChunks: {chunks: all,},},
};使用 optimization.splitChunks 配置选项后构建将会发现 index.bundle.js 和 another.bundle.js 已经移除了重复的依赖模块。从插件将 lodash 分离到单独的 chunk并且将其从 main bundle 中移除减轻了 bundle 大小。执行 npm run build 查看效果
3.动态导入
终于到最后一个了-动态导入。 webpack 提供了两个类似的技术实现动态代码分离。第一种也是推荐选择的方式是使用符合 ECMAScript 提案 的 import() 语法 实现动态导入。第二种则是 webpack 的遗留功能使用 webpack 特定的 require.ensure。让我们先尝试使用第一种。
3.1 使用符合 ECMAScript 提案 的 import() 语法
现在我们不再静态导入 lodash而是通过动态导入来分离出一个 chunk src/index.js
//动态导入
function getComponent() {return import(lodash).then(({ default: _ }) {const 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);
});需要 default 的原因是自 webpack 4 之后在导入 CommonJS 模块时将不再解析为 module.exports 的值而是创建一个人工命名空间对象来表示此 CommonJS 模块。参阅 webpack 4: import() and CommonJs 以了解更多有关信息。 打包 lodash会分离到一个单独的 bundle。 由于 import() 会返回 promise因此它可以和 async 函数 一起使用。下面是使用 async 简化后的代码 src/index.js:
//动态导入 - async写法
async function getComponent() {const element document.createElement(div);const { default: _ } await import(lodash);element.innerHTML _.join([Hello, webpack], );return element;}getComponent().then((component) {document.body.appendChild(component);});vendors-node_modules_lodash_lodash_js.bundle.js 是一个由 Webpack 打包生成的 JavaScript 文件。它通常包含了 Lodash 库的代码并可能还包含其他第三方库的代码这取决于你的项目中使用了哪些库和配置。
Lodash 是一个流行的 JavaScript 实用工具库提供了许多常用的功能和工具函数用于简化 JavaScript 编程任务。lodash.js 是 Lodash 库的核心文件其中包含了 Lodash 提供的各种功能和方法。
当你在项目中使用 Lodash 并通过 Webpack 打包时Webpack 会将 Lodash 的代码打包成一个单独的文件这就是 vendors-node_modules_lodash_lodash_js.bundle.js 的由来。打包成单独的文件有助于提高浏览器加载速度并允许你在需要时进行缓存和异步加载。 我的理解就是把lodash单独分离出去了的就是例子中的第二个文件代码分离了如果其他地方调用了的话也不用再打包一个bundle出来了。
3.2 使用 webpack 特定的 require.ensure
好像官网没举这个例子。有句话: 警告 require.ensure() 是 webpack 特有的已被 import() 取代。 4.预获取/预加载模块
能看懂意思不知道具体能用在代码里的哪里。。。
5.分析bundle
webpack打包出来的bundle光从命令行感觉是很难看出些什么的不大直观。刚好有插件能解决这个问题以webpack-bundle-analyzer为例。 先安装:
npm install --save-dev webpack-bundle-analyzer然后在webpack配置文件中配置:
const BundleAnalyzerPlugin require(webpack-bundle-analyzer).BundleAnalyzerPlugin;module.exports {// ...其他配置plugins: [new BundleAnalyzerPlugin()]
};然后打包完成了它会默认打开浏览器一个网页:
6.总结
1.webpack的代码分离方式: 入口起点使用 entry 配置手动地分离代码。 防止重复使用 入口依赖 或者 SplitChunksPlugin 去重和分离 chunk。 动态导入通过模块的内联函数调用分离代码。 2.预获取/预加载模块,暂时不知道能干嘛 3.分析bundle通过插件能够更直观的分析打包后的各个bundle包