繁体   English   中英

在 firebase/auth 中使用 createUserWithEmailAndPassword 时,Jest 遇到了 Next.js 和 TypeScript 的意外令牌

[英]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
        );,

, 我必须得出结论

  1. 我以某种方式滥用了上述声明,
  2. firebase 导入发生了其他事情,或者
  3. 我以某种方式错误配置了 jest,导致它不能很好地与 firebase 配合使用。

我也探索了错误的“Jest encountered an unexpected token”部分:

  1. 我尝试将 "^firebase/auth$": "/node_modules/firebase/auth/dist/esm/index.esm.js", 添加到 moduleNameMapper 中的 jest.config.js 并重新运行测试。 没变。

  2. 我在设置期间使用了 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM