[英]Jest encountered an unexpected token with Next.js and TypeScript when using createUserWithEmailAndPassword in firebase/auth
我正在尝试在我的 Next.js 项目(使用 TypeScript)上设置 firebase 身份验证,我相信我遇到了一些与使用 firebase 相关的配置问题,这些问题导致我的 Jest 测试失败。
以下是相关的配置文件:
开玩笑.config.js:
const nextJest = require("next/jest");
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: "./",
});
// Add any custom config to be passed to Jest
const customJestConfig = {
setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
moduleNameMapper: {
// Handle module aliases (this will be automatically configured for you soon)
"^@/components/(.*)$": "<rootDir>/components/$1",
"^@/pages/(.*)$": "<rootDir>/pages/$1",
},
testEnvironment: "jest-environment-jsdom",
};
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig);
tsconfig.json:
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "firebase.js"],
"exclude": ["node_modules"]
}
package.json:
{
"name": "video-annotator",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"test": "jest --watch",
"test:ci": "jest --ci"
},
"dependencies": {
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@mui/material": "^5.11.3",
"@next/font": "13.1.1",
"@types/node": "18.11.18",
"@types/react": "18.0.26",
"@types/react-dom": "18.0.10",
"eslint-config-next": "13.1.1",
"firebase": "^9.15.0",
"next": "13.1.1",
"react": "^18.2.0",
"react-dom": "18.2.0",
"react-intl": "^6.2.5",
"typescript": "4.9.4"
},
"devDependencies": {
"@jest/globals": "^29.3.1",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"eslint": "^8.31.0",
"eslint-plugin-formatjs": "^4.3.9",
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.3.1",
"next-router-mock": "^0.9.1-beta.0",
"ts-jest": "^29.0.5"
}
}
而且,在我下面的一些尝试解决方案中,您可能还需要查看:
tsconfig.jest.json:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"jsx": "react"
}
}
我注意到我的测试套件在我添加时开始失败
const userInfo = await createUserWithEmailAndPassword(
auth,
email,
password
);
到 ln 附近pages/create-account/index.tsx中的代码库。 94.
显示的错误很奇怪。 测试套件失败,因为“Jest 遇到了意外的标记”。
此外,在测试 output 的详细信息部分,我看到:
细节:
.../video-annotator/node_modules/firebase/auth/dist/esm/index.esm.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export * from '@firebase/auth';
^^^^^^
SyntaxError: Unexpected token 'export'
10 | import { Paper } from "@mui/material";
11 | import { Button } from "@mui/material";
> 12 | import { AuthContext } from "../contexts/authContext";
| ^
13 | import { useContext } from "react";
我相信import { AuthContext } from "../contexts/authContext";
语句,因为如果我将该行代码与其上面的代码交换,我会看到:
语法错误:意外的令牌“导出”
10 | import { Paper } from "@mui/material";
11 | import { AuthContext } from "../contexts/authContext";
> 12 | import { Button } from "@mui/material";
| ^
鉴于我确信 Button 和我的 AuthContext 都不是问题,并且注意到测试中没有错误,直到我在createUserWithEmailAndPassword
调用中回复:
const userInfo = await createUserWithEmailAndPassword(
auth,
email,
password
);,
, 我必须得出结论
我也探索了错误的“Jest encountered an unexpected token”部分:
我尝试将 "^firebase/auth$": "/node_modules/firebase/auth/dist/esm/index.esm.js", 添加到 moduleNameMapper 中的 jest.config.js 并重新运行测试。 没变。
我在设置期间使用了 ts-jest 和 Rust 编译器而不是 Babel,所以我认为提供的指向https://jestjs.io/docs/getting-started#using-typescript的链接不适用于我的案例。
我做到了,但是尝试将我原来的 jest.config.js 从上面看到的替换为:
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
};
这给了我一个新的“Jest encountered an unexpected token”错误变体:
细节:
/Users/mf/Desktop/video-annotator/__tests__/login.test.tsx:39
return (0, react_1.render)(<react_intl_1.IntlProvider locale={locale} messages={messages}>
^
SyntaxError: Unexpected token '<'
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1449:14).
此错误又类似于此处报告的问题,他们建议将配置文件拆分为多个部分,以防止从“反应”自动更改为“保留”:
这个问题是因为jsx没有被转换,jest不知道怎么解析。 修复非常简单,在您的 tsconfig.json 中,您需要将“jsx”键设置为“反应”而不是“保留”。 不幸的是,next 的构建期望它是“保留”并自动将其更改回 tsconfig.json:( 我解决这个问题的方法是创建一个单独的 tsconfig.jest.json。以下是步骤:
使用以下内容创建文件 tsconfig.jest.json:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"jsx": "react"
}
}
... 2) 配置 jest.config.js 使用新的 tsconfig.jest.json。
我也试过这个,但它没有解决我的问题。
我也在相关的 SO 帖子中尝试了一些其他建议,但在我的特定情况下,它们似乎都没有帮助。
我主要是在寻找下一步尝试的指导,除非解决方案或错误立即跳出某人。 我认为我尝试了所有这些不同的解决方案,把它弄得一团糟。
我应该改用 Babel 吗? 与 ts-jest 相比,Babel 似乎有更大的社区和历史。
我的回购协议(以及我目前所在的创建帐户分支)可以在这里找到。 您可以通过克隆存储库、检查创建帐户分支、运行npm install
,然后运行npm test
,在本地重现错误。 您可能还需要创建一个“./key.ts”文件并填充它:
export const secrets = {
apiKey: "TODO",
authDomain: "TODO",
projectId: "TODO",
storageBucket: "TODO",
messagingSenderId: "TODO",
appId: "TODO",
measurementId: "TODO",
};
另一方面,身份验证确实是该项目的第一个主要功能,因此我认为遵循 repo 中的逻辑可能会相对简单。 不用本地下载。
非常感谢您!
我对 NexTJS 的工作不多,所以如果我遗漏了什么请原谅我。
由于这个答案,我可以通过添加以下内容来运行测试:
module.exports = async () => ({
...(await createJestConfig(customJestConfig)()),
transformIgnorePatterns: [
'/node_modules/(?!(firebase|@firebase)/)',
]
});
然后完整的jest.config.js
文件是这样的:
const nextJest = require("next/jest");
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: "./",
});
// Add any custom config to be passed to Jest
const customJestConfig = {
setupFilesAfterEnv: ["<rootDir>/jest.setup.js"],
moduleNameMapper: {
// Handle module aliases (this will be automatically configured for you soon)
"^@/components/(.*)$": "<rootDir>/components/$1",
"^@/pages/(.*)$": "<rootDir>/pages/$1",
},
testEnvironment: "jest-environment-jsdom",
};
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = async () => ({
...(await createJestConfig(customJestConfig)()),
transformIgnorePatterns: [
'/node_modules/(?!(firebase|@firebase)/)',
]
})
我知道测试都是绿色的:)
Test Suites: 2 passed, 2 total
Tests: 13 passed, 13 total
Snapshots: 0 total
Time: 6.104 s
Ran all test suites.
奇怪的是,他们文档中的示例显示我们可以在您的customJestConfig
object 中添加相同的模式。
旁注:请使您的 firebase 应用程序的机密无效,并确保将它们从您的存储库中删除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.