Resolver 是什么
对于:
import Button from "@/components/Button";
JavaScript 引擎实际上只看到了:
CodeBlock Loading...
接下来需要解决的问题是:
CodeBlock Loading...
这个过程称为 Resolution。
Node.js ESM 规范中的入口算法:
CodeBlock Loading...
本质就是完成这个映射过程。
Node 默认支持哪些 specifier
Node 原生 Resolver 只支持四类:
CodeBlock Loading...
路径模块。
CodeBlock Loading...
包模块。
CodeBlock Loading...
Package Imports。
CodeBlock Loading...
URL 模块。
除此之外:
CodeBlock Loading...
Node 无法解析。
直接进入:
CodeBlock Loading...
异常路径。
为什么 Alias 可以工作
假设存在:
CodeBlock Loading...
Webpack 配置:
CodeBlock Loading...
Webpack 在执行真正解析前:
CodeBlock Loading...
先经过 Alias Resolver:
CodeBlock Loading...
随后再进入正常模块解析。
因此 Alias 并不是一种新的模块类型。
而是:
CodeBlock Loading...
的一次转换。
Vite Alias
Vite:
CodeBlock Loading...
执行流程与 Webpack 完全一致。
对于:
CodeBlock Loading...
Vite 首先执行:
CodeBlock Loading...
得到:
CodeBlock Loading...
然后继续执行后续解析。
因此:
CodeBlock Loading...
本质是同一个东西。
区别只是 Resolver 实现不同。
TypeScript Paths 为什么经常失效
配置:
CodeBlock Loading...
很多人会发现:
CodeBlock Loading...
原因是:
CodeBlock Loading...
不是运行时 Resolver。
TypeScript 只会在:
CodeBlock Loading...
使用 paths。
Node 运行时根本不会读取:
CodeBlock Loading...
因此:
CodeBlock Loading...
无法让 Node 识别:
CodeBlock Loading...
必须额外配置:
CodeBlock Loading...
其中之一。
Node Loader 如何实现 Alias
Node 提供:
CodeBlock Loading...
允许接管解析过程。
例如:
CodeBlock Loading...
此时:
CodeBlock Loading...
会变成:
CodeBlock Loading...
然后进入正常加载流程。
Browser Import Map
浏览器没有:
CodeBlock Loading...
因此:
CodeBlock Loading...
无法工作。
Import Map 的作用:
CodeBlock Loading...
执行:
CodeBlock Loading...
时。
浏览器先映射:
CodeBlock Loading...
再继续加载。
Resolver 的本质
观察:
CodeBlock Loading...
会发现它们都在做同一件事:
CodeBlock Loading...
区别仅在于:
CodeBlock Loading...
模块图的起点
对于:
CodeBlock Loading...
编译器首先执行:
CodeBlock Loading...
得到:
CodeBlock Loading...
然后继续递归:
CodeBlock Loading...
最终构建:
CodeBlock Loading...
Tree Shaking、Code Splitting、HMR、Chunk 拆分全部建立在这个图之上。
因此 Resolver 是整个现代前端工具链真正的入口。