Skip to content

Add support for CJS files #12700

Description

@fryorcraken

Describe the bug

If a dependency contains a .cjs file, then said file is not processed by babel due to the default webpack config, meaning it will not be loaded.

Also, some cjs file are not excluded when needed: #11889

Did you try recovering your dependencies?

Tried but did not help

Which terms did you search for in User Guide?

CJS, ESM, commonjs

Environment

Environment Info:p@5.0.1
Ok to proceed? (y) y
  current version of create-react-app: 5.0.12c87c: timing idealTree:#root Completed in 1377ms
  running from /home/fryorcraken/.npm/_npx/c67e74de0542c87c/node_modules/create-react-app

  System:
    OS: Linux 5.18 Fedora Linux 36 (Workstation Edition)
    CPU: (12) x64 Intel(R) Core(TM) i7-10750H CPU @ 2.60GHz
  Binaries:
    Node: 16.17.0 - ~/.nvm/versions/node/v16.17.0/bin/node
    Yarn: 1.22.19 - ~/.yarn/bin/yarn
    npm: 8.15.0 - ~/.nvm/versions/node/v16.17.0/bin/npm
  Browsers:
    Chrome: 104.0.5112.101
    Firefox: 103.0.2
  npmPackages:
    react: Not Found
    react-dom: Not Found
    react-scripts: Not Found
  npmGlobalPackages:
    create-react-app: Not Found

Steps to reproduce

Use any npm package that contains *.cjs files.

Expected behavior

The .cjs files are correctly loaded and the functions, variable, classes, defined in them are available.

Actual behavior

The .cjs files notloaded and the functions, variable, classes, defined in them are undefined.

Reproducible demo

I don't believe this is necessary as there at least 5 PRs opened to fix this issue:

Related issues

Activity

  1. dben89x commented on Oct 21, 2022

    @dben89x

    This breaks a few different packages for me. I need to go in and directly modify the webpack.config.js in order to fix it. It'd be really helpful if this could get some attention. Until then, CRA needs to be forked...

    This issue was referenced back in 2020, but was closed as completed for some reason: #8754

  2. dben89x commented on Oct 27, 2022

    @dben89x

    For anyone who needs CJS support, add react-app-rewired and add a file named config-overrides.js at the root of your project, with the following contents:

    const getCacheIdentifier = require('react-dev-utils/getCacheIdentifier');
    
    const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
    
    module.exports = function override(config, webpackEnv) {
      console.log('overriding webpack config...');
    
      const isEnvDevelopment = webpackEnv === 'development';
      const isEnvProduction = webpackEnv === 'production';
      const loaders = config.module.rules[1].oneOf;
    
      loaders.splice(loaders.length - 1, 0, {
        test: /\.(js|mjs|cjs)$/,
        exclude: /@babel(?:\/|\\{1,2})runtime/,
        loader: require.resolve('babel-loader'),
        options: {
          babelrc: false,
          configFile: false,
          compact: false,
          presets: [
            [
              require.resolve('babel-preset-react-app/dependencies'),
              { helpers: true },
            ],
          ],
          cacheDirectory: true,
          // See #6846 for context on why cacheCompression is disabled
          cacheCompression: false,
          // @remove-on-eject-begin
          cacheIdentifier: getCacheIdentifier(
            isEnvProduction
              ? 'production'
              : isEnvDevelopment && 'development',
            [
              'babel-plugin-named-asset-import',
              'babel-preset-react-app',
              'react-dev-utils',
              'react-scripts',
            ]
          ),
          // @remove-on-eject-end
          // Babel sourcemaps are needed for debugging into node_modules
          // code.  Without the options below, debuggers like VSCode
          // show incorrect code and set breakpoints on the wrong lines.
          sourceMaps: shouldUseSourceMap,
          inputSourceMap: shouldUseSourceMap,
        },
      });
    
      return config;
    };

    Then replace your the react-scripts scripts in your package.json with the following:

    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    

    Fixed it for me.

  3. fryorcraken commented on Oct 28, 2022

    @fryorcraken
    Author

    For anyone who needs CJS support, add react-app-rewired and add a file named config-overrides.js at the root of your project, with the following contents:

    I would recommend using https://github.com/dilanx/craco/ instead, it is better maintained and provide more flexibility.

  4. laustdeleuran commented on Mar 9, 2023

    @laustdeleuran

    @dben89x, thanks for the workaround. I'm gonna try to adapt it to craco. Can you explain how this workaround works? It might just be my late afternoon brain, but I'm having trouble understanding what's going on.

  5. 1038642892 commented on Mar 9, 2023

    @1038642892

    I can confirm the issue and here's the work around to prove it, would be good to have CRA updated to include CJS.

    When I change webpack.config.js (adding cjs to the mix) within the node_modules of my CRA app I no longer receive undefined error when loading my dependency which uses .cjs.

                // Process application JS with Babel.
                // The preset includes JSX, Flow, TypeScript, and some ESnext features.
                {
                  test: /\.(js|mjs|jsx|ts|tsx|cjs)$/,
    
                // Process any JS outside of the app with Babel.
                // Unlike the application JS, we only compile the standard ES features.
                {
                  test: /\.(js|mjs|cjs)$/,
    
  6. laustdeleuran commented on Mar 10, 2023

    @laustdeleuran

    I adapted @nyan-left's workaround for use with craco, and it solved my issues:

    // craco.config.ts
    export default {
      webpack: {
        configure: config => ({
          ...config,
          module: {
            ...config.module,
            rules: config.module.rules.map(rule => {
              if (rule.oneOf instanceof Array) {
                // eslint-disable-next-line no-param-reassign
                rule.oneOf[rule.oneOf.length - 1].exclude = [
                  /\.(js|mjs|jsx|cjs|ts|tsx)$/,
                  /\.html$/,
                  /\.json$/,
                ];
              }
              return rule;
            }),
          },
        }),
      },
    };

    However, I still think this is a bug in create-react-app, that this issue is valid, and that one of the many PRs mentioned in this issue would be a better way to solve it.

  7. JurajKavka commented on Jul 28, 2023

    @JurajKavka

    Hi. I spent couple of hours with solving nothing expanatory error message. I was trying to use my package with dependency on react-tooltip within host project built with create-react-app

    image

    Following workaround above, my project works, but we have like 20 projects depended on our custom package and all of them are built with create-react-app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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