Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

require.context is not a function, snapshots, CRA 2 #4479

Closed
semb09 opened this issue Oct 18, 2018 · 21 comments
Closed

require.context is not a function, snapshots, CRA 2 #4479

semb09 opened this issue Oct 18, 2018 · 21 comments
Labels
addon: storyshots cra Prioritize create-react-app compatibility question / support

Comments

@semb09
Copy link

semb09 commented Oct 18, 2018

If you are reporting a bug or requesting support, start here:

Bug or support request summary

Bug

After updating to Create React App 2.0 I can no longer run snapshot tests with yarn test. I get the following error

  ● Test suite failed to run

    TypeError: require.context is not a function

      1 | import { configure } from '@storybook/react';
      2 |
    > 3 | const req = require.context('../src', true, /\^*.stories.js$/);
        |                     ^
      4 |
      5 | import '../src/styles/main.css';
      6 |

      at Object.context (.storybook/config.js:3:21)
      at configure (node_modules/@storybook/addon-storyshots/dist/frameworks/configure.js:37:11)
      at Object.load (node_modules/@storybook/addon-storyshots/dist/frameworks/react/loader.js:24:26)
      at loadFramework (node_modules/@storybook/addon-storyshots/dist/frameworks/frameworkLoader.js:41:17)
      at testStorySnapshots (node_modules/@storybook/addon-storyshots/dist/api/index.js:44:53)
      at Object.<anonymous> (src/storybook.test.js:6:1)

Steps to reproduce

The code is written exactly as explained in the Quick Star Guide under structural testing https://storybook.js.org/testing/structural-testing/ and was working fine before I upgraded to CRA2. I also updated the versions of Storybook to the latest Beta. And I am also using the new SVG import syntax in CRA2 so I'm not sure which of these things has caused the issue.

Please specify which version of Storybook and optionally any affected addons that you're running

"@storybook/addon-actions": "^4.0.0-alpha.24",
"@storybook/addon-knobs": "^4.0.0-alpha.24",
"@storybook/addon-links": "^4.0.0-alpha.24",
"@storybook/addon-storyshots": "^4.0.0-alpha.24",
"@storybook/addons": "^4.0.0-alpha.24",
"@storybook/react": "^4.0.0-alpha.24",

I read in the Storyshot documentation that you may need to add registerRequireContextHook to your Jest test setup. This was not needed before I made the changes as mentioned above. And as I am using CRA, I only have access to setupTests.js and no way of adding a plugin to the jest babelrc file afaik.

Any help would be really appreciated

@semb09 semb09 changed the title require.context is not a function CRA 2 require.context is not a function, snapshots, CRA 2 Oct 18, 2018
@igor-dv
Copy link
Member

igor-dv commented Oct 18, 2018

require.context is a webpack's feature. It was supported before in Storyshots but caused a lot of maintenance troubles and bugs. So Babel currently is the right way to polyfill this behavior.

I think you can put .babelrc at the root level with something like this:

{
  "env": {
    "test": {
      "plugins": ["babel-plugin-require-context-hook"]
    }
  }
}

@semb09
Copy link
Author

semb09 commented Oct 18, 2018

I tried adding a .babelrc in the .storybook folder with

{
  "plugins": [
	  "require-context-hook"
  ]
}

and then

require('babel-plugin-require-context-hook/register')();

just above

const req = require.context('../src', true, /\^*.stories.js$/);

but I still get the error

@igor-dv
Copy link
Member

igor-dv commented Oct 18, 2018

I am not the biggest expert in CRA =), but I see people are using react-app-rewired for that kind of things.

@semb09
Copy link
Author

semb09 commented Oct 18, 2018

Ok looks like I will have to downgrade to current version of Storybook for time being. react-app-rewired isn't compatible with CRA 2.0 unfortunately. I think a lot of people using require, CRA2 and the next version of Storybook are going to run into this issue.

@igor-dv
Copy link
Member

igor-dv commented Oct 18, 2018

They mention customize-cra in docs.

@semb09
Copy link
Author

semb09 commented Oct 18, 2018

Thanks. I'm not entirely sure why but the following seems to have fixed the issue 🤞 -

  • Added react-app-rewired to app
  • Replaced react-scripts with react-app-rewired in package.json scripts (as mentioned in react-app-rewired docs)
  • Created an empty file named config-overrides.js in route dir (this is required for react-app-rewired to run). I placed no configuration in this file at all.
  • Added custom babelrc file to .storybook directory as above
  • Added import registerRequireContextHook from 'babel-plugin-require-context-hook/register'; registerRequireContextHook(); to setupTests.js in src folder

As I did not actually add any overrides I did not need to use customize-cra. If I remove react-app-rewired the issue re-appears.

@igor-dv igor-dv closed this as completed Oct 19, 2018
@ecsmyth
Copy link

ecsmyth commented Nov 3, 2018

@semb09,
The solution that I'm using doesn't require react-app-rewired, only babel-plugin-require-context-hook.

jest.config.js

...
  setupTestFrameworkScriptFile: '<rootDir>/testing/setupTestFramework.js',
  transform: {
    '^.+\\.jsx?$': '<rootDir>/testing/transform.js'
  },
...

testing/transform.js

const babelOptions = {
  presets: ['@babel/preset-react', '@babel/preset-env'],
  plugins: ['require-context-hook', 'react-hot-loader/babel', '@babel/plugin-proposal-class-properties']
};

