TSConfig と vitest.config で、非相対モジュール名を解決するベースディレクトリを設定する

2023.09.06

こんにちは、CX事業本部 Delivery部の若槻です。

今回は、TypeScript と Vitest で構成ファイル(TSConfig と vitest.config)を設定して、モジュールインポート時のカスタムプレフィクスを指定する方法を確認してみました。

これにより、下記のように相対モジュール名ではなく、ベースディレクトリを使用した非相対モジュール名を指定できるようになります。

// 相対モジュール名
import { logger } from "../../../utils/logger";

// ベースディレクトリを指定した非相対モジュール名
import { logger } from "@/utils/logger";

これにより、インポート分の読み書きがしやすくなり、またモジュールの移動によるパスの変更にも対応しやすくなります。

カスタムプレフィクスの指定

TSConfig

モジュールファイルでのカスタムプレフィクスを定義する場合は、tsconfig.jsonで次のようにcompilerOptionsを設定します。

packages/server/tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}
  • baseUrl
    • pathsで指定するパスのベースディレクトリを定義します。
  • paths
    • カスタムプレフィクスのマッピングを定義します。

vite.config

Vitest のテストファイルでカスタムプレフィクスを使用したい場合は、vitest.config.tsで次のようにtest.aliasを設定します。

packages/server/vitest.config.ts

import * as path from "path";
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
});

上記ではインポート構文でのパス指定をエイリアス@に置き換えています。

動作確認

モジュールファイル

モジュールファイルでは、次のようにインポート構文でカスタムプレフィクスを使用した非相対モジュール名を指定できるようになります。

packages/server/src/lambda/handlers/api-gateway/create-company.ts

import { APIGatewayProxyEvent } from "aws-lambda";
import * as zod from "zod";

import { createCompanyService } from "@/lambda/domains/services/create-company";
import * as HttpUtil from "@/utils/http-response";
import { logger } from "@/utils/logger";

// some process

テストファイル

Vitest のテストファイルでは、次のようにインポート構文に加えて、vi.mockでモックしたいモジュールの指定時にもカスタムプレフィクスを使用できるようになります。

packages/server/src/lambda/handlers/api-gateway/create-company.test.ts

import { APIGatewayProxyEvent } from "aws-lambda";
import { expect, test, describe, vi, afterEach } from "vitest";

import { handler } from "./create-company";
import { createCompanyService } from "@/lambda/domains/services/create-company";

const event = {} as APIGatewayProxyEvent;

describe("handler", (): void => {
  vi.mock("@/lambda/domains/services/create-company", () => {
    return {
      createCompanyService: vi
        .fn()
        .mockResolvedValue({ id: "dummy-id", name: "dummy-name" }),
    };
  });

  // some test
});

おまけ

TSConfig で次のようにcompilerOptions.esModuleInteroptrueに設定すると、import * as zod from "zod"のように名前空間インポートが可能になります。

packages/server/tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"]
    },
    "esModuleInterop": true
  }
}

よって、次のように vitest.config.ts でimport * as path from "path"のように名前空間インポートすることができるようになります。

packages/server/vitest.config.ts

import path from "path";
import { defineConfig } from "vitest/config";

便利なので設定を追加しておくと良いでしょう。

おわりに

TSConfig と vitest.config で、非相対モジュール名を解決するベースディレクトリを設定する方法を確認してみました。

冒頭で示したように、インポート分の読み書きや、モジュールの移動によるパスの変更への対応のしやすさが大きく向上するので、ぜひ設定してみてください。

参考

以上