👻
Create React Appで作成したプロジェクトをJestでテストしようとするとGraphQLのファイルが読み込めない
モックサーバーとして建てたGraphQLサーバーを利用して useQuery
を使ったカスタムフックのテストしようと思い、
GraphQLの変換処理を設定してテストを起動したところ、エラーになってしまった。
package.json
{
...,
"jest": {
"transform": {
"\\.(graphql|gql)$": "jest-transform-graphql"
}
}
}
$ npm run test
... (中略)
Invariant Violation: Argument of foobar.graphql passed to parser was not a valid GraphQL DocumentNode. You may need to use 'graphql-tag' or another method to convert your operation into a document
ファイルのインポートはできているようだが、インポートされた内容が DocumentNode
ではなくファイル名の文字列( foobar.graphql
)になってしまっている。
react-app-rewired を使ってJestにどのような設定が渡されているか確認したところ、下記の通りだった。
config-overrides.js
module.exports = {
jest: function override(config) {
console.log(config);
process.abort();
return config;
}
};
$ npm run test
{
...,
transform: {
'^.+\\.(js|jsx|mjs|cjs|ts|tsx)$': '/path/to/project/node_modules/react-app-rewired/scripts/utils/babelTransform.js',
'^.+\\.css$': '/path/to/project/node_modules/react-scripts/config/jest/cssTransform.js',
'^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)': '/path/to/project/node_modules/react-scripts/config/jest/fileTransform.js',
'\\.(graphql|gql)$': 'jest-transform-graphql'
},
...
}
これを見ると、 .graphql
ファイルが transform の3行目にある fileTransform.js
のファイルパターンに合致してしまっているため、
jest-transform-graphql
に到達できていないことがわかった。
この transform は react-scripts
内に定義されている。
対策の方法が分からなかったので、 react-app-rewired
で fileTransform.js
の例外パターンを追加することにした。
const FILE_TRANSFER_KEY = "js|jsx|mjs|cjs|ts|tsx|css|json";
module.exports = {
jest: function override(config) {
Object.keys(config.transform).forEach(key => {
const replacedKey = key.replace(FILE_TRANSFER_KEY, `${FILE_TRANSFER_KEY}|graphql|gql`);
if (key !== replacedKey) {
config.transform[replacedKey] = config.transform[key];
delete config.transform[key];
}
});
return config;
}
};
これで .graphql
ファイルが正常にロードされるようになった。
Discussion