実現したいこと
Next.jsプロジェクトでのJestでのテスト実行
前提
Next.jsのプロジェクトをcreate-next-app
で作成し、nanoidというライブラリをインストールしてJestでテストを実行したところ、SyntaxError: Unexpected token 'export' というエラーが出ました。
nanoidのimport部分を削除すると問題なくテストが実行されました。
以下の記事を参考に、jest.config.js
に以下を書き加えましたが、全く同じエラーが出ます。
javascript
1const config = { 2 // 追記 3 transformIgnorePatterns: [`node_modules/(?!nanoid/)`], 4 // その他の設定 5} 6 7module.exports = config
参考にした記事:https://beyooon.jp/blog/nanoid-v4-fails-jest/
発生している問題・エラーメッセージ
npm run test でターミナルに出力されるエラーです。
node_modules/nanoid/index.browser.js
というファイルの export でエラーが出ているようです。
terminal
1> next13-jest-swc@0.1.0 test 2> jest 3 4 FAIL __test__/index.test.tsx 5 ● Test suite failed to run 6 7 Jest encountered an unexpected token 8 9 Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax. 10 11 Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration. 12 13 By default "node_modules" folder is ignored by transformers. 14 15 Here's what you can do: 16 • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it. 17 • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript 18 • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config. 19 • If you need a custom transformation specify a "transform" option in your config. 20 • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option. 21 22 You'll find more details and examples of these config options in the docs: 23 https://jestjs.io/docs/configuration 24 For information about custom transformations, see: 25 https://jestjs.io/docs/code-transformation 26 27 Details: 28 29 /Users/user/dev/react-liblary-exmples/next13-jest-swc/node_modules/nanoid/index.browser.js:1 30 ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { urlAlphabet } from './url-alphabet/index.js' 31 ^^^^^^ 32 33 SyntaxError: Unexpected token 'export' 34 35 10 | 36 37 at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1495:14) 38 at Object.<anonymous> (src/pages/index.tsx:12:17) 39 at Object.<anonymous> (__test__/index.test.tsx:7:55) 40 41Test Suites: 1 failed, 1 total 42Tests: 0 total 43Snapshots: 0 total 44Time: 1.11 s 45Ran all test suites.
試したこと
前提の部分で参考にした記事によれば、nanoid4以降で発生している問題らしいので、nanoidのverison3をインストールし直してテストを実行してみました。
以下のようなエラーが出ました。
やはり/node_modules/nanoid/index.browser.js
というファイルで、この場合は import でエラーが出ています。
Details: /Users/sekiguchi/dev/react-liblary-exmples/next13-jest-swc/node_modules/nanoid/index.browser.js:1 ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { urlAlphabet } from './url-alphabet/index.js' ^^^^^^ SyntaxError: Cannot use import statement outside a module
該当のソースコード
テスト対象のページ(index.tsx)です
tsx
1import { nanoid } from 'nanoid' 2export default function Home() { 3 return ( 4 <> 5 <div>{nanoid()}</div> 6 </> 7 8 ) 9}
テストコード(index.test.tsx)です
tsx
1import { render } from '@testing-library/react'; 2import Home from 'pages'; 3 4describe('Home component', () => { 5 it('render Home component', () => { 6 render(<Home />); 7 }); 8}); 9
現状のjest.config.jsです(以下の記事を参考にしました)
https://zenn.dev/uttk/scraps/475390e9d5b820
javascript
1const fs = require("fs"); 2const tsconfig = require("./tsconfig.json"); 3 4// tsconfigから baseUrl を取得する 5const baseUrl = tsconfig.compilerOptions.baseUrl; 6 7// フォルダー名一覧を取得する 8const folders = fs.readdirSync(baseUrl, { withFileTypes: true }).flatMap((ele) => { 9 return ele.isDirectory() ? [ele.name] : []; 10}); 11 12/** 13 * @type {import("@jest/types").Config.InitialOptions} 14 */ 15const config = { 16// tsconfig.json の baseUrl によるエイリアスを有効にする 17 moduleNameMapper: folders.reduce((mapper, folderName) => { 18 return { ...mapper, [`^${folderName}(.*)$`]: `<rootDir>/src/${folderName}$1` }; 19 }, {}), 20 21 testEnvironment: 'jsdom', 22 23 testMatch: ['**/*.test.js', '**/*.test.ts', '**/*.test.tsx'], 24 25 // @testing-library/react を使うためセットアップスクリプト( 後述 ) 26 setupFilesAfterEnv: ['<rootDir>/src/test/utils/setup.ts'], 27 28 // 除外するフォルダーを指定する 29 testPathIgnorePatterns: [ 30 '<rootDir>/src/test/utils/', // セットアップが入っているフォルダーは除外する 31 '<rootDir>/node_modules/', 32 '<rootDir>/.next/', 33 ], 34 35 transformIgnorePatterns: [`node_modules/(?!nanoid/)`], 36 37 transform: { 38 '.+\\.(t|j)sx?$': [ 39 '@swc/jest', 40 { 41 sourceMaps: true, // エラーを見やすくする( 有効じゃないと内容がズレて表示されます ) 42 43 module: { 44 type: 'commonjs', // 出力するファイルをcommonjsとする 45 }, 46 47 jsc: { 48 parser: { 49 syntax: 'typescript', // ソースコードをtypescriptとしてパースする 50 tsx: true, // jsx記法を許可する 51 }, 52 53 transform: { 54 react: { 55 // 必須。省略すると "ReferenceError: React is not defined" が発生します 56 runtime: 'automatic', 57 }, 58 }, 59 }, 60 }, 61 ], 62 }, 63} 64 65module.exports = config
補足情報(FW/ツールのバージョンなど)
バージョン等(package.jsonです)
json
1{ 2 "name": "next13-jest-swc", 3 "version": "0.1.0", 4 "private": true, 5 "scripts": { 6 "dev": "next dev", 7 "build": "next build", 8 "start": "next start", 9 "lint": "next lint", 10 "test": "jest" 11 }, 12 "dependencies": { 13 "@types/node": "20.2.3", 14 "@types/react": "18.2.6", 15 "@types/react-dom": "18.2.4", 16 "autoprefixer": "10.4.14", 17 "eslint": "8.41.0", 18 "eslint-config-next": "13.4.3", 19 "nanoid": "^4.0.2", 20 "next": "13.4.3", 21 "postcss": "8.4.23", 22 "react": "18.2.0", 23 "react-dom": "18.2.0", 24 "tailwindcss": "3.3.2", 25 "typescript": "5.0.4" 26 }, 27 "devDependencies": { 28 "@swc/core": "^1.3.59", 29 "@swc/jest": "^0.2.26", 30 "@testing-library/jest-dom": "^5.16.5", 31 "@testing-library/react": "^14.0.0", 32 "@testing-library/user-event": "^14.4.3", 33 "@types/jest": "^29.5.1", 34 "@types/testing-library__jest-dom": "^5.14.5", 35 "@types/testing-library__user-event": "^4.2.0", 36 "jest": "^29.5.0", 37 "jest-environment-jsdom": "^29.5.0", 38 "ts-jest": "^29.1.0" 39 } 40}
回答2件
あなたの回答
tips
プレビュー