Skip to content

TypeScript プロジェクト

TypeScript プロジェクトジェネレーターは、ECMAScript Modules (ESM)、TypeScript プロジェクト参照、テスト実行のための Vitest、リントとフォーマットのための Biome などのベストプラクティスで構成された、モダンな TypeScript ライブラリまたはアプリケーションを作成するために使用できます。

新しい TypeScript プロジェクトは2つの方法で生成できます:

Terminal window
pnpm nx g @aws/nx-plugin:ts#project
変更されるファイルを確認するためにドライランを実行することもできます
Terminal window
pnpm nx g @aws/nx-plugin:ts#project --dry-run
パラメータデフォルト説明
name 必須string-TypeScriptプロジェクト名
directory stringpackagesライブラリが配置される親ディレクトリ
subDirectory string-ライブラリが配置されるサブディレクトリ。デフォルトではライブラリ名になります。
preferInstallDependencies booleantrueジェネレーター実行後に依存関係のインストールを優先するかどうか。複数のジェネレーターをバッチ処理する際にインストールを延期する場合はfalseに設定します(後続のジェネレーターがNxプロジェクトグラフを計算できるよう、必要に応じてインストールは実行されます)。最後に一度だけインストールします。

ジェネレーターは <directory>/<name> ディレクトリに以下のプロジェクト構造を作成します:

  • Directorysrc TypeScript ソースコード
    • index.ts
  • package.json プロジェクトのパッケージ名と依存関係を定義するプロジェクトマニフェスト
  • project.json プロジェクト設定とビルドターゲット
  • tsconfig.json このプロジェクトのベース TypeScript 設定(ワークスペースルートの tsconfig.base.json を拡張)
  • tsconfig.lib.json ライブラリ用の TypeScript 設定(ランタイムまたはパッケージ化されたソース)
  • tsconfig.spec.json テスト用の TypeScript 設定
  • vitest.config.mts Vitest の設定

また、ワークスペースルートの以下のファイルにいくつかの変更があることに気付くでしょう:

  • nx.json Nx 設定が更新され、プロジェクト用に @nx/js/typescript プラグインが設定されます
  • tsconfig.base.json プロジェクト用に TypeScript エイリアスが設定され、ワークスペース内の他のプロジェクトからインポートできるようになります
  • tsconfig.json プロジェクト用に TypeScript プロジェクト参照が追加されます

src ディレクトリに TypeScript コードを追加します。

TypeScript プロジェクトは ES Module であるため、正しい ESM 構文でインポート文を記述し、ファイル拡張子を明示的に参照してください:

index.ts
import { sayHello } from './hello.js';

他の TypeScript プロジェクト用のエクスポート

Section titled “他の TypeScript プロジェクト用のエクスポート”

TypeScript プロジェクトのエントリーポイントは src/index.ts です。他のプロジェクトがインポートできるようにしたいものをここでエクスポートできます:

src/index.ts
export { sayHello } from './hello.js';
export * from './algorithms/index.js';

他のプロジェクトでライブラリコードをインポートする

Section titled “他のプロジェクトでライブラリコードをインポートする”

プロジェクトの TypeScript エイリアスはワークスペースの tsconfig.base.json で設定されており、他の TypeScript プロジェクトから TypeScript プロジェクトを参照できます:

packages/my-other-project/src/index.ts
import { sayHello } from '@my-scope/my-library';

ワークスペース内の新しいプロジェクトのインポート文を初めて追加すると、IDE で以下のようなエラーが表示される可能性があります:

インポートエラー
Terminal window
File '/path/to/my/workspace/packages/my-library/src/index.ts' is not under 'rootDir' '/path/to/my/workspace/packages/my-consumer'. 'rootDir' is expected to contain all source files.
File is ECMAScript module because '/path/to/my/workspace/package.json' has field "type" with value "module" ts(6059)
File '/path/to/my/workspace/packages/my-library/src/index.ts' is not listed within the file list of project '/path/to/my/workspace/packages/my-consumer/tsconfig.lib.json'. Projects must list all files or use an 'include' pattern.
File is ECMAScript module because '/path/to/my/workspace/package.json' has field "type" with value "module" ts(6307)

