问题描述
我针对 jest 项目提出了一个问题 https://github.com/facebook/jest/issues/11504,我认为该项目负责维护 babel-jest。添加明显无害且无错误的代码后,转译完全失败。
但是,Typescript Next 项目的转译有很多层次,所以我不确定这是否是提交问题的正确位置,并与可能的失败来源相匹配。
这个问题是否与 babel-jest 项目匹配,还是我应该将其归档到其他地方?
BUG
我在一个复杂的 Next Typescript 项目中发现,在一个文件中添加几行代码足以破坏 babel-jest 转译并在一个完全不同的文件中创建运行时错误。
在提交 04c4c7b 中,在检查干净项目并运行 yarn
后,我能够通过 yarn run test
获得通过测试。传递的源代码树位于 https://github.com/cefn/jest-transpile-failure-repro/tree/04c4c7b7013e8b88c25d3ab2a7d4a33ccd3fb191
然而,在添加了几行你可以看到 in commit 25703fc 之后,babel-jest 转译器似乎有效地打破了使测试无法运行的问题,并且一个完全不相关的文件在测试期间开始出现运行时错误,这使得没意思……
ReferenceError: Cannot access 'scoreRS' before initialization
47 | sortedEntries.sort((a: Immutable<Entry>,b: Immutable<Entry>) => {
48 | for (const scoreName of scorePriority) {
> 49 | const scorer = scoreRS[scoreName]
| ^
50 | const diff = scorer(b) - scorer(a)
51 | if (diff !== 0) {
52 | return diff
at sort (src/util.tsx:49:22)
at Array.sort (<anonymous>)
at sortEntries (src/util.tsx:47:17)
at Object.<anonymous> (src/logic.ts:10:20)
at Object.<anonymous> (src/components/controls/Buttons.tsx:6:1)
at Object.<anonymous> (src/components/Controls.tsx:8:1)
at Object.<anonymous> (src/components/index.ts:1:1)
at Object.<anonymous> (src/util.tsx:6:1)
at Object.<anonymous> (test/util.test.ts:3:1)
请注意,commit 25703fc 使用 tsc
进行编译并且运行良好并且看起来很正常。
这个错误没有意义,因为 scoreRS 是在函数定义正上方的模块闭包中定义的常量。
这也是一个与提交 25703fc 中更改的文件完全无关的文件,这表明提交 25703fc 中的语言结构的某些内容已将转译器推入错误状态。
最后,这是一个文件中的运行时错误,该文件已被使用并且在生产案例中运行良好,所以我不相信其中实际上存在任何打字稿错误。
我应该用 babel 还是 nextjs 来解决这个问题,或者它是 babel-jest 问题还是其他项目?
任何人都知道一种解决方法,例如使用完全不同的 babel 系统来转译 Typescript nextjs 代码,以防我能证明 babel-jest 有问题?
通过“证明”,您可以看到代码在生产环境中编译并运行,尽管 https://cefn.com/cv 处存在 babel-jest 编译器错误
下图显示了实际更改的行,将转译器推入错误,作为提交的 github diff 的屏幕截图...
解决方法
您通过添加新的代码在代码中引入了依赖循环
import { INITIAL_APPSTATE } from '../../logic'
在 Button.tsx
中导入。您可以在您发布的错误的堆栈跟踪中看到它
at sort (src/util.tsx:49:22)
at Array.sort (<anonymous>)
at sortEntries (src/util.tsx:47:17)
at Object.<anonymous> (src/logic.ts:10:20)
at Object.<anonymous> (src/components/controls/Buttons.tsx:6:1)
at Object.<anonymous> (src/components/Controls.tsx:8:1)
at Object.<anonymous> (src/components/index.ts:1:1)
at Object.<anonymous> (src/util.tsx:6:1)
at Object.<anonymous> (test/util.test.ts:3:1)
您的测试加载 util.tsx
,它导入 components/index.ts
,依此类推,直到加载 Buttons.tsx
,由于您的补丁现在导入 logic.ts
,然后再次导入 util.tsx
,但是由于您的代码开始是通过导入 util.tsx
,它尚未完成执行,因为它仍在加载其所有依赖项。当 Button.tsx
尝试导入 logic.ts
时,它会调用 sortEntries
,但该函数依赖于 util.tsx
是否已正确执行,而它还没有时间这样做。
您需要重新组织您的代码,以便在依赖项中不存在此循环。一个名为 util
的文件会导入一个组件,这似乎非常令人惊讶,因此将 downloadPdf
移动到它自己的 downloadPdf.ts
中,这样 util.ts
不再需要执行 import { Resume } from './components'
将是理想的解决方案。