Skip to content

require.context doesn't work in tests #517

Closed
@suchipi

Description

@suchipi

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?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions