🙆♀️
NestJSをESModules化する
これはなに
モジュールシステムはCommonJSとESModulesがあり、NestJSをnest new
で作成するとデフォルトでCommonJSになっています。
このことはtsconfig.json
を見ても分かります。
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
// ...
}
しかしここ数年でいろいろなライブラリがESModulesに対応する流れがあり、NestJSのプロジェクトでもESModules化をしてみます。
CommonJSで困ること
CommonJSのままだと、ESModules形式だけを提供するPure ESMのライブラリを読み込むことができません。
例えば、ログに色をつけるchalkはv5.0.0以降はPure ESMとなっています。
これをインストールして、適当な箇所に書いてみます。
src/app.service.ts
import { Injectable } from '@nestjs/common';
import chalk from 'chalk';
@Injectable()
export class AppService {
getHello(): string {
// chalkを使ってみる
console.log(chalk.blue('Hello World!'));
return 'Hello World!';
}
}
これでNestを起動するとエラーになります。
❯ npm run start
> my-esm-2@0.0.1 start
> nest start
/Users/*****/dist/app.service.js:315
undefined
^
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/*****/node_modules/chalk/source/index.js from /Users/*****/dist/app.service.js not supported.
Instead change the require of index.js in /Users/*****/dist/app.service.js to a dynamic import() which is available in all CommonJS modules.
at TracingChannel.traceSync (node:diagnostics_channel:315:14)
at Object.<anonymous> (/Users/*****/dist/app.service.js:11:17) {
code: 'ERR_REQUIRE_ESM'
}
NestをESModules化することでこれを解消できます。
NestJSのESModules化
tsconfigを以下のように変更する。
tsconfig.json
{
"compilerOptions": {
- "module": "commonjs",
+ "module": "Node16",
+ "moduleResolution": "Node16",
// ...
}
package.jsonに以下を追記する。
package.json
{
// ...
+ "type": "module",
// ...
import文の末尾に.js
をつける。
- import { AppService } from './app.service';
+ import { AppService } from './app.service.js';
これで無事にNestを起動して、chalkによって色付きのログが表示されるようになります。
Discussion