ESM,即 ES 模块,也就是 JavaScript 模块。比如,import
及其相关语句。
如今浏览器都支持它了。虽然其中有很多细微差别,但只要你放弃了 IE,这条路就基本畅通无阻了。
在 ESM 之前,JavaScript 项目的状况是
- 我们需要使用 npm 中的包。
- 我们会提前使用
package.json
和npm install
等命令从 npm 安装它们。 - 我们会编写
import
语句,出于某种原因(可能是为了开发者方便),这些语句并非有效的 ESM,并假设我们正在从本地node_modules
文件夹导入包。 - 我们的打包器会知道如何处理这些无效的导入。
- 这一切都没有问题,因为坊间传言打包对于性能仍然是必要的,而且它还会执行我们想要的其他操作,比如运行 Babel 等工具。
现在,由于我们可以更多地依赖 ESM,所以情况正在发生一些变化,所有这些事情都受到了质疑。
- 如果我们不必
npm install
会怎样? - 如果我们不需要打包器会怎样?
- 如果性能没问题,在 HTTP/2+、全球 CDN、浏览器执行各种高级操作等情况下会怎样?
- 如果我们可能不应该 过度编译代码,因为我们过度向下兼容会怎样?
我们看到下一代工具正在利用所有这些优势。 Snowpack 3 刚刚发布,看看这个
这个 React(带有 JSX),按照通常的方式编写,没有 npm install
,没有 node_modules
目录,也没有构建步骤。但是,仍然有开发服务器和重新加载功能。非常轻量级。非常令人耳目一新。
我刚刚听了 最近一期 Toolsday 节目,Una 和 Chris 与 Jason Miller 聊了聊 WMR,我之前从未听说过。它在精神上感觉与 Snowpack/Skypack 非常相似。使用 WMR,你可以使用 npm 包而无需安装它们,或者使用 JSX、TypeScript 或 CSS Modules 等编写代码,并获得许多开发便利,例如服务器、热重载等。
显然,这里有一些东西在起作用,我认为那就是对 ESM 的倚重。
即使在 Node.js 方面,ESM 也正在发生。 这是 Sindre Sorhus 的观点,他拥有超过 1000 个 npm 包(!)
2021 年 4 月底,Node.js 10 将停止维护,这意味着包维护者可以将目标设置为 Node.js 12。这个 Node.js 版本完全支持JavaScript 模块,也称为 ESM。
他计划在 2021 年将这 1000 个包中的几乎所有包迁移到 ESM。不是“双重”设置,输出多种不同的格式……仅 ESM,他鼓励每个人都这样做。我认为,当 npm 生态系统也做同样的事情时,这种向浏览器中直接使用 ESM 的趋势会得到极大的推动。
当你确实需要打包时,例如,npm 上的一些东西还没有准备好使用 ESM,那么 新一代打包器速度非常快。
现在使用 npm,只要我已经下载了这些包,无论我是否想在没有网络连接的情况下运行我的项目,都没关系。ESM 会在浏览器之外的某个地方进行本地缓存吗?
像 Skypack 这样的 CDN 会缓存这些包,并且访问次数越多,缓存时间越长。因此,非常流行的库在这些 CDN 上的速度会非常快。或者也许我错了。不知道
恐怕你把两件事搞混了。
Snowpack 或 WMR 会像 NPM/Yarn 一样在本地缓存它们(尽管可能不会与其他项目共享,我不确定)。
但是,如果你在浏览器中直接使用
import Foo from "https://…"
而没有一些工具来转换它,则不会涉及本地缓存。我认为对于 WMR 来说可能是这样,但 Skypack 是一个用于包的全局 CDN,你根本不会在本地拉取,而 Snowpack 3 具有使用它的“流式导入”。 来自他们的博文
等等,Node 对 ES 模块的支持难道也是伪 ES 模块吗?
关于你“我们可能不应该过度编译代码”的问题,以及你最后一段,你是否在某种程度上混淆了打包与转译和/或解析依赖项?
除了使用 Babel/Bublé/其他工具或使用“裸导入说明符”导入之外,打包还有其他原因,你可以在不打包的情况下使用 Babel/等工具,最后你可能可以有一个工具来重写裸导入说明符并移动文件,而无需触碰代码中的任何其他内容(例如,作为缺少导入映射支持的解决方法)。
我们倾向于将打包器用于所有这些事情,但它们只是我们构建管道中的步骤,我们可以单独执行这些步骤,或者根本不执行。