create-react-app
create-react-app copied to clipboard
[CRA v5] Jest + React-markdown = Must use import to load ES Module
Describe the bug
Running a CRA test rendering react-markdown
leads to an error message "Must use import to load ES Module:"
A (somewhat) related issue in https://github.com/remarkjs/react-markdown/issues/635 seems to redirect to https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c, which in turn states "Create React App doesn't yet fully support ESM. I would recommend opening an issue on their repo with the problem you have encountered. One known issue is #10933."
/cc @ChristianMurphy
Did you try recovering your dependencies?
Yes
Which terms did you search for in User Guide?
esm
Environment
Windows
Steps to reproduce
Full repro case is available at
- Clone https://github.com/nulltoken/repro-react-markdown-cra-esm
- run
yarn test
Output of yarn test
can be reviewed at https://github.com/nulltoken/repro-react-markdown-cra-esm/runs/4841320780?check_suite_focus=true
Expected behavior
I'd very much like the test not to fail because of an import issue :-/
Actual behavior
Reproducible demo
(Paste the link to an example project and exact instructions to reproduce the issue.)
Not sure if this helps but I managed to get my react-markdown tests to run with CRA by modifying the test command
react-scripts test --maxWorkers=2 --transformIgnorePatterns \"node_modules/(?!react-markdown)/\" --env=jsdom
@KieranDotCo Thanks for the hand. Unfortunately, this doesn't seem to do the trick with CRA v5. The same error occurs.
Try the solution suggested here: https://github.com/remarkjs/react-markdown/issues/635#issuecomment-956158474
@yuchen-w Thanks but it looks like those solutions target CRA 4.x (and I'd really like to avoid the mocking approach)
@nulltoken I am using this solution on CRA v5.
// package.json
"jest": {
"transformIgnorePatterns": [
"(?!(/node_modules/(react-markdown|vfile|vfile-message|unist-.*|unified|bail|is-plain-obj|trough|remark-.*|mdast-util-.*|micromark.*|decode-named-character-reference|character-entities|property-information|hast-util-whitespace|space-separated-tokens|comma-separated-tokens|pretty-bytes)/))(/node_modules/.+.(js|jsx|mjs|cjs|ts|tsx)$)",
"^.+.module.(css|sass|scss)$"
]
}
@esetnik had to slightly modify the pattern for me.
This worked for me on a MacBook:
"jest": {
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\](?!(react-markdown|vfile|vfile-message|markdown-table|unist-.*|unified|bail|is-plain-obj|trough|remark-.*|mdast-util-.*|escape-string-regexp|micromark.*|decode-named-character-reference|character-entities|property-information|hast-util-whitespace|space-separated-tokens|comma-separated-tokens|pretty-bytes|ccount)).+\\.(js|jsx|mjs|cjs|ts|tsx)$"
]
},
@jcgentr and @esetnik answers didn't work for me. However, they pointed me in the correct direction. Especially because those solutions work for projects created with create-react-app
. I needed to edit the regex pattern to the following.
"jest": {
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\](?!(react-markdown|vfile|vfile-message|markdown-table|unist-.*|unified|bail|is-plain-obj|trough|remark-.*|rehype-.*|html-void-elements|hast-util-.*|zwitch|hast-to-hyperscript|hastscript|web-namespaces|mdast-util-.*|escape-string-regexp|micromark.*|decode-named-character-reference|character-entities|property-information|hast-util-whitespace|space-separated-tokens|comma-separated-tokens|pretty-bytes|ccount|mdast-util-gfm|gemoji)).+\\.(js|jsx|mjs|cjs|ts|tsx)$"
]
}
Basically, I just added these patterns:
-
rehype-*
-
hast-util-.*
-
mdast-util-gfm
-
web-namespaces
-
zwitch
-
hast-to-hyperscript
-
html-void-elements
-
gemoji
If running the tests still fails for you because Jest encountered an unexpected token
, just try to add the folder, where the error occurred, from the node_module
folder. Unfortunately, sometimes the error message does not directly point to the correct package, which should be transformed. For example, I always got an error message which pointed to the mdast-util-gfm-autolink-literal
package, however, the error actually happened because mdast-util-gfm
was not transformed. Just try to google the error. :)
@martenmatrix This worked for me, thank you so much!
I used Option 1 in Recommended solution by react-markdown Which is mocking the modules. Probably the easiest way.
Guys, you can see a lot of likes under the previous entries, and in you, as well as me, the tests still don't work. Pay attention ob a babel, in my case, it helped me:
I followed this: https://babeljs.io/docs/en/configuration#whats-your-use-case
1. Converted my .babelrc to babel.config.json
2. In jest config added this: transformIgnorePatterns: [...],
This solved my problem.
@Slisarenko Great you figured it out. Do you mind sharing the relevant parts of your babel.config.json
and jest.config.cjs
?
@fbruckhoff No problem, here: jest.config.cjs:
const esModules = [
'react-markdown',
'vfile-message',
'markdown-table',
'unist-.*',
'unified',
'bail',
'is-plain-obj',
'trough',
'remark-.*',
'rehype-.*',
'html-void-elements',
'hast-util-.*',
'zwitch',
'hast-to-hyperscript',
'hastscript',
'web-namespaces',
'mdast-util-.*',
'escape-string-regexp',
'micromark.*',
'decode-named-character-reference',
'character-entities',
'property-information',
'hast-util-whitespace',
'space-separated-tokens',
'comma-separated-tokens',
'pretty-bytes',
'ccount',
'mdast-util-gfm',
'gemoji',
/** react-markdown 8.0.3 */
'trim-lines',
'jest-runtime',
'vfile',
/** react-markdown 7.2.1 */
'longest-streak',
].join('|');
module.exports = {
clearMocks: true,
collectCoverage: true,
collectCoverageFrom: ['src/**/*.{js,jsx,ts,tsx}', '!src/index.tsx'],
coverageDirectory: 'coverage',
coveragePathIgnorePatterns: [
'/node_modules/',
],
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|pdf)$': '<rootDir>/__mocks__/fileMock.js',
'\\.(css|less)$': 'identity-obj-proxy',
},
transformIgnorePatterns: [
`[/\\\\]node_modules[/\\\\](?!${esModules}).+\\.(js|jsx|mjs|cjs|ts|tsx)$`,
],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
globalSetup: '<rootDir>/global-setup.js',
};
babel.config.js:
module.exports = {
presets: [
'@babel/preset-env',
'@babel/preset-react',
],
};