-1

I raised an issue https://github.com/facebook/jest/issues/11504 against the jest project, which I think is responsible for maintaining babel-jest. Transpilation totally fails after adding apparently harmless and error-free code.

However, there are a lot of layers to the transpilation of a Typescript Next project, so I am unsure if this is the correct place to file the issue and matches with the likely source of the failure.

Does this issue seem like it matches with the babel-jest project or should I file it somewhere else?

BUG

I found in a complex Next Typescript project that adding a handful of lines in one file was enough to break babel-jest transpilation and create runtime errors in a completely different file.

In commit 04c4c7b, after checking out the clean project and running yarn I am able to get passing tests with yarn run test. The passing source tree is at https://github.com/cefn/jest-transpile-failure-repro/tree/04c4c7b7013e8b88c25d3ab2a7d4a33ccd3fb191

However, after adding the handful of lines which you can see in commit 25703fc the babel-jest transpiler seems to effectively break making tests impossible to run, and a totally unrelated file starts to get runtime errors during the test which make no sense like...

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)

Note, commit 25703fc compiles with tsc and runs perfectly well and seems functional.

This error makes no sense because SCORERS is a const defined in the module closure immediately above the function definition.

It is also a completely unrelated file to those changed in commit 25703fc, suggesting that something about the language constructs in commit 25703fc has pushed the transpiler into an errored state.

Finally it's a runtime error in a file which is already used and runs fine in the production case, so I don't believe there are actually any typescript errors in it.

Should I pursue this with babel, or with nextjs, or is it correctly a babel-jest problem, or some other project?

Anyone know a workaround for e.g. using a totally different babel system to transpile Typescript nextjs code in case I can prove that babel-jest is at fault here?

By way of 'proof' you can see the code compiled and running in production despite the babel-jest compiler error at https://cefn.com/cv

The image below shows the actual lines changed which pushed the transpiler into error as a screenshot from the github diff of the commit...

enter image description here

cefn
  • 2,895
  • 19
  • 28

1 Answers1

1

You are introducing a dependency cycle in your code by adding the new

import { INITIAL_APPSTATE } from '../../logic'

import in Button.tsx. You can see it in the stack trace of the error you posted

  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)

Your test loads util.tsx which imports components/index.ts and so on until it loads Buttons.tsx which due to your patch now imports logic.ts which then again imports util.tsx, but since your code started by importing util.tsx, it hasn't finished executing yet, because it is still loading all of its dependencies. When Button.tsx tries to import logic.ts, it calls sortEntries, but that function relies on util.tsx having executed properly, and it hasn't had time to do that yet.

You need to reorganize your code to not have this cycle in the dependencies. It seems very surprising that a file called util would import an components, so moving downloadPdf into its own downloadPdf.ts so that util.ts no longer has to do import { Resume } from './components' would be the ideal fix.

loganfsmyth
  • 156,129
  • 30
  • 331
  • 251
  • That is very helpful, thanks! I have been using madge to try and eliminate circularity as per https://github.com/cefn/cvnext/blob/main/package.json#L12 Running it as follows reveals no circularity `npx madge --circular test/util.test.ts` but I should have eyeballed the import sequences too. – cefn Jun 03 '21 at 18:01
  • Update I found that madge WOULD detect the circularity if the top level tsconfig was specified as an argument like `npx madge --circular --ts-config tsconfig.json --extensions ts,tsx ./`. Unfortunately `npx madge --circular --ts-config tsconfig.jest.json --extensions ts,tsx ./` (pointing to https://github.com/cefn/cvnext/blob/dd46352b6f36ff32ebc5dda9edc2067d2909d816/tsconfig.jest.json ) or with the `--ts-config` argument omitted as I was previously running it DOESN'T find this particular circularity. – cefn Jun 03 '21 at 20:37