これは、プロジェクト参照がまだ設定されておらず、インポートされたプロジェクトがプロジェクトの package.json でワークスペース依存関係として宣言されていないためです。

ワークスペースは、両方を管理する同期ジェネレーターで設定されているため、手動で設定する必要はありません。次のコマンドを実行するだけで、Nx が必要な設定を追加します:

Terminal window
pnpm nx sync
Terminal window
NX The workspace is out of sync
[@nx/js:typescript-sync]: Some TypeScript configuration files are missing project references to the projects they depend on, contain stale project references, or have duplicate project references.
[@aws/nx-plugin:ts#sync]: Local project dependencies are out of sync. The following workspace dependencies will be declared:
packages/my-other-project/package.json:
- @my-scope/my-library: workspace:*
Syncing the workspace...
The workspace was synced successfully!

Nx の TypeScript 同期ジェネレーターがプロジェクト参照を追加し、プラグインの ts#sync ジェネレーターがインポートされたプロジェクトをプロジェクトの package.json で宣言します(パッケージマネージャーがワークスペースプロトコルをサポートしている場合は workspace:*、npm と yarn classic では *)。これにより、パッケージマネージャーはインストール時にローカルプロジェクトをリンクします。この後、IDE のエラーは消え、ライブラリを使用する準備が整います。

プロジェクトの tsconfig.json にカスタム compilerOptions.paths エントリを追加すると、TypeScript は tsconfig.base.json で定義されたワークスペースエイリアスの継承を停止します。隠された ts#sync ジェネレーターは compile ターゲットの前に実行され(nx.json で設定)、すでに paths を宣言している tsconfig.jsontsconfig.lib.jsontsconfig.app.json ファイルに不足しているベースエイリアスをコピーします。オプトアウトするには、nx.jsontargetDefaults.compile.syncGenerators から @aws/nx-plugin:ts#sync を削除します。

各 TypeScript プロジェクトは、独自の package.json でサードパーティのランタイム依存関係を宣言します。プロジェクト間で共有されるビルドおよびテストツールは、ルートの package.json で定義されます。

プロジェクトにランタイム依存関係を追加するには、そのプロジェクトにインストールします:

Terminal window
pnpm add some-npm-package --filter my-library

プロジェクトのディレクトリ内からパッケージマネージャーの通常の add/install コマンドを実行することもできます。

共有開発ツールを追加するには、ワークスペースルートにインストールします:

Terminal window
pnpm add -Dw some-dev-tool

カタログをサポートするパッケージマネージャー(pnpmyarnbun)の場合、ジェネレーターは各バージョンをカタログに記録し、catalog: プロトコルで参照します(例:"zod": "catalog:")。これにより、どのプロジェクトが依存関係を宣言しても、カタログがバージョンの唯一の信頼できる情報源になります。これは、単一バージョンポリシーに従うのに役立ち、型の競合やデプロイメントバンドル内のパッケージの複数コピーを回避します。

新しい依存関係を自分で追加する場合は、カタログにも保持してください:

ワークスペースは catalogMode: strict を設定しているため、pnpm add はバージョンをカタログに記録し、自動的に参照します — 追加の手順は不要です。

Terminal window
pnpm add some-npm-package --filter my-library

カタログはデフォルトで有効になっています。オフにするには、--catalog false でワークスペースを作成します:

Terminal window
pnpm create @aws/nx-workspace my-project --catalog false

または、いつでも aws-nx-plugin.config.mts で設定します:

aws-nx-plugin.config.mts
export default {
packageManager: {
catalogs: false,
},
} satisfies AwsNxPluginConfig;

カタログを無効にすると、ジェネレーターは依存関係のバージョンを各プロジェクトの package.json に直接書き込み、プロジェクト間でバージョンを整合させることはあなたの責任になります。

すべての依存関係をルートで宣言する

Section titled “すべての依存関係をルートで宣言する”

すべての依存関係をルートの package.json のみで宣言することを好む場合(プロジェクトごとの依存関係宣言なし)、ワークスペースの biome.json でリントルールをオフにします:

biome.json
{
"linter": {
"rules": {
"correctness": {
"noUndeclaredDependencies": "off"
}
}
}
}

プロジェクトはビルド時にルートにインストールされたパッケージを解決するため、すべてが正常にビルドされます — 各プロジェクトの依存関係の正確な記録としてのプロジェクトごとのマニフェストを放棄することになります(これは、後でプロジェクトを公開したり、リポジトリを分割したりする場合に重要です)。

TypeScript プロジェクトをランタイムコードとして使用する場合(例:AWS Lambda 関数のハンドラーとして)、Rolldown などのツールを使用してプロジェクトをバンドルすることをお勧めします。これにより、ツリーシェイクを行い、プロジェクトが実際に参照する依存関係のみが含まれるようにすることができます。

これは、project.json ファイルに次のようなターゲットを追加することで実現できます:

{
...
"targets": {
...
"bundle": {
"cache": true,
"executor": "nx:run-commands",
"outputs": ["{workspaceRoot}/dist/packages/my-library/bundle"],
"options": {
"command": "rolldown -c rolldown.config.ts"
}
},
},
}

そして、次のように rolldown.config.ts ファイルを追加します:

rolldown.config.ts
import { defineConfig } from 'rolldown';
export default defineConfig([
{
input: 'src/index.ts',
output: {
file: '../../dist/packages/my-library/bundle/index.js',
format: 'cjs',
codeSplitting: false,
},
},
]);

TypeScript プロジェクトは build ターゲット(project.json で定義)で設定されており、次のコマンドで実行できます:

Terminal window
pnpm nx build <project-name>

ここで、<project-name> はプロジェクトの完全修飾名です。

build ターゲットは、プロジェクトをコンパイル、リント、テストします。

ビルド出力は、ワークスペースのルート dist フォルダー内の、パッケージとターゲット用のディレクトリ内にあります。例:dist/packages/<my-library>/tsc

ワークスペース内のすべてのプロジェクトをビルドするには、次を実行します:

Terminal window
pnpm nx run-many --target build

または、ショートハンドコマンドを使用します:

Terminal window
pnpm build

Vitest がプロジェクトのテスト用に設定されています。

テストは、プロジェクトの src フォルダー内に配置された .spec.ts または .test.ts ファイルに記述する必要があります。

例:

  • Directorysrc
    • hello.ts ライブラリソースコード
    • hello.spec.ts hello.ts のテスト

Vitest は、describeittestexpect などのユーティリティを使用して、Jest のような構文でテストを定義できます。

hello.spec.ts
import { sayHello } from './hello.js';
describe('sayHello', () => {
it('should greet the caller', () => {
expect(sayHello('Darth Vader')).toBe('Hello, Darth Vader!');
});
});

テストの記述方法や依存関係のモック化などの機能の詳細については、Vitest ドキュメントを参照してください。

テストはプロジェクトの build ターゲットの一部として実行されますが、test ターゲットを実行して個別に実行することもできます:

Terminal window
pnpm nx test <project-name>

Vitest の -t フラグを使用して、個々のテストまたはテストスイートを実行できます。-- セパレーターの後に渡すことで、Nx が独自の --target オプションとして消費するのではなく、Vitest に転送します:

Terminal window
pnpm nx test <project-name> -- -t 'sayHello'

TypeScript プロジェクトは、リントとフォーマットに Biome を使用します。Biome はワークスペースルートの biome.json ファイルで設定されます — これに対する変更は、ワークスペース内のすべての TypeScript プロジェクトに適用され、一貫性を確保します。

プロジェクトをチェックするためにリンターを呼び出すには、lint ターゲットを実行できます。

Terminal window
pnpm nx lint <project-name>

リントまたはフォーマットの問題の大部分は、--configuration=fix 引数を付けて実行することで自動的に修正できます。

Terminal window
pnpm nx lint <project-name> --configuration=fix

同様に、ワークスペース内のすべてのパッケージのすべてのリント問題を修正したい場合は、次を実行できます:

Terminal window
pnpm nx run-many --target lint --all --configuration=fix

開発中にリント問題によって速度が低下するのを避けるため(特にプロジェクトに自動修正できない問題がある場合)、skip-lint 設定でビルドを実行できます:

Terminal window
pnpm nx run-many --target build --configuration=skip-lint

これにより、ビルド中に lint ターゲットが完全にスキップされます。