精读《snowpack》

高分请说明下,精读《snowpack》
最新回答
vigilia°宝瓜

2026-10-18 12:38:24

基于webpack构建的大型项目开发速度已经非常缓慢,前端开发者已经逐渐习惯了超过100秒的启动时间和超过30秒的reload时间。即使被寄予厚望的webpack5内置了缓存机制,也无法获得质的提升。然而,十年前的等待时间只有几百毫秒。

幸运的是,浏览器支持了ESM import模块化加载方案,原生支持了文件模块化,这使得本地构建不再需要处理模块化关系并聚合文件,甚至可以将构建时间从30秒降低到300毫秒。

当然,基于ESM import的构建框架不止snowpack一个,还有如基于vue的vite。因为浏览器支持模块化是一个标准,而不与任何框架绑定,未来任何构建工具都会基于此特性开发。这意味着在未来的五年,前端构建一定会回到十年前的速度,这个趋势是明显、确定的。

ESM import带来的最直观的改变有下面三点:

所以可以说ESM import模式下的开发效率,能做到与十年前修改HTML单文件的零构建效率几乎相当。

Snowpack的核心特征:

安装:通过snowpack.config.json文件配置,并能自动读取babel.config.json生效babel插件。

开发调试:调试snowpack dev,编译snowpack build,会自动以src/index作为应用入口进行编译。

Snowpack dev命令几乎是零耗时的,因为文件仅会在被浏览器访问时进行按需编译,因此构建速度是理想的最快速。

当浏览器访问文件时,snowpack会将文件做如下转换:

目的就是生成一个相对路径,并启动本地服务让浏览器可以访问到这些被import的文件。其中web_modules是snowpack对node_modules构建的结果。

在这之前也会对Typescript文件做tsc编译,或者babel编译。

编译:编译命令snowpack build默认方式与snowpack dev相同:

也可以指定以webpack作为构建器:

除了默认构建方式之外,还支持自定义文件处理,通过snowpack.config.json配置scripts指定:

比如上述语法支持了对scss文件编译的拓展。

"build:*": "..."

对文件后缀进行编译,比如:"build:js,jsx": "babel --filename $FILE" 指定了对js,jsx后缀的文件进行babel构建。

"run:*": "..."

仅执行一次,可以用来做lint,也可以用来配合批量文件处理命令,比如tsc: "run:tsc": "tsc"

"mount:*": "mount DIR [--to /PATH]"

将文件部署到某个URL地址,比如"mount:public": "mount public --to /" 意味着将public文件夹下的文件部署到/这个URL地址。

还有proxy等API就不一一列举了,详细可以见官方文档。

我们可以从构建命令体会到snowpack的理念,将源码以流式方式编译后,直接部署到本地server提供的URL地址,浏览器通过一个main入口以ESM import的方式加载这些文件。

所以所有加载与构建逻辑都是按需的,snowpack要做的只是将本地文件逐个构建好并启动本地服务给浏览器调用。

前端开发离不开node_modules,snowpack通过snowpack install的方式支持了这一点。

Snowpack install这个命令已经被snowpack dev内置了,所以snowpack install仅用来理解原理。

以下是snowpack install执行的结果:

可以看到,snowpack遍历项目源码对node_modules的访问,并对node_modules进行了Web版install,可以认为npm install是将npm包安装到了本地,而snowpack install是将node_modules安装到了Web API,所以这个命令只需构建一次,node_modules就变成了可以按需被浏览器加载的静态资源文件。

同时源码中对npm包的引用都会转换为对web_modules这个静态资源地址的引用:

但同时可以看到snowpack对前端生态的高要求,如果某些包通过webpack别名设置了一些magic映射,就无法通过文件路径直接映射,所以snowpack生态成熟需要一段时间,但模块标准化一定是趋势,不规范的包在未来几年内会逐步被淘汰。

2020年适合使用snowpack吗?答案是还不适合用在生产环境。

当然用在开发环境还是可以的,但需要承担三个风险:

但可以看到,这些风险的原因都是非标准化造成的。我们站在2020年看以前浏览器非标准化API适配与兼容工作,可能会觉得不可思议,为什么要与那些陈旧非标准化的语法做斗争;相应的,2030年看2020年的今天可能也觉得不可思议,为什么很多项目存在大量magic自定义构建逻辑,明明标准化构建逻辑已经完全够用了 :P。

所以我们要看到未来的趋势,也要理解当下存在的问题,不要在生态尚未成熟的时候贸然使用,但也要跟进前端规范化的步伐,在合适的时机跟上节奏,毕竟bundleless模式带来的开发效率提升是非常明显的。

前端发展到2020年这个时间点,代码规范已经基本稳定,工程化要做的事情已经从新增功能逐渐转移到研发提效上了,因此提升开发时热更新速度、构建速度是当下前端工程化的重中之重。

Snowpack代表的bundleless方案肯定是光明的未来,带来的构建提效非常明显,人力充足的前端团队与不需要考虑浏览器兼容性的敏捷小团队都已经开始实践bundleless方案了。

但对于业务需要兼容各浏览器的大团队来说,目前bundleless方案仅可用于开发环境,生产环境还是需要webpack打包,因此webpack生态还可以继续繁荣几年,直到大的前端团队也抛弃它为止。

如果看未来十年,可能前端工程化构建脚本都不需要了,浏览器可以直接运行源码。在这一点上,以snowpack为代表的bundleless模式着实跨越了一大步。