Resolverとは?
たとえば次のようなコードがあるとします。
import Button from "@/components/Button";
JavaScriptエンジンが実際に認識しているのは、次のspecifierだけです。
specifier = "@/components/Button"
次に、解決すべき問題は次のとおりです。
specifier
↓
真实模块
このマッピング処理はResolutionと呼ばれます。
Nodeがデフォルトでサポートするspecifier
Node標準のResolverがサポートするのは、次の4種類だけです。
import "./foo.js"
import "../foo.js"
import "/app/foo.js"
パスモジュール。
パッケージモジュール。
Package Imports。
URLモジュール。
除此之外、たとえば次のようなspecifierがあります。
Nodeはこれを解決できません。
そのまま
Module Not Found
という例外経路に入ります。
Aliasが機能するのはなぜ
たとえば次のようなコードがあるとします。
Webpackの設定は次のとおりです:
Webpackが本来の解決処理を実行する前にも、まずAlias Resolverを通ります。
@/components/Button
Alias Resolverによる変換結果は次のとおりです:
/project/src/components/Button
その後、通常のモジュール解決処理に進みます。
つまり、Aliasは新しいモジュールタイプではありません。単なる
旧 specifier
↓
新 specifier
というspecifierの置換にすぎません。
ViteのAlias
Viteでも次のように設定できます:
実行フローはWebpackとまったく同じです。
次のimportについて、
Viteがまず行うのは次の置換です:
@ -> /project/src
置換後のspecifierは次のとおりです:
/project/src/utils/request
その後、引き続き解決処理を実行します。
次の3つは、
Webpack Alias
Vite Alias
Rspack Alias
であり、本質的には同じ仕組みです。
異なるのはResolverの実装だけです。
TypeScriptのPathsが機能しないのはなぜ?
設定は次のとおりです:
多くの場合、次のような状況になります。
VSCode 正常
TypeScript 正常
Node 运行失败
原因は、
paths
が実行時のResolverではないことです。
TypeScriptは、
类型检查
IDE 跳转
编译阶段
の段階でだけpathsを使用します。
Nodeの実行時は、
をまったく読み込みません。
したがって、
という設定だけでは、Nodeは
を解決できません。Nodeにこのspecifierを認識させるには、次のいずれかを追加で設定する必要があります:
Webpack Alias
Vite Alias
Rspack Alias
Node Loader
のいずれか1つ。
Node LoaderでAliasを実装する方法
Nodeは次の関数を提供しています:
これにより、解決処理を引き継げます。
たとえば、次のように実装できます:
この場合、
は次のように変換されます:
file:///project/src/utils.js
その後、通常の読み込み処理に進みます。
ブラウザーのImport Map
ブラウザーには
node_modules
がないため、
はそのままでは機能しません。
Import Mapは、次のようにマッピングを指定できます:
例えば、
をインポートすると、
ブラウザーはまず次のようにマッピングします:
react
↓
/vendor/react.js
その後、ロードを続けます。
Resolverの本質
次のものを比較すると、
Webpack Alias
Vite Alias
Rspack Alias
TS Paths
Node Loader
Import Map
いずれも同じことをしています:
specifier
↓
mapping
↓
new specifier
↓
real URL
違いがするのは、マッピングルールが置かれている場所だけです:
映射规则存放的位置不同
モジュールグラフの起点
たとえば、
コンパイラはまず次の処理を行います:
specifier
↓
resolver
↓
real module
その結果、
App.tsx
が得られます。
その後、次のように依存関係をたどります:
App.tsx
↓
Button.tsx
↓
request.ts
↓
...
最終的に構築されるのは
Module Graph
です。Tree Shaking、Code Splitting、HMR、Chunk分割は、すべてこのグラフの上に成り立っています。
したがって、Resolverこそ、現代的なフロントエンドツールチェーン全体の出発点です。