razzle icon indicating copy to clipboard operation
razzle copied to clipboard

Upgrading to Razzle 4 breaks over half our tests

Open heath-freenome opened this issue 3 years ago • 16 comments

🐛 Bug report

Current Behavior

Upgrading from razzle 3 to razzle 4 and running tests causes lots of the following errors:

 ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    <path>/src/__tests__/<file>.test.jsx:20
    import React from "react";
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

Expected behavior

Upgrading to razzle 4 allows all my tests to keep working

Reproducible example

Working repo on razzle 3

Broken branch on razzle 4

Suggested solution(s)

Pick up the env.test.plugin from the .babelrc file since they seem to be dropped in the razzle 4 test world

Additional context

We have customized the jest config as follows:

  modifyJestConfig({ jestConfig }) {
    const customJestConfig = {
      automock: false,
      setupFiles: ['<rootDir>/src/__tests__/__setup__/initJest.js'],
      setupFilesAfterEnv: ['<rootDir>/node_modules/jest-enzyme/lib/index.js'],
      modulePathIgnorePatterns: ['<rootDir>[/\\\\](build|docs|node_modules|scripts)[/\\\\]'],
      testEnvironment: 'jest-environment-jsdom-global',
      transform: {
        'src/client.jsx': '<rootDir>/src/__tests__/__setup__/hotModulesPreprocessor.js',
        'src/index.jsx': '<rootDir>/src/__tests__/__setup__/hotModulesPreprocessor.js',
        '\\.[jt]sx?$': 'babel-jest',
      },
      // Add react-intl libs to be transpiled per: https://formatjs.io/docs/react-intl#jest
      transformIgnorePatterns: ['/node_modules/(?!react-intl|intl-messageformat|intl-messageformat-parser).+\\.js$'],
      coverageDirectory: '<rootDir>/coverage/',
      collectCoverage: true,
      coveragePathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/src/__tests__'],
    };
    const newJestConfig = { ...jestConfig, ...customJestConfig };
    // Uncomment this to debug the new jest config
    // console.dir(newJestConfig, { depth: null });
    return newJestConfig;
  },

Also our .babelrc file has a special env section for testing, which maybe isn't being picked up anymore?

{
  "presets": [
    [
      "razzle/babel",
      {
        "preset-env": {
          "modules": false, // don't convert modules into CommonJS
          "useBuiltIns": "usage", // use polyfill when needed
          "corejs": 3
        },
        "class-properties": {
          "loose": false
        }
      }
    ],
    "@babel/preset-react"  // Transpile React components to JavaScript
  ],
  "plugins": [
    "@babel/plugin-proposal-export-default-from",
    "@babel/plugin-syntax-dynamic-import",
    "@babel/plugin-syntax-import-meta",
    "@babel/plugin-proposal-json-strings",
    ["@babel/plugin-proposal-decorators", { "legacy": true }],
    "@babel/plugin-proposal-export-namespace-from",
    "@babel/plugin-proposal-throw-expressions",
    "@loadable/babel-plugin"
  ],
  "env": {
    "test": {
      "plugins": [
        "dynamic-import-node",
        "@babel/plugin-transform-react-jsx",
        "@babel/plugin-transform-modules-commonjs",
      ]
    }
  }
}

Your environment

Software Version(s)
Razzle 4
Razzle Plugins "babel-preset-razzle": "^4.0.5"
Node 14.16
Browser n/a
npm/Yarn 6.14.11
Operating System macOS
TypeScript no
React 16.x

heath-freenome avatar Jul 14 '21 21:07 heath-freenome

Can you try not overriding transform in jest config.

fivethreeo avatar Jul 14 '21 22:07 fivethreeo

Can you try not overriding transform in jest config.

That did not make a difference :(

I believe that the test environment in the .babelrc is somehow lost when processing .jsx files. For some reason it works fine for .js files.

heath-freenome avatar Jul 14 '21 22:07 heath-freenome

Update: With razzle@3, when I remove the "@babel/plugin-transform-react-jsx" line from the test environment in my .babelrc file I get the exact same errors as I do with razzle@4 with it in there. So somehow that transformer is lost.

heath-freenome avatar Jul 14 '21 23:07 heath-freenome

I'm working on a reproducible repo... should have one ready by tomorrow... If what I shared above inspires you, feel free to provide a one-off solution

heath-freenome avatar Jul 14 '21 23:07 heath-freenome

@fivethreeo I've added a reproducible test case

heath-freenome avatar Jul 15 '21 18:07 heath-freenome

@fivethreeo Also, I'm wondering if you upgraded to jest@27 whether this is still a problem? I made a branch where I explicitly call jest@27 to run my tests on top of razzle 4 and they work. Actually, calling jest directly with the stock jest from razzle@4 also works... i.e.

"test": "jest --config jest.config.json --runInBand"

heath-freenome avatar Jul 15 '21 21:07 heath-freenome

I think jest 27 changed the test runner. So razzle tests break with jest 27 since you can’t mix promises and async in tests.

fivethreeo avatar Jul 15 '21 22:07 fivethreeo

I don't know what to say about that. You can just pay attention to the master and razzle-4-tests-break branches of the repo I linked above if you are willing to fix the issue

heath-freenome avatar Jul 15 '21 22:07 heath-freenome

I upgraded to 26 for razzle 4, 27 would be a breaking change since it is a major version upgrade. So can’t upgrade until razzle 5. But could fast track that and move planned features to razzle 6.

fivethreeo avatar Jul 15 '21 22:07 fivethreeo

But then I need help fixing razzle tests for 27.

fivethreeo avatar Jul 15 '21 22:07 fivethreeo

I'm not entirely sure 26 => 27 would fix it anyway... I wonder if there is anything that jumps out at you related to the losing of the env.tests.plugin set in the razzle world?

heath-freenome avatar Jul 15 '21 22:07 heath-freenome

Nothing jumps out at me, but unable to test now as I am on vacation until June 26.

fivethreeo avatar Jul 15 '21 23:07 fivethreeo

Enjoy your vacation

heath-freenome avatar Jul 15 '21 23:07 heath-freenome

Ok, so I'm wondering if it has something with the razzle-babel-preset changes in 4? I set the following in the preset config and the problems in the tests went away, although a few new test problems suddenly occurred:

  "env": {
    "test": {
      "presets": [
        [
          "razzle/babel",
          {
            "preset-react": {
              "runtime": "automatic" // Allow the tests to run with razzle babel preset
            }
          }
        ]
      ],

heath-freenome avatar Jul 16 '21 18:07 heath-freenome

Try setting modules to false in preset env.

Sendt fra min iPhone

  1. jul. 2021 kl. 8:24 pm skrev Heath C @.***>:

 Ok, so I'm wondering if it has something with the preset?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

fivethreeo avatar Jul 16 '21 22:07 fivethreeo

Whoops, I missed this since I gave up and switched back to calling jest directly with a jest.config.json... Did you mean:

"env": {
    "test": {
      "presets": [
        [
          "razzle/babel",
          {
            "preset-react": {
              "modules": false,
              "runtime": "automatic" // Allow the tests to run with razzle babel preset
            }
          }
        ]
      ],

heath-freenome avatar Apr 01 '22 06:04 heath-freenome