在现代 JavaScript 的动态特性中,必须牢记 “旧” 并不一定意味着 “过时”,而 “新” 也不一定意味着 “更好”。
选择正确技术的关键在于它是否符合您的项目需求。在考虑 JavaScript 模块打包程序时,这一原则引起了强烈反响。无论打包工具是经受了时间的考验,还是刚刚问世,每种打包工具都有其独特的优势和局限性。
本文将探讨两个重要的流行工具:Vite 和 Webpack。我们将根据这些打包工具的功能、区别、架构理念以及它们如何集成到开发人员生态系统中进行评估。
什么是 JavaScript 模块打包程序?
JavaScript 打包
JavaScript 打包程序是网络开发中使用的一种工具,用于将多个 JavaScript 文件合并为一个文件,即打包文件。它通过减少网络应用程序所需的请求次数来简化 JavaScript 代码的管理,最终提高性能。
例如,假设有两个独立的 JavaScript 文件:module1.js 和 module2.js。module1.js 包含以下内容:
// module1.js export const greet = (name) => { console.log(`Hello, ${name}!`); }
而 module2.js 包含:
// module2.js export const farewell = (name) => { console.log(`Goodbye, ${name}!`); }
要将这些模块打包到一个文件中,可以使用 Rollup、Webpack 或 Parcel 等打包工具。例如,在项目目录下创建一个 index.js 文件,代码如下:
// index.js import { greet } from './module1.js'; import { farewell } from './module2.js'; greet('Wbolt'); farewell('Server Troubles');
在使用 JavaScript 打包程序时,它会将 module1.js、module2.js 和 index.js 组合成一个为您的网络应用程序量身定制的优化打包程序。
虽然现代网络浏览器支持 ES 模块和 HTTP/2 等技术,从而解决了请求开销问题,但 JavaScript 打包程序对于一系列代码增强仍然不可或缺。它们可以执行基本的代码转换,包括最小化、转码和优化。
此外,JavaScript 模块打包程序还能确保不同浏览器之间的兼容性。无论用户选择何种网络浏览器,它们都能帮助解决浏览器特有的问题,确保用户获得一致的体验。
这种打包过程不仅能加快网络应用程序的加载速度,还能确保高效的性能,尤其是在生产环境中。现在,您已经了解了 JavaScript 打包程序及其在网络开发中的作用,让我们把重点转移到 Vite 和 Webpack 上。
Vite 和 Webpack:简介和概述
很明显,Vite 和 Webpack 在快速发展的现代网络开发领域处于领先地位,在这一领域,资源管理和优化打包至关重要。不过,在进行详细比较之前,让我们先快速了解一下这两个打包程序,并了解它们的优势所在。
Vite:Swift 和按需开发
Vite 的发音是 “veet”,它改变了网络开发人员的游戏规则,将速度和效率放在首位。让 Vite 脱颖而出的是它的按需打包方法。Vite 不预先打包所有代码和资产,而是利用现代浏览器中的本地 ES 模块,在开发过程中直接向浏览器提供代码。这使得热模块替换(HMR)几乎立竿见影,减少了冷启动时间。
Vite 的开发服务器采用这种按需方法,使开发人员无需重新编译即可快速查看更改。它还使用 Rollup,实现高效的生产构建。因此,Vite 的开发速度快如闪电,生产性能稳定可靠。
Webpack:组织有序、适应性强
Webpack 是现代网络开发的基石,自 2012 年以来一直在稳步发展。Webpack 的优点在于它如何组织网站组件。它通过将代码组织成模块来优化加载时间和用户体验。
Webpack 的适应性是一个显著优势。开发人员可以为简单或复杂的任务定制项目。它使开发人员能够定制工作流程,并精确地构建流程。
Vite 和 Webpack 的异同
既然我们已经掌握了 Vite 和 Webpack 的基本概念,下面就让我们来详细探讨它们的异同。在分析这两个打包程序时,我们将从各个方面进行研究,以全面了解它们之间的比较以及各自的优势所在。
- 构建与哲学
- 受欢迎程度、社区和生态系统
- 配置和易用性
- 开发服务器
- 构建时间和软件包大小
- 构建优化
- 静态资产处理
- 静态网站支持
- 服务器端渲染支持
- JSON 支持
- Vue.js 和 JSX 支持
- TypeScript 支持
- 全局导入支持
- Web Workers 支持
- 库开发能力
- 浏览器兼容性
1. 构建与哲学
这两种打包程序都从独特的角度构建和优化网络应用程序。它们的共同点是都采用了插件方式,允许社区创建更多有益的插件来扩展其功能,从而使它们成为开发人员的多功能工具。
Vite 的核心理念是精简和可扩展性。它坚持极简策略,专注于最常见的网络应用程序开发模式。这种方法确保了项目的长期可维护性。
Vite 依靠基于卷积的插件系统,通过外部插件实现功能,防止核心臃肿。这有助于精简核心,并鼓励维护良好的插件生态系统蓬勃发展。此外,Vite 还积极与 Rollup 项目合作,以保持兼容性和共享的插件生态系统。
Webpack 为开发人员提供了自定义功能,使他们能够根据从基本任务到复杂工作的具体需求定制项目。它可以灵活配置构建过程的方方面面,是寻求个性化开发体验的开发人员的首选。
此外,Webpack 引入了模块化方法,类似于为网络项目组装乐高积木。对于 Webpack 来说,代码库中的所有内容都是一个模块,它可以通过多种方式表达其依赖关系。以下是几个例子:
- ES2015
import
语句。 - CommonJS
require()
语句。 - AMD
define
和require
语句 - css/sass/less 文件中的
@import
语句。 - 样式表
url()
或 HTML文件中的图片 URL。
Vite 哲学
Vite 精益和可扩展的架构理念在其构建网络应用程序的方法中体现得淋漓尽致。假设您正在开发一个网络应用程序,并希望加入 ES 模块等现代 JavaScript 功能。有了 Vite,您可以毫不费力地做到这一点。下面是一个简化的示例:
// app.js import { greet } from './utilities.js'; const worker = new Worker(new URL('./worker.js', import.meta.url)); // Simulate a calculation in the web worker worker.postMessage({ input: 42 }); worker.onmessage = (e) => { const result = e.data.result; console.log(`Result from the web worker: ${result}`); }; const message = greet('Hello, Vite!'); console.log(message);
在这个代码片段中,Vite 使用了 ES 模块,它能毫不费力地即时打包代码,避免了开发过程中耗时的打包步骤。这种模块化方法可以有效管理依赖关系,创建可维护的代码库。这体现了 Vite 对极简主义和开发人员友好体验的承诺。
Webpack 哲学
Webpack 的模块化理念对大型项目尤其有益。想象一下,您正在用各种 JavaScript 模块构建一个大型网络应用程序。有了 Webpack,您就可以无缝地组合这些模块,从而提高可读性、可维护性和网站加载时间。下面是一个简化的示例:
// webpack.config.js const path = require('path'); module.exports = { entry: './app.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, module: { rules: [ { test: /.js$/, use: 'babel-loader', exclude: /node_modules/, }, ], }, };
在本示例中,Webpack 可让您配置构建流程、优化代码并高效处理资产。通过将项目组织成模块并使用 Babel 等加载器,您可以编写简洁的模块化代码,从而改善用户体验。这表明 Webpack 致力于提供定制化和灵活性,确保开发人员可以根据特定需求定制自己的项目。
虽然 Vite 和 Webpack 的架构理念各不相同,但它们都致力于推动现代网络开发的发展。Vite 专注于现代编码模式,推广源代码的 ECMAScript 模块(ESM),并鼓励采用现代标准,如 Web Worker 的新 Worker 语法。
另一方面,Webpack 是为了应对 Node.js 和 CommonJS 带来的挑战而发展起来的,推动了模块在网络开发中的应用。Webpack 的自动依赖关系收集和性能改进确保了开发人员的无缝体验。
2. 受欢迎程度、社区和生态系统
Vite 和 Webpack 有着不同的时间线,这决定了它们的受欢迎程度和社区。
Vite 和 Webpack 在过去 5 年的谷歌趋势对比。
Vite 才诞生不到 5 年,于 2020 年首次亮相。尽管诞生时间相对较短,但 Vite 已迅速获得关注,成为现代网络开发领域的一个有前途的参与者。
相比之下,Webpack 成立于 2012 年,起步较早。它在业界的时间使其发展出一个成熟的生态系统和一个强大的社区。
过去 5 年中 Vite 和 Webpack 在 npmtrends 上的对比。
上图来自 npmtrends,展示了 Vite 和 Webpack 的下载量对比。它清楚地表明,Webpack 在下载次数方面始终保持着突出的地位,这凸显了它在开发者社区中的长期存在和广泛使用。
Vite 和 Webpack 获得星星数的历史数据对比。
当我们使用 star-history(衡量受欢迎程度和社区支持度的标准)查看 GitHub 星星数据时,我们发现 Vite 拥有令人印象深刻的 60,318 个星星,而 Webpack 则拥有 63,598 个星星,保持着强大的影响力。这些星星数量反映了这两个项目的认可度和活跃度。Vite 的快速发展和 Webpack 的持续流行使它们成为网络开发领域的宝贵财富。
3. 配置和易用性
Vite 和 Webpack 都提供了大量配置选项,可根据您的特定需求量身定制打包包。不过,它们之间也有明显的区别,值得您注意。让我们来探讨一下这两种工具的配置和易用性。
Vite 的精简配置
Vite 与众不同之处在于其零配置理念,旨在简化您的网站开发过程。这意味着您只需花费最少的精力就能创建一个基本的 Vue 3 组件库。下面是这样一个项目的简单 Vite 配置:
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], })
在上述示例中,我们只导入并安装了 Vite 的 Vue.js 官方插件。Vite 的神奇之处在于它能自动检测大多数项目的正确设置。
Webpack 配置的复杂性
另一方面,Webpack 往往需要更详细的配置。虽然在最近的版本中,Webpack 已经趋向于零配置方法,但它并不像 Vite 那样自动。对于 Vue 3,Webpack 的基本设置可能如下所示:
const webpack = require('webpack'); const path = require('path'); const { HotModuleReplacementPlugin } = require('webpack'); const { VueLoaderPlugin } = require('vue-loader'); module.exports = { entry: './src/main.js', output: { path: path.resolve(__dirname, './build'), filename: 'bundle.js', }, module: { rules: [ { test: /.js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'], }, }, }, { test: /.vue$/, use: { loader: 'vue-loader', }, }, { test: /.css$/, use: ['vue-style-loader', 'css-loader'], }, ], }, resolve: { alias: { vue: 'vue/dist/vue.js', }, }, plugins: [ new HotModuleReplacementPlugin(), new VueLoaderPlugin(), ] };
与 Vite 相比,Webpack 的配置需要更多的手动设置。其复杂性包括指定入口和输出路径、为不同文件类型配置加载器,以及为特定功能设置插件。下面让我们对配置的每个部分进行分解,并指出其中的复杂之处:
- Entry 和 Output:
entry
指定应用程序的入口点,即 Webpack 开始打包的位置。在本例中,它被设置为 ./src/main.js,假设应用程序的主 JavaScript 文件在 src 目录中,而output
则定义了打包文件的保存位置。输出路径使用path.resolve
解析,生成的打包文件命名为 bundle.js,并保存在 build 目录中。 - 模块规则:
module.rules
部分定义了如何处理不同类型的文件。在本例中,有针对 JavaScript 文件(用于转译的babel-loader
)、Vue 单文件组件(vue-loader
)和 CSS 文件(用于处理样式的vue-style-loader
和css-loader
)的规则。 - 别名配置:
resolve.alias
部分定义了模块导入的别名。在本例中,它将 Vue 的别名配置为 vue/dist/vue.js。 - 插件:插件部分包括支持热模块替换的
HotModuleReplacementPlugin
,该功能可让你在开发过程中无需重新加载整个页面即可查看更改,而VueLoaderPlugin
则是处理 Vue 单文件组件所必需的。
最后,Vite 在易用性方面表现突出,提供了简化的设置和精简的开发体验。它的配置要求最低,并使用本地 ES 模块,因此非常适合初学者和快速开发。
相比之下,Webpack 广泛的可配置性虽然有利于复杂的项目,但也会给新手开发者带来挑战。复杂的设置和维护会拖慢开发速度,尤其是对于小型项目而言。
4. 开发服务器
开发服务器在开发人员的工作流程中起着至关重要的作用,影响着效率和生产力。让我们对 Vite 和 Webpack 进行比较,评估它们的开发服务器性能和可用性,从而为您的网站开发项目找到最合适的工具。
服务器配置
Vite 凭借其内置的、开箱即用的开发服务器脱颖而出,通常无需进行大量配置。
相比之下,Webpack 具有灵活性,但需要额外的设置。开发人员可以选择 Webpack 的观察模式、webpack-dev-server
和 webpack-dev-middleware
等选项,以便在变更时自动编译代码。不过,通常需要对这些选项进行配置和微调。
冷启动速度
传统的基于打包程序的设置涉及急切抓取,需要在提供服务前构建整个应用程序,从而导致明显的延迟,尤其是在复杂的项目中。
Vite 从根本上改变了冷启动方式,大大缩短了初始化时间:
Esbuild 使用默认设置从头开始制作了一个包含 10 份 three.js 库的生产打包。(图片来源:Esbuild)
(1)高效的依赖关系处理:Vite 利用基于 Go 语言的高性能打包程序 esbuild 来预打包依赖项,包括纯 JavaScript 和大型模块。作为预打包流程的一部分,Vite 通过将 ESM 依赖项与众多内部模块合并为一个模块来优化性能。例如,lodash-es 包含 600 多个内部模块。例如,lodash-es 包含 600 多个内部模块。使用传统方法导入 debounce
这样的函数时,会触发 600 多个 HTTP 请求。Vite 的解决方案是将 lodash-es
预先打包成一个模块,从而将 HTTP 请求减少到一个。请求的大幅减少大大提高了开发服务器的页面加载速度。
基于 ESM 的开发服务器图 (图片来源:Vite)
(2)按需加载源代码:Vite 利用本地 ES 模块提供源代码,最大限度地减少服务器负载和延迟。源代码转换和服务在浏览器请求时进行,从而提高了效率,减少了等待时间。
基于打包的开发服务器图。(图片来源:Vite)
另一方面,Webpack 采用基于打包的方法,预先打包源代码和依赖项,从而延长了开发过程中的服务器启动时间。与 Vite 的高效初始化相比,Webpack 的服务器设置时间本来就更长。
不过,当用户导航到需要额外数据、CSS 和资产的路由时,Vite 的按需加载方法可能会带来轻微的延迟。如果这些资源需要进一步的打包步骤,这种延迟就尤为明显。相反,Webpack 的策略能确保所有网站数据可用,从而加快浏览器导航到开发服务器内新网页的速度。
HMR(热模块替换)
Vite 采用 HMR 而非本地 ESM,通过将一些打包工作卸载到浏览器来减少服务器负载和延迟。这可确保快速更新,而无需重新加载整个页面,这对开发过程中的实时反馈至关重要。
Webpack 也支持 HMR,可在开发过程中实现实时更新并保留应用程序状态。不过,利用本地 ES 模块的潜在限制可能会导致更高的服务器负载和延迟。
缓存性能
缓存对于提高网络应用性能、通过重复使用存储资产来减少负载和构建时间至关重要。
Vite 中的缓存由文件系统缓存管理,根据 package.json、lockfiles 和 vite.config.js 中的变化更新依赖关系。它通过缓存已解决的依赖请求来优化页面重载。
Webpack 也使用文件系统缓存,在监视模式下清除修改过的文件,在非监视模式下每次编译前清除缓存,需要自定义配置以优化缓存。
在开发服务器的比较中,Vite 和 Webpack 提供了不同的开发服务器方法:
- Vite 提供了开箱即用的开发服务器,最大限度地减少了配置开销。
- Webpack 配置灵活,但需要额外设置。
- Vite 在冷启动速度和快速更改代码的 HMR 方面表现出色
- 由于预先打包了网站数据,Webpack 在浏览器导航速度方面表现更好。
- 两者都支持 HMR,但有不同的模块服务机制。
- Vite 可无缝管理本地和浏览器缓存,而 Webpack 则需要自定义配置。
5. 构建时间和软件包大小
现在,让我们比较一下 Vite 和 Webpack 的构建时间和打包包大小(考虑到开发构建、开发服务器期间的热更改和生产构建)。
我们的测试环境包括:
- 在配备苹果 M1 芯片和 8 核 GPU 的 MacBook Air 上运行测试。
- 一个中等规模的 Vue 3 项目,包含 10 个组件,使用 Vuex 进行状态管理,使用 Vue Router 进行路由。
- 包含样式表(CSS/SASS)、图片和字体等资产,以及适量的依赖关系。
我们先来比较一下打包时间:
Vite [v4.4.11] | Webpack [v5.89.0] | |
---|---|---|
开发人员首次构建 | 376ms | 6s |
热更新 | 立即 | 1.5s |
最终打包 | 2s | 11s |
原文地址:https://www.wbolt.com/vite-vs-webpack.html