はじめに
TypeScriptとNuxt.jsで作成したWebアプリケーションをJestでテストしようとしたらハマったので、その備忘録として残します。
環境
- Node.js: 10.22.0
- nuxt: 2.14.4
- nuxt-property-decorator: 2.7.2
- jest": 26.4.2
状況
ビルド自体は通っていて、目視での動作確認は取れている状態でしたが、Jestを通すと以下のようなエラーが発生しました。
● Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
jest.config.jsの設定ミスかと思い色々試してみましたが、治らず
その時の jest.config.jsは以下の通りです。
module.exports = {
globals: {
'ts-jest': {
tsConfig: 'tsconfig.json',
},
},
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/$1',
'^~/(.*)$': '<rootDir>/$1',
},
moduleFileExtensions: ['js', 'vue', 'json', 'ts'],
testMatch: ['**/__tests__/**/*.+(ts|js)', '**/?*?(.)+(spec|test).+(ts|js)'],
transform: {
'^.+\\.js$': 'babel-jest',
'^.+\\.(vue)$': 'vue-jest',
'^.+\\.tsx?$': 'ts-jest',
},
};
改めてエラーのスタックトレースをみてみると
Details:
SyntaxError: Unexpected token ] in JSON at position 608
at JSON.parse (<anonymous>)
at parse (node_modules/tsconfig/src/tsconfig.ts:195:15)
at readFileSync (node_modules/tsconfig/src/tsconfig.ts:181:10)
at Object.loadSync (node_modules/tsconfig/src/tsconfig.ts:151:18)
at find (node_modules/vue-jest/lib/load-typescript-config.js:33:39)
at loadTypescriptConfig (node_modules/vue-jest/lib/load-typescript-config.js:73:26)
at compileTypescript (node_modules/vue-jest/lib/compilers/typescript-compiler.js:9:20)
at processScript (node_modules/vue-jest/lib/process.js:23:12)
at Object.module.exports [as process] (node_modules/vue-jest/lib/process.js:42:18)
at ScriptTransformer.transformSource (node_modules/@jest/transform/build/ScriptTransformer.js:463:35)
どうやら tsconfig.ts周りが怪しそうでした。
tsconfig.tsが何者かはわかりませんが, JSON.parseでエラーが出ているのでtsconfig.jsonが怪しそう
以下がエラー発生時のtscofig.jsonです。
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Node",
"lib": [
"ESNext",
"ESNext.AsyncIterable",
"DOM"
],
"esModuleInterop": true,
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"sourceMap": true,
"strict": true,
"experimentalDecorators": true,
"noEmit": true,
"baseUrl": ".",
"paths": {
"~/*": [
"./*"
],
"@/*": [
"./*"
]
},
"types": [
"@types/node",
"@nuxt/types",
"@types/jest",
]
},
"exclude": [
"node_modules",
".nuxt",
"dist"
]
}
よくよく見ると間違いに気づきます
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Node",
"lib": [
"ESNext",
"ESNext.AsyncIterable",
"DOM"
],
"esModuleInterop": true,
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"sourceMap": true,
"strict": true,
"experimentalDecorators": true,
"noEmit": true,
"baseUrl": ".",
"paths": {
"~/*": [
"./*"
],
"@/*": [
"./*"
]
},
"types": [
"@types/node",
"@nuxt/types",
"@types/jest", <- ここのコンマが不要でした...
]
},
"exclude": [
"node_modules",
".nuxt",
"dist"
]
}
jsonは配列やオブジェクトの終点に ,
は不要らしいです。。。このエラーで初めて知りました
コンマを取り除いただけで動いたときはこの4時間なんだったんだと思いました
終わりに
jsonの正しい書き方を知らなかったのもそうですが、なによりスタックトレースをもう少ししっかりと読む癖をつけようと心底思いました