create-react-app: require.context doesn't work in tests
I sometimes use webpack’s require.context
to automatically load files from the filesystem. Example:
Directory structure:
- components
- Button.js
- Icon.js
- index.js
- docs.js
index.js
:
// `require` in every file except index.js from the current directory, then
// add their default export to module.exports based on their filename.
// eg module.exports["Button"] = require("./Button.js");
const req = require.context(".", false, /^\.\/(?!index).*\.js$/);
req.keys().forEach((fileName) => {
const exportName = fileName.replace("./", "").replace(".js", "");
module.exports[exportName] = req(fileName).default;
});
docs.js
:
import * as components from "./components";
Object.entries(components).forEach(([componentName, ComponentClass]) => {
/* generate docs for `componentName` using `ComponentClass` */
});
This example is somewhat contrived because index.js
could just be replaced with:
import Button from "./Button";
import Icon from "./Icon";
export { Button, Icon }
but when you’re importing hundreds of files, this is both helpful and powerful; it’s easy to write a require.context
that treats named exports differently, for example:
const req = require.context(".", false, /^\.\/(?!index).*\.js$/);
req.keys().forEach((fileName) => {
const exportName = fileName.replace("./", "").replace(".js", "");
// next line changed, now we export both the default export and the named docExamples export
module.exports[exportName] = [req(fileName).default, req(fileName).docExamples];
});
This pattern allows you to co-locate documentation examples with your code, which discourages documentation getting out of sync with the component.
Although this example only addresses documentation, this pattern can be useful anywhere you have a lot of files with correlated features and enforcing an export signature convention is feasible and discourages code rot.
This is all possible using create-react-app
today. However, it all breaks when you try to run your tests (in 0.3.0-alpha), because jest (naturally) doesn’t use webpack:
Using Jest CLI v14.1.0, jasmine2
FAIL src/__tests__/some-test.js (0s)
Runtime Error
- TypeError: require.context is not a function
Is require.context
“too obscure” of a webpack feature? Should create-react-app
start disallowing it or warning about its usage? Where and how do we draw the line on which webpack features should be supported and which should not be?
Or, should we try to support require.context
in the test runner enrivonment? If so, where and how do we draw the line on which webpack features should be supported in the test environment?
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 4
- Comments: 24 (11 by maintainers)
Inside of tests this is fine, you can require dynamic modules as much as you’d like and sometimes that is useful.
Outside of tests it is bad because those cases cannot be statically analyzed.
FYI for anyone who encounters this issue - instead of relying on
require.context
or manually building a file like @gaearon suggested, you can use directory-metagen automatically generate import/requires for files in a directory. It can output es6 modules, AMD, commonjs, and more. It even has a CLI 😃No, unfortunately not… and just to be clear, I’m not expecting you to magic a solution out of thin air, I’ve just found from experience that it’s useful to receive feedback. I’m not expecting require.context to be suddenly supported, I just wanted to share my experience.
I’ll continue to try to find a good solution to the problem and will provide an update if and when I do.
I do appreciate you taking the time to answer though and provide suggestions.
All comments makes sense. Thanks for the discussion. Future readers: I was able to workaround this by providing mocks for each file that uses
require.context
, as @cpojer indicated. But as it is unsupported, I do not recommend using it. I plan on changing my code to not use it.