一、简要
ESM,是指构成ESM规范的一系列的JavaScript特性或者API
1、首先要明确的是,Vite跟WebPack的优势只在开发环境。当把包部署到了生产环境后,大家都是一样的,甚至webpack的兼容性可能会更好。 这也是为什么有人提出,开发环境用Vite,打包时用webpack。
提问:为什么webpack的兼容性更好?
二、Vite 解决了 WebPack 的什么痛点 ?
1、冷启动时长(刚启动项目的时候)。我个人认为这是Vite解决了webpack的最大痛点,在项目非常大的时候,启动时间要等很久。
1.1为什么能比WebPack冷启动快很多?
Vite 通过在一开始将应用中的模块区分为 依赖 和 源码 两类,改进了开发服务器启动时间。
1、使用了GO语言编写的esbuild 预构建工具 ,许多内部模块的 ESM 依赖项转换为单个模块。有些包将它们的 ES 模块构建为许多单独的文件 。
2、Vite 以 原生 ESM 方式提供源码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入代码,即只在当前屏幕上实际使用时才会被处理。
简而言之: 使用了更好的预构建工具,最重要的是使用了原生的ESM来动态导入模块。
tip: 跟下面的解释一样,纯纯是ESM厉害,webpack使用联邦模块一样做到了这样的动态导入。
2、热更新时长。热更新差别不大,最新的webpack使用了联邦模块,既MSFU,热更新也是非常快。
2.1、vite 为什么能 webpack 热更新更快?
这里标注一个词 动态模块热替换(HMR)。同时讲下热更新是如何实现的? 正常的更新都是重新编译整个项目,重新打包。但热更新是,哪个文件改变了,重新构建这个模块,同时原先的这个模块失活(断掉链接),webpack 通过联邦模块消费这个新的模块,Vite 在原生 ESM 上执行的,重新链接这个新的模块。
1、Vite 的热更新模块是基于 ESM,纯纯是ESM 厉害。
2、Vite 还利用了 HTTP 头来加速整个页面的重新加载。
源码模块的请求会根据 304 Not Modified
进行协商缓存,而依赖模块请求则会通过 Cache-Control: max-age=31536000,immutable
进行强缓存,因此一旦被缓存它们将不需要再次请求。
总结: Vite 比 Webpack 快,完全是因为ESM 。不管热更新还是冷启动,webpack都做了对应的优化,但就是比不过基于ESM做的优化。
ESM的来源与定义
ESM是一种规范,这个规范里面包含有一些新的语法和概念,包括`import`和`export`关键字、模块作用域等,是在ES6引入,后逐渐被大部分浏览器所支持。所以,我们通常说的ESM,其实是指构成ESM规范的一系列的JavaScript特性或者API。
ESM(ECMAScript Modules)是一种在 JavaScript 中使用模块化编程的标准。浏览器支持 ESM 是通过实现 JavaScript 的内置模块系统来实现的。在支持 ESM 的浏览器中,可以使用`<script type="module">`标签来加载模块。当浏览器遇到该标签时,会将其内部的 JavaScript 代码视为一个模块并进行加载。在模块中,可以通过`import`语句引入其他模块,也可以通过`export`语句将模块中的内容暴露给其他模块使用。
支持 ESM 的浏览器使用了一种叫做“异步模块定义”(AMD)的技术。当浏览器遇到`<script type="module">`标签时,它会将该标签内部的 JavaScript 代码下载并解析,然后使用异步加载技术来加载该模块所依赖的其他模块。这样,当一个模块依赖的其他模块还没有加载完成时,浏览器就不会执行该模块的代码,从而避免了因为依赖关系而导致的代码执行错误。
总的来说,浏览器支持 ESM 是通过实现 JavaScript 的内置模块系统来实现的,并且使用了异步加载技术来解决模块之间的依赖关系。
ESM是在ECMAScript 6标准中被引入的,它通过`import`和`export`语法来实现模块化。在ES6之前,JavaScript本身并没有原生支持模块化,因此开发者们使用各种不同的模块加载器和打包工具来解决这个问题。为了实现ESM,在ES6标准制定时,JavaScript语言设计者们引入了一些新的语法和概念,包括`import`和`export`关键字、模块作用域等。同时,JavaScript运行时环境(如浏览器和Node.js)也需要升级以支持这些新特性。浏览器和Node.js的开发者们都在近年来逐步对ESM进行支持,使得JavaScript语言的模块化能力越来越强大。