Snowpack,新时代前端构建的先锋
大家好,我是三元同学。
今天给大家介绍一个非常厉害的前端构建工具——Snowpack。也许你之前听说过前端领域非常多的打包工具,诸如 Webpack
、Rollup
,或者Parcel
,甚至是现在在前端圈大火的 Bundleless 构建工具Vite
,但大家也许并没有注意到 Snowpack
。
其实它在 2019 年 2 月就在开源社区诞生了,可以说是业界最早提出并实现的 Bundleless 方案,如今在社区已经有了不小的影响力,Github 上的 star 已经超过了两万,而尤大本人也承认早期 Vite 的设计也确实受到了 Snowpack 的启发。不管怎么说,Snowpack 本身是一个非常优秀的方案,背后的开发团队是一支非常值得 respect 的团队,我想很有必要将这个方案分享给大家。
时代先锋队——Pika
Snowpack 的开发团队名为Pika,团队的技术紧跟时代的最前沿,在开发 Snowpack 这个新时代前端构建工具的同时,也率先提出了Skypack
这种造福大众的针对 ESM 格式第三方库的 CDN 服务(后续再跟大家详细介绍这个服务到底有多吸引人)。
他们有一个使命: 让 Web 项目构建速度加快 90%。
作为走在时代前沿的他们,始终贯穿着一句研发宗旨:
You should be able to use a bundler because you want to, and not because you need to.
换句话说,在现在的 Web 开发时代,打包不再是必需的选项,而只是一种优化的手段,不用打包也能运行你的应用。现代 Web 构建要变天了,未来即将进入一个 Bundleless(顾名思义,更少的打包,更快的构建速度)的时代,Web 领域在经历之前一系列的工程化改革之后,现在即将又要迎来一场翻天覆地的革新浪潮,而 Snowpack 之父——Pika 团队就是跨时代的弄潮儿,Snowpack 就是 Pika 团队创造新时代而打响的第一枪!
Why?
Snowpack 为什么会诞生?Web 构建为什么会进入 Bundleless 的时代?为什么 Pika 团队宁愿倾其所有去改变当下 Web 项目的构建现状?在真正介绍 Snowpack 之前,这些问题,必须得弄清楚。
在很久很久以前,开发前端网页,似乎并没有现在这么繁杂的工具链和框架,仅仅写一些原生的 HTML 代码、CSS 和一些 JavaScript 代码,那个时候怎么启动项目?直接打开 HTML 文件!我改动了代码怎么看到更新?直接刷新网页!一切看上去都是那么的丝滑,所见即所得,可以说那个时候的前端,足够开门见山,足够简单粗暴,简单得甚至让人有些怀念。
直到后来,随着前端的逻辑越来越复杂,对模块化的需求越来越强烈,逐渐出现了 CommonJS
(2009 年)、AMD
(2010 年)、UMD
(2011 年)这些模块规范,底层的规范出现并稳定之后必然会有上层的工具来实现,由此出现了一系列的工程化方案:
模块加载器,比如 SeaJS 包管理器,比如 npm 打包器,比如 Browserify、Gulp、Webpack
更重要的是,09 的时候 Ryan Dahl 写出了一个叫 Node.js
的东西,给 JS 带来了全新的可能,以前 Java、C++ 能写的工具,用 JS 照样能写了! 也就是从这个时候开始,前端开始变复杂了,各种工具链开始乱花渐欲迷人眼
,尤其是在 2015
年 ESModule 标准的诞生,再次将工程化方案之争推上风口浪尖,最后的胜出者很明显了,就是在座各位如今几乎天天能遇到的Webpack
、Babel
,这两个东西,甚至已经成为了如今前端工程化的代名词了。
Babel 不用多说,是鼎鼎有名的 JavaScript 编译器,在让人眼花缭乱的语法标准中,它能够将灵活地一份 JS 代码从一种语法标准转换到另一种语法标准。
Webpack 是干什么的呢?它给自己的定位其实很简单,就是一个模块打包器。
它的理念是:万物皆模块。
不管代码里面依赖关系多复杂,按照它的模块导入导出语法来写,写完之后把入口扔给它,它给你理清所有的依赖关系,最后打包到一起,给你一份产物,甭管这份产物你能不能看得懂,你大可以放心,浏览器看得懂,并且代码性能和安全性也都还不错。
当然,作为打包器,Rollup
包括Parcel
现在也都是很亮眼的存在,不过在 Webpack 强大的生态和业界落地基础面前,二位就相形见绌了。
但总体来说,对于这样的打包器而言,一定是有潜在的性能风险的,因为它的构建时间是和项目的整体规模成正比的,也就是说,项目规模的变大难以避免构建时长不断增加,现在的前端项目可以说要多复杂有多复杂,你可以尽情地想象打包器的这种性质带来的后果。
果然,这一天还是来了。
五年前,我用 Webpack 打包,启动还挺快的。
五年后,我还是在用 Webpack 打包,团队多了 20 个人,代码多了 20 万行
,现在启动一次要 10 分钟
!代码改动一次,看到结果更新要等 30000 ms
!😭
直到 2018 年的某一天,主流的浏览器 Chrome/Safafi/Firefox 开始支持 ESModule,跟开发者们说,你们只需要把入口代码扔进来,我给你请求所有需要导入的模块,你们不用再煞费苦心写什么打包器把代码放到一起了。
在这时,Pika 团队登场,向全世界宣告: 未来的曙光已经出现,想要摆脱当下的困境,请跟着我们一起朝着光的方向奔跑!
这道曙光指的就是浏览器开始支持 ESModule 标准,他们务必坚定地相信这件事情,并且由于 HTTP/2 的普及,以前将多个静态资源打包到一起从而减少请求次数的性能优化手段不再成为必须,所以打包这个过程也就不再必要。
本着这样的信念和基础,一年之后他们宣布了 Snowpack 的诞生,新时代的第一份 Bundleless 方案终于问世。
和 Webpack 的关系
一方面,与 Webpack 对比,Snowpack 的优势就在于它的构建速度特别快。这种快主要体现在两个方面:
开发阶段相当于启动一个 Dev Server,无需将业务代码进行打包,也就省略了一系列分析依赖、代码打包的繁琐过程,甚至可以直接秒起。
无论项目规模如何增加,构建时间复杂度始终为O(1),不会随项目规模不断增长。
可以看到,当文件变更之后,对于 Webpack 来说,为了整体打包,它需要重新构建依赖图,但对于代表 Bundleless 的 Snowpack 则不是这样,每次都是单文件编译,构建速度不再受限于项目规模,也带来了文件改动后极快的更新速度。
而另一方面,Snowpack 并不排斥 Webpack,在生产环境构建阶段,Snowpack 本身也是提供了插件机制来集成其它的打包器,并且官方提供了开箱即用的插件 @snowpack/plugin-webpack
直接集成 Webpack。这也是相对于 Vite 更加灵活的地方,Vite 只能选择 Rollup 进行生产环境打包,但 Snowpack 可以直接不打包,也可以选择集成任何一个打包器(Webpack
、Rollup
或Esbuild
)进行打包。
小结
这次我们仔细分析了 Snowpack 诞生的历史背景和实现基础,相信你也对 Bundleless 有了初步的认识。当然知道这些还远远不够,关于 Snowpack 以及 Bundleless,有很多的细节需要展开,包括依赖预构建
、Streaming Imports
、插件架构
、HMR 系统
、服务端渲染支持
等等,后续我们会逐渐从使用到内部实现,逐步深入 Snowpack 的方方面面,让你一览新时代构建工具的风采。