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

Add .cjs and .mjs files support #535

Closed
ai opened this issue Mar 21, 2020 · 10 comments
Closed

Add .cjs and .mjs files support #535

ai opened this issue Mar 21, 2020 · 10 comments

Comments

@ai
Copy link

ai commented Mar 21, 2020

Do you want to request a feature or report a bug?

bug

What is the current behavior?

If you have require('./index.cjs') you will have issue:

Error: While trying to resolve module `lib` from file `project/index.js`, the package `project/node_modules/lib/package.json` was successfully found. However, this package itself specifies a `main` module field that could not be resolved (`project/node_modules/lib/index.cjs`. Indeed, none of these files exist:

      * project/node_modules/lib/index.cjs(.native|.web.js|.native.js|.js|.web.json|.native.json|.json|.web.ts|.native.ts|.ts|.web.tsx|.native.tsx|.tsx)
      * project/node_modules/lib/index.cjs/index(.native|.web.js|.native.js|.js|.web.json|.native.json|.json|.web.ts|.native.ts|.ts|.web.tsx|.native.tsx|.tsx)

If the current behavior is a bug, please provide the steps to reproduce and a minimal repository on GitHub that we can yarn install and yarn test.

  1. Create empty project
  2. Add lib.cjs
  3. Create index.js with require('./lib.cjs')

What is the expected behavior?

Load .cjs files as any .js files.

Please provide your exact Metro configuration and mention your Metro, node, yarn/npm version and operating system.

  • No Metro config
  • Metro 0.59.0
  • Node 13.11.0
  • Yarn 1.22.4

Extra details

I opened this issue because users of my dual CJS/ESM project have a problem with using my lib to React Native
ai/nanoevents#44 (comment)

You had .mjs issue before, but it was closed because in 2017 it was not clear about .mjs standard. Now .mjs and .cjs is an official Node.js API.

voidrender added a commit to voidrender/demo-react-native-emotion that referenced this issue Sep 2, 2020
Workaround for metro deficiency: facebook/metro#535

Caused by stylis shipping a .cjs file: thysultan/stylis#233

Fix from emotion-js/emotion#1986
voidrender added a commit to voidrender/demo-react-native-emotion that referenced this issue Sep 2, 2020
Workaround for metro deficiency: facebook/metro#535

Caused by stylis shipping a .cjs file: thysultan/stylis#233

Fix from emotion-js/emotion#1986
@rossmartin
Copy link

rossmartin commented Nov 16, 2021

I wanted to chime in and mention how I worked around this currently with RN 0.65.1

metro.config.js

/**
 * Metro configuration for React Native
 * https://github.com/facebook/react-native
 *
 * @format
 */
const defaultSourceExts =
  require('metro-config/src/defaults/defaults').sourceExts;
module.exports = {
  transformer: {
    getTransformOptions: () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
  resolver: {
    sourceExts: process.env.RN_SRC_EXT
      ? [...process.env.RN_SRC_EXT.split(',').concat(defaultSourceExts), 'cjs'] // <-- cjs added here
      : [...defaultSourceExts, 'cjs'], // <-- cjs added here
  },
};

The latest version of @apollo/client (3.5.2) is using .mjs as the entry point of the package. The above change fixed the issue with the dep.

@ndukachukz
Copy link

ndukachukz commented Jan 19, 2022

How do I resolve this using expo?. I am using expo w/ typescript & I have no metro.config. any ideas on how to go about this?

@mchambaud
Copy link

mchambaud commented Jan 19, 2022

https://docs.expo.dev/guides/customizing-metro/

const { getDefaultConfig } = require('@expo/metro-config');

const config = getDefaultConfig(__dirname);

config.resolver.sourceExts = process.env.RN_SRC_EXT
    ? [...process.env.RN_SRC_EXT.split(',').concat(config.resolver.sourceExts), 'cjs'] // <-- cjs added here
    : [...config.resolver.sourceExts, 'cjs'] // <-- cjs added here

module.exports = config;

@ndukachukz
Copy link

Thanks works great. Now I'm having another error.

ReferenceError: Can't find variable: indexedDB

@mchambaud
Copy link

mchambaud commented Jan 19, 2022

Does React-Native even support IndexedDB?

You should research this away from this page as it's not relevant to this topic.

@vladimirevstratov
Copy link

I wanted to chime in and mention how I worked around this currently with RN 0.65.1

metro.config.js

/**
 * Metro configuration for React Native
 * https://github.com/facebook/react-native
 *
 * @format
 */
const defaultSourceExts =
  require('metro-config/src/defaults/defaults').sourceExts;
module.exports = {
  transformer: {
    getTransformOptions: () => ({
      transform: {
        experimentalImportSupport: false,
        inlineRequires: true,
      },
    }),
  },
  resolver: {
    sourceExts: process.env.RN_SRC_EXT
      ? [...process.env.RN_SRC_EXT.split(',').concat(defaultSourceExts), 'cjs'] // <-- cjs added here
      : [...defaultSourceExts, 'cjs'], // <-- cjs added here
  },
};

The latest version of @apollo/client (3.5.2) is using .mjs as the entry point of the package. The above change fixed the issue with the dep.

if anyone will encount problem with react navigation on react native:

Error: While trying to resolve module `nanoid/non-secure` from file `node_modules/@react-navigation/core/lib/commonjs/useRegisterNavigator.js`, the package `node_modules/nanoid/non-secure/package.json` was successfully found. However, this package itself specifies a `main` module field that could not be resolved (`/node_modules/nanoid/non-secure/index.cjs`. Indeed, none of these files exist:

This answer will help you too! Thanks @rossmartin

@mobinni
Copy link

mobinni commented Apr 15, 2022

I ran into an issue with firebase session persistence on React Native where it would not persist the auth session with the default fix of

[...defaultSourceExts, 'cjs']

@vladimirevstratov 's solution above

    sourceExts: process.env.RN_SRC_EXT
      ? [...process.env.RN_SRC_EXT.split(',').concat(defaultSourceExts), 'cjs'] // <-- cjs added here
      : [...defaultSourceExts, 'cjs'], // <-- cjs added here

Fixed that issue

@Ahmed-ao
Copy link

This solution :
const { getDefaultConfig } = require("metro-config");
const { resolver: defaultResolver } = getDefaultConfig.getDefaultValues();
exports.resolver = {
...defaultResolver,
sourceExts: [
...defaultResolver.sourceExts,
"cjs",
],
};

doesn't solve it all I still get some errors like:
[TypeError: undefined is not a function (near '...graphql.parse...')]
https://gist.github.com/Ahmed-ao/69653660b03660cc94c7830b3bfbc8f9

here is a link to a simple gist that shows my dependencies and component

@bombillazo
Copy link

I solved it like this for now:

// metro.config.js
const { getDefaultConfig } = require('@expo/metro-config');
const defaultConfig = getDefaultConfig(__dirname);

module.exports = (async () => {
  ...
  defaultConfig.resolver.sourceExts.push('cjs');
  ...
  return defaultConfig;
})();

@huntie
Copy link
Member

huntie commented Jul 28, 2022

This issue is resolved in c1c6d9c which should ship in the next major release (0.72.0) 🙂.

  • Metro will now resolve .cjs and .mjs extensions by default when imported explicitly (import/require that includes the module file extension).
  • Additional source file extensions for explicit resolution can now be configured via the watcher.additionalExts option.
  • Importing .cjs and .mjs files implicitly (without giving the extension) can still be configured via resolver.sourceExts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants