Skip to content

基于 ESM 的开发服务器

传统开发服务器

在传统的开发服务器情况下,启动一个项目时,程序会先获取你的所有资源进行处理解析,处理完之后打包成一个 bundle.js 文件并传给浏览器运行。

基于 ESM 的开发服务器

基于 ESM 的开发服务器刚好与传统的开发服务器相反,它是先启动一个项目服务,当你访问它的时候,它会通过 http 服务去请求你的主入口文件 main.js 一步步去分析和处理。例如 main.js 中注册的路由页面又引用了哪些模块依赖。最终呈现效果到网页上。

从而达到了真正的按需引入,当前页面用了哪些模块就加载哪些模块资源,而不会一次性把所有资源都加载进来,包括用不上的。所以首屏的渲染时间也大大减少了。

Vite 还做了更多的优化事情

Vite 不仅使用了基于 ESM 的开发服务器,它在项目启动和更新上还做了一些额外的优化。Vite 将项目的中代码区分为两大类,依赖和源码。

对依赖项做的处理

依赖指的是第三方库 node_modules,这些依赖基本上是不会有变动的,也不会特意去改它。

如果项目中用到的依赖包很多,那么平常通过 JavaScript 去处理的代价是很高的,甚至这些依赖还存在多种模块化的标准(例如 ESM 或者 CommonJS)。

所以 Vite 将会使用 esbuild 进行预构建依赖,而 esbuild 又是使用 Go 语言编写的,相比 Javascript 语言编写的预构建工具快 10-100 倍。

另外浏览器请求依赖资源时,通过 Cache-Control: max-age=31536000,immutable 进行强缓存,因此一旦被缓存它们将不需要再次请求了。

对源码做的处理

我们的源码并非都是 Javascript, 可能还有 Sass Vue 之类的文件,这些文件都是要额外编译处理的,浏览器默认都是不支持的。

当浏览器请求源码时,vite 会进行转换和按需提供源码,不是当前路由下的源码不会提供。

另外浏览器请求源码时,通过 304 Not Modified 进行协商缓存。

为什么生产环境仍需要打包

尽管原生 ESM 得到了广泛的支持,但是打包环节还是要有的。例如下面列举的一些事项,并不都是在开发的环境中适合的。

  • 利用插件将代码进行压缩

  • Tree-shaking 移除没有作用的代码

  • 根据路由懒加载实现分包 chunk

  • 合并嵌套导入,减少 http 请求