最近基于 ES module 的 bundleless 构建工具很火,特地是尤大在到处推广 Vite,号称“下一代前端构建工具”,在前不久的 VueConf 2021 上,尤大堪称狠狠地宣传了一下。以至于一度有很多人认为,有了 Vite 之后就不再须要 Webpack 了。尽管 Vite 当初的确很火,也有很多人在尝鲜,但事实恰好与大家的观点相同,目前简直没人把 Vite 用于理论的我的项目开发。
首先先要先明确一个问题,为什么 Webpack 须要打包?集体认为次要有两点起因:第一,在过来因为 HTTP/1.1 受网络提早和浏览器并行申请限度等起因,将资源合并压缩有助于缩小 HTTP 申请从而晋升页面加载性能。第二,JS 自身并没有提供模块零碎。尽管 Node.js 中提供了 Common.js 的模块化机制,然而浏览器环境并不反对。而且尽管 ES2015 规范中提供了语法层面的模块化标准,然而当初依然是 implementation-defined 的状态,无论是 Node.js 还是浏览器均不反对(应用 babel 还是会编译为 Common.js)。直到 2017 年 Chrome 61 公布,浏览器才具备了对 JavaScript Module 的原生反对。因而,应用 Webpack 显然益处不只是一点点,不仅能够对动态资源打包压缩,还实现了一套模块零碎,另外还有各种 loader、plugin,能够对打包的代码进行 polyfill,还能够编译转换 .less
、.vue
、.jsx
等在浏览器无奈辨认的文件格式,更重要的是提供了 HMR 机制,极大地晋升了开发体验。
当然 Webpack 的痛点也不少,因为 Webpack 在打包时须要构建模块依赖图,因而须要递归遍历所有的模块,最显著的就是随着我的项目体积的增长,构建的工夫也线性增长,启动工夫也相应减少。第二,当咱们批改了其中的文件之后,Webpack 须要从新打包。第三,因为 Webpack 在打包后会对源码进行编译和压缩,代码的可读性大大降低,因而在开发环境下,咱们须要借助 SourceMap 进行调试,而开启 SourceMap 无疑也会升高打包速度。第四,随着我的项目体积减少,打进去的包也越来越大,过大的包会缩短页面首屏加载工夫,对此 Webpack 也有解决方案,即应用 Tree Shaking、lazy-loading、CommonsChunkPlugin 等。
那么为什么当初开始尝试不打包了?首先最次要的起因是 HTTP/2.0 实现了多路复用和首部压缩,解决了 HTTP/1.1 中队头阻塞的问题,因而通过资源合并压缩缩小 HTTP 申请对页面加载性能不会有显著晋升了。其次,随着 Chrome 61 公布,当初各大浏览器逐个反对 ESM,间接浏览器便可解析 imports,无需本人再实现模块化了。通过浏览器原生 ESM 最大的益处就是能够实现按需加载,不必打包了,构建工夫复杂度 O(1),启动很快,只须要启动 devServer 即可。
和 Snowpack 相似,Vite 也是利用浏览器原生的 ESM 去解析 imports,而后向 devServer 申请模块,在服务器端应用 esbuild 对模块进行即时编译后返回(次要是转换 .jsx
、.tsx
、.vue
、.less
等浏览器无奈解决的文件,而不是编译为 ES5 兼容老旧浏览器)。那么为什么 Vite 应用 esbuild 进行编译?一个字:快!咱们能够看一组比照,Webpack5 打包须要 54.5s,而 esbuild 仅需 0.37s。这是因为 esbuild 是用 Golang 编写的,天然比用 JS 编写的构建工具快很多。同时,esbuild 中的算法通过精心设计,大量应用了并行操作,能够充分利用 CPU 资源。另外,esbuild 没有应用第三方依赖,和内存的高效利用,也是打包快的起因。
只管 esbuild 劣势非常显著,然而它依然无奈取代 Webpack,次要有两点起因:第一,esbuild 尽管有 loader,然而没有插件机制;第二,esbuild 没有热更新。那么 Vite 在 esbuild 的根底上解决了热更新的问题,是不是就能够干掉 Webpack 了。
当初回到结尾那个问题,为什么当初简直没人把 Vite 用于理论我的项目的开发?首先一个就是,尽管 Vite 在开发环境应用原生 ESM,然而在生产环境依然须要应用 Rollup 打包。因为嵌套 import 会导致发送大量网络申请,即便应用 HTTP/2.0,间接应用未打包的 ESM 依然效率低下。所以为了在生产环境中获得最佳的加载性能,最好将代码 bundle 一遍(联合 Tree Shaking,lazy-loading 和 common chunk splitting 等技术手段)。所以当初看来,Vite 更像是一个开发工具,而不是用于生产环境的构建工具。另外,开发环境应用浏览器 ESM 解析模块,而生产环境应用 Rollup 打包,这就导致本地和线上环境跑的代码不统一,线上环境出了 bug,本地很难排查。那有的同学会问,为什么 Vite 不必 esbuild 打包?esbuild 速度十分快,曾经是一个十分弱小的 Bundler,但一些构建利用所需的重要个性仍在开发中——特地是 代码宰割
和 CSS 解决
。目前,Rollup 在这些方面更加成熟和灵便。也就是说,当 esbuild 在未来稳固这些个性时,不排除在生产版本中应用 esbuild 的可能性。
综上,Vite 其实和 Vue-cli 一样,能够说是 Vue 官网给集体开发者和中小企业提供的脚手架工具,毕竟不必本人造轮子了。正如 Vue-cli 就是对 Webpack 的封装一样,Vite 其实就是对 esbuild 的封装,因而“Vite 能干掉 Webpack”这句话自身就是不对等的,充其量作为下一代脚手架工具还差不多。而且 Vite 当初还只能在开发环境用 ESM,生产环境还是须要打包,基本上只有浏览器反对齐全和基于 QUIC 协定的 HTTP/3 遍及之后才可能大规模应用 ESM。更何况 Webpack 倒退至今 loader 和 plugin 生态曾经非常丰盛,而 bundleless 构建工具的生态还在起步阶段。久远来看 ESM 的确极具发展潜力,不排除当前 bundleless 构建工具可能会超过 Webpack,然而 Webpack 在当初的前端工程化中依然扮演着十分重要的角色。
参考
Babel 官方网站
为什么抉择 webpack – webpack 官网文档
Vite.js 中文网
「不懂就问」为什么 esbuild 这么快?
Vite 扫盲
初识 Vite 基础知识