module.exports = require('babel-jest').createTransformer(babelOptions);

testing/setupTestFramework.js

import registerRequireContextHook from 'babel-plugin-require-context-hook/register';
import '@babel/polyfill';

registerRequireContextHook();

I do not have a .babelrc or webpack.config.js in my .storybook directory

@MaryGorshkova
Copy link

@ecsmyth thank you for your solution!
I tailored it for my TypeScript needs. my transform.ts looks this way:

const babelOptions = {
    plugins: ['require-context-hook'],
};

module.exports = require('ts-jest').createTransformer({ babelConfig: babelOptions });

@shilman shilman added the cra Prioritize create-react-app compatibility label Nov 22, 2018
@mAAdhaTTah
Copy link

@ecsmyth Are you using create-react-app (CRA2)? It doesn't look like we can override jest.transform in the configuration, nor does use jest.config.js seem to be working either. Were you / are you on the latest version of CRA?

@ecsmyth
Copy link

ecsmyth commented Nov 27, 2018

@mAAdhaTTah, my solution will not work with CRA2 unless you eject or fork react-scripts. Up to you to determine if either of those options is better for you than @semb09's approach.

With CRA2, you can set up the test environment by creating the file src/setupTests.js. This is where you would add the code in the testing/setupTestFramework.js file. However, looking at how the react-scripts package creates the Jest config (<rootDir>/node_modules/react-scripts/scripts/utils/createJestConfig.js) and Babel transformer (<rootDir>/node_modules/react-scripts/config/jest/babelTransform.js), I don't see a way to add the require-context-hook babel plugin.

@kylemh
Copy link
Member

kylemh commented Dec 17, 2018

👋 @semb09 check out #5015

Hopefully going forward it's a simpler experience for other CRAv2 users 💃

@d3bgger
Copy link

d3bgger commented Feb 21, 2019

Hello

I use require.context only in storybook config for loadStories;

I followed these instructions: https://www.npmjs.com/package/@storybook/addon-storyshots#configure-jest-to-work-with-webpacks-requirecontext

I used the macro, as its the only way to make it work in CRAv2.

Now storybook doesn't build in the normal "development" webpack build. (warnings and errors)

WARNING in ./node_modules/babel-plugin-macros/dist/index.js 62:46-53 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted @ ./node_modules/require-context.macro/require-context.macro.js

WARNING in ./node_modules/import-fresh/index.js 28:8-25 Critical dependency: the request of a dependency is an expression @ ./node_modules/cosmiconfig/dist/loaders.js

ERROR in ./node_modules/cosmiconfig/dist/readFile.js Module not found: Error: Can't resolve 'fs' in '...\node_modules\cosmiconfig\dist' @ ./node_modules/cosmiconfig/dist/readFile.js 4:11-24

ERROR in ./node_modules/is-directory/index.js Module not found: Error: Can't resolve 'fs' in '...\node_modules\is-directory' @ ./node_modules/is-directory/index.js 10:9-22

and 4 more Module not found errors...

thanks

@shilman
Copy link
Member

shilman commented Feb 22, 2019

@d3bgger did you look at #5015 ?

@d3bgger
Copy link

d3bgger commented Feb 22, 2019

@d3bgger did you look at #5015 ?

Yes, that's the pr for the doc i linked.

@d3bgger
Copy link

d3bgger commented Feb 26, 2019

turns out that storybook can't find react-scripts config because i use a forked package instead.
"info => Using base config because react-scripts is not installed."
I tested without my forked react-scripts and it works ok.

Any ideas how can i make storybook read the forked config?

@shilman
Copy link
Member

shilman commented Feb 27, 2019

@d3bgger The relevant code is here: https://github.com/storybooks/storybook/blob/next/app/react/src/server/cra-config.js

We'll be documenting these presets more comprehensively after the v5 release

@chungskie
Copy link

If you're having trouble with require-context.macro, here's a workaround that worked for me.

Install babel-plugin-macros:

yarn add --dev babel-plugin-macros

And add this to a .babelrc in your project root or .storybook directory:

{
  "plugins": ["macros"]
}

@kylemh
Copy link
Member

kylemh commented Jul 23, 2019

I was watching this issue, but not the damned repo I made... I've gone ahead and spruced that repo up!

@tmpaul06
Copy link

For those who stumble onto d3bgger's issue:

const req = process.env.NODE_ENV === 'test' ? requireContext('../src', true, /\.stories.js$/) : require.context('../src', true, /\.stories.js$/);

@IstOnline
Copy link

The @ecsmyth solution works for me. Thanks

@bastian-hidalgo
Copy link

For those who stumble onto d3bgger's issue:

const req = process.env.NODE_ENV === 'test' ? requireContext('../src', true, /\.stories.js$/) : require.context('../src', true, /\.stories.js$/);

For those who used it for i18next config:

const req =
  process.env.NODE_ENV === 'test'
    ? __requireContext(__dirname, '..', true, /i18n\.js$/)
    : require.context('..', true, /i18n\.js$/);

Has nothing related to stories, I know, but I came here for the same kind of error, maybe it helps another dev.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addon: storyshots cra Prioritize create-react-app compatibility question / support
Projects
None yet
Development

No branches or pull requests