随着前端项目的复杂度不断增加,现代前端应用已经远远不是简单的一些 HTML、CSS 和少量的 JavaScript 代码了。越来越多的库和框架变得必不可少。这些库和框架不仅消耗了大量的网络资源和加载时间,还有助于增加 JavaScript 包的大小,从而导致页面加载时间过长的问题。为了解决这个问题,服务端渲染与按需加载等技术诞生了。其中 webpack 打包时公共模块 (vendor) 单独打包是一种关键技术。
为什么要把公共模块单独打包
我们假设有一个项目,其中有多个入口点(entry points)和许多模块(modules)。当我们使用 webpack 将这些模块打包成 bundle 时,我们将得到一个包含所有代码的 bundle 文件。而这个文件只有当它被加载时,才会开始执行整个应用程序。因此,我们将需要加载的 JavaScript 代码压缩成尽可能小的文件。
这里的问题在于,如果我们的多个入口点之间共享了一些公共代码,这些代码将被打包到多个 bundle 中,从而导致代码冗余,增加整个包的大小。例如,如果我们在不同的文件中使用了 jQuery,这意味着我们在每个文件中都将包含一份 jQuery 代码。这样做不仅导致代码冗余,而且还增加了 bundle 的体积,使整个项目加载变慢。因此,我们需要将这些公共代码提取到一个单独的文件中,然后在每个入口点中使用这个文件。
如何将公共模块单独打包
webpack 支持使用 CommonsChunkPlugin
插件将代码分离为不同的 chunk。这个插件将公共模块提取出来并打包到一个单独的文件中。我们可以将所有共享模块提取到一个文件中,将不同的入口文件和 vendor 文件组合起来,以便在浏览器中加载并渲染。
我们来看一个简单的示例:
// javascriptcn.com 代码示例 // webpack.config.js const webpack = require('webpack'); module.exports = { entry: { app: './src/app.js', vendor: ['jquery'] // 提取出来的公共模块 }, output: { filename: '[name].bundle.js' }, plugins: [ new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: Infinity }) ] };
在上面的示例中,我们使用了 CommonsChunkPlugin
插件将名为 vendor
的 chunk 提取出来。此外,我们还将 minChunks
设置为 Infinity
,这表示不要将任何其他模块提取到 vendor chunk 中。这段代码将提取出所有在 vendor
chunk 中引用的依赖。
如果我们使用 HTML 页面作为我们的入口点,我们可以通过将这些脚本作为标签添加到 HTML 中来使用它们:
// javascriptcn.com 代码示例 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Webpack example</title> </head> <body> <script src="vendor.bundle.js"></script> <script src="app.bundle.js"></script> </body> </html>
在这个示例中,我们首先加载 vendor.bundle.js
文件,然后加载 app.bundle.js
文件。由于 vendor
chunk 包含了所有共享的依赖,我们可以确保它会在应用代码之前加载。
总结
在本文中,我们介绍了将 webpack 打包时公共模块 (vendor) 单独打包的原因和如何实现。这是使您的 JavaScript 代码更小,更快速加载,从而帮助提高应用性能的关键技术。
在开发过程中,当我们开始使用一些其他人创建的库时,我们应该考虑它们的大小,以及我们应该如何在我们的应用程序中使用它们。一般情况下,提取这些库中的公共代码,或者使用像 webpack
中的模块系统,将是解决问题的最佳方式。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653e24507d4982a6eb7b6f91