1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React Testing Library × Chakra UI】「Cannot find module '@/lib/todo' or its corresponding type declarations.」の解決方法

Posted at

はじめに

お疲れ様です、りつです。

Viteで「React × TypeScript」のプロジェクトを作成し、テストを実装しようとしたところ、表題のエラーに遭遇しました。

問題

jestやReactTestingLibrary導入後、npm run test実行時に以下のエラーが発生しました。

エラー内容

ターミナルのエラー内容
$ npm run test

> type-class@0.0.0 test
> jest

(node:412914) ExperimentalWarning: CommonJS module /home/ritsu/workspace/type-class/node_modules/jest-util/build/requireOrImportModule.js is loading ES Module /home/ritsu/workspace/type-class/jest.config.js using require().
Support for loading ES Module in require() is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
ts-jest[config] (WARN) message TS151001: If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
 FAIL  src/__tests__/App.spec.tsx
  ● Test suite failed to run

    src/App.tsx:3:29 - error TS2307: Cannot find module '@/lib/todo' or its corresponding type declarations.

    3 import { GetAllTodos } from "@/lib/todo"
                                  ~~~~~~~~~~~~
    src/App.tsx:4:22 - error TS2307: Cannot find module '@/domain/todo' or its corresponding type declarations.

    4 import { Todo } from "@/domain/todo"
                           ~~~~~~~~~~~~~~~

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        3.834 s
Ran all test suites.
(node:412914) [DEP0040] DeprecationWarning: The `punycode` module is deprecated. Please use a userland alternative instead.

ソースコード

src/__tests__/App.spec.tsx
import { ChakraProvider, defaultSystem } from "@chakra-ui/react";
import App from "../App";
import { render, screen } from "@testing-library/react";

describe("App", () => {
  it("タイトルがあること", () => {
    render(<ChakraProvider value={defaultSystem}><App /></ChakraProvider>);
    const title = screen.getByTestId("title");

    expect(title).toBeInTheDocument();
  });
});
src/App.tsx
import { useEffect, useState } from "react"
import { Table } from "@chakra-ui/react"
import { GetAllTodos } from "@/lib/todo"
import { Todo } from "@/domain/todo"

function App() {
  const [todos, setTodos] = useState<Todo[]>([]);

  useEffect(() => {
    const getAllTodos = async () => {
      const todoData =  await GetAllTodos();
      setTodos(todoData);
    }

    getAllTodos();
  }, [])

  return (
    <>
      <h1 data-testid="title">TODOリスト</h1>
      <Table.Root size="sm">
        <Table.Header>
          <Table.Row>
            <Table.ColumnHeader>Title</Table.ColumnHeader>
            <Table.ColumnHeader>Done</Table.ColumnHeader>
            <Table.ColumnHeader>CreatedAt</Table.ColumnHeader>
          </Table.Row>
        </Table.Header>
        <Table.Body>
          {todos.map((todo) => (
            <Table.Row key={todo.id}>
              <Table.Cell>{todo.title}</Table.Cell>
              <Table.Cell>{todo.done ? "TRUE" : "FALSE"}</Table.Cell>
              <Table.Cell>{todo.created_at}</Table.Cell>
            </Table.Row>
          ))}
        </Table.Body>
      </Table.Root>
    </>
  )
}

export default App
tsconfig.app.json
{
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "target": "ESNext",
    "useDefineForClassFields": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,

    /* Bundler mode */
    "moduleResolution": "Bundler",
    "allowImportingTsExtensions": true,
    "isolatedModules": true,
    "moduleDetection": "force",
    "noEmit": true,
    "jsx": "react-jsx",

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedSideEffectImports": true,

    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src"]
}
tsconfig.json
{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  "compilerOptions": {
    "jsx": "react-jsx",
    "types": ["node", "jest", "@testing-library/jest-dom"],
  }
}
jest.config.js
export default {
  preset: "ts-jest",
  testEnvironment: "jsdom",
  setupFilesAfterEnv: ["./jest.setup.ts"],
  transform: {
    "^.+\\.(ts|tsx)$": "ts-jest",
  },
  moduleNameMapper: {
    "\\.(css|less)$": "identity-obj-proxy"
  },
};

原因

Chakra UIを導入した際、tsconfig.app.jsonにパスのエイリアスを設定しています。

tsconfig.app.json(一部省略)
{
  "compilerOptions": {
    // 省略
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  // 省略
}

App.tsxなどでimportする時にエイリアスの@を使用してパスを記載しているのですが、それがうまく認識されていないようです。

解決方法

  1. tsconfig.jsonpathsを追加

    {
      "files": [],
      "references": [
        { "path": "./tsconfig.app.json" },
        { "path": "./tsconfig.node.json" }
      ],
      "compilerOptions": {
        "jsx": "react-jsx",
        "types": ["node", "jest", "@testing-library/jest-dom"],
    +   "paths": {
    +     "@/*": ["./src/*"]
    +   }
      }
    }
    
  2. jest.config.jsmoduleNameMapperに追記

    jest.config.js
    export default {
      preset: "ts-jest",
      testEnvironment: "jsdom",
      setupFilesAfterEnv: ["./jest.setup.ts"],
      transform: {
        "^.+\\.(ts|tsx)$": "ts-jest",
      },
      moduleNameMapper: {
        "\\.(css|less)$": "identity-obj-proxy",
    +   "^@/(.*)$": "<rootDir>/src/$1"
      },
    };
    

おわりに

上記の修正で、無事テストが通るようになりました。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?