Closed4
ts-node や nestjs で絶対パスと ESM を同時に使う
片方ずつであれば方法はそこらじゅうに転がってる。
絶対パス
ESM
これとか
両方を使うように設定するとこんなエラーが出る
CustomError: Cannot find package '@/xxx' imported from yyy
問題は2つあって、「ts-node/esm が paths を読まない」「tsconfig-paths は ESM 標準の書き方 (拡張子付きの import) を変換しない」
これを解決するカスタムローダーを作らないといけない。
issue とか pull request などもある。
結論としてはこれで動いた。ts-node/esm を使いつつ、matchPath には拡張子を除いたパスを渡して変換してもらう。
import { pathToFileURL } from 'url';
import {
resolve as esmResolve,
getFormat,
transformSource,
load,
} from 'ts-node/esm';
import { createMatchPath, loadConfig } from 'tsconfig-paths';
export { getFormat, transformSource, load };
const { absoluteBaseUrl, paths } = loadConfig();
const matchPath = createMatchPath(absoluteBaseUrl, paths);
export async function resolve(specifier, context, defaultResolve) {
// *.js を matchPath が展開できないため、matchPath 前後で拡張子を付け直す
if (specifier.endsWith('.js')) {
const trimmed = specifier.substring(0, specifier.length - 3);
const matchedSpecifier = matchPath(trimmed);
if (matchedSpecifier) {
return esmResolve(
pathToFileURL(`${matchedSpecifier}.js`).toString(),
context,
defaultResolve,
);
}
}
return esmResolve(specifier, context, defaultResolve);
}
nestjs はビルド時に paths を変換してくれる機能があるみたいですが、拡張する方法が見当たらなかったので実行時に解決させるようにした。パワー💪
package.json
を抜粋
"scripts": {
"build": "nest build",
"start": "node --loader ./custom-loader.js dist/main.js",
"dev": "node --loader ./custom-loader.js ./node_modules/.bin/ts-node src/main.ts"
}
このスクラップは6ヶ月前にクローズされました