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

Can't import the named export 'Component' from non EcmaScript module (only default export is available) #1395

Closed
danilofuchs opened this issue Aug 6, 2019 · 30 comments

Comments

@danilofuchs
Copy link

When using create-react-app with Typescript, I cannot complete a successful build.

Failed to compile.

./node_modules/react-intl/dist/components/message.mjs
Can't import the named export 'Component' from non EcmaScript module (only default export is available)

Expected behavior

Should build

Current behavior

Does not build

Step to reproduce for BUG REPORT

yarn add react-intl@3.1.0

Your Environment

Executable Version
npm ls react-intl 3.1.0
npm ls react 16.8.6
yarn --version 1.16.0
node --version 10.16.0
OS Version
MacOS Mojave 10.14.6
@longlho
Copy link
Member

longlho commented Aug 6, 2019

CRA doesn't support mjs. There's a workaround mentioned here: #143

@danilofuchs
Copy link
Author

danilofuchs commented Aug 6, 2019

This is a huge problem for most users, and increases the time needed to configure react-intl.
I was able to make it work by following reactioncommerce/reaction-component-library#399 (comment).
I am using customize-cra, so my solution became:

// config-overrides.js
const { override } = require("customize-cra");

const supportMjs = () => (webpackConfig) => {
    webpackConfig.module.rules.push({
        test: /\.mjs$/,
        include: /node_modules/,
        type: "javascript/auto",
    });
    return webpackConfig;
};

module.exports = override(
    supportMjs()
);

@lc-stevenzhang
Copy link

lc-stevenzhang commented Aug 6, 2019

Same issue here, not using webpack. And we need to roll back to 3.0.0 to fix this problem.

@polson136
Copy link

I am having the same issue using babel/webpack. When debugging, I noticed a couple issues with the built code, spot checked using message.mjs

  1. .mjs files MUST use extensions on their imports, ex: import { Context } from './injectIntl.mjs' instead of `import { Context } from './injectIntl'.
  2. .mjs files can ONLY import commonjs modules by their default export. It is importing react as import * as React from 'react'.
    Note that both of these patterns ARE allowed when using the "module" field in package.json, but they ARE NOT allowed when using "type": "module"/.mjs extension.

@longlho
Copy link
Member

longlho commented Aug 6, 2019

@lc-stevenzhang what's ur setup?
@polson136 does #143 (comment) not work for u?

@lc-stevenzhang
Copy link

@lc-stevenzhang what's ur setup?
@polson136 does formatjs/formatjs#143 (comment) not work for u?

We use create-react-app + circle-ci. With latest version of React and npm, running on MacOs Mojave 10.14.6. And got exact same build error as @danilofuchs .

@longlho
Copy link
Member

longlho commented Aug 6, 2019 via email

@danilofuchs
Copy link
Author

danilofuchs commented Aug 7, 2019

I'm sure the community for react-intl discussed a lot about the possible implications of this change, but I would really like to have a solution that does not break CRA or needs the user to perform additional build configurations.

Maybe .mjs files could be exported at a different root, like react-intl/esm.

The base minimum is to document well the steps needed to configure CRA / webpack 4.

@polson136
Copy link

@polson136 does formatjs/formatjs#143 (comment) not work for u?

It does work, but the reason why it works is because, as I mentioned in my previous comment, you are using .mjs wrong. The errors we are getting are correct according to the behavior of .mjs as described in the node documentation.

But you're really not doing anything special, there are many projects that export both commonjs and esm versions, so no special configuration should be required. (not even the extension part)

To name a few:
luxon
antd
react-router
redux

@danilofuchs
Copy link
Author

danilofuchs commented Aug 7, 2019

There are many projects that export both commonjs and esm versions, so no special configuration should be required. (not even the extension part)

To name a few:
luxon
antd
react-router
redux

Looking at the bundle produced by these projects, they usually export 2 or more folders:

antd
  |_es/
  |_lib/

react-router-dom
  |_cjs/
  |_es/
  |_esm/
  |_umd/

And in package.json, they add all the possible entrypoints in the files array. I don't know if the order in this field is important, but those libraries always put the default cjs or lib folder as one of the first paths, followed by es.

@longlho
Copy link
Member

longlho commented Aug 7, 2019

We used to separate out ESM/CJS dist, but then it broke some other bundling tool. The short answer is that there's no perfect solution for all bundlers (webpack/rollup/fuse-box/parcel/node) along with their transpiler combo (babel/typescript). This project doesn't have enough resources to debug them all unfortunately. So far the current state only breaks CRA (which doesn't allow custom webpack config & that's on them) and I'm fine with that. I want to focus our efforts on new features instead of fighting bundlers.

@polson136
Copy link

polson136 commented Aug 7, 2019

May I ask which bundler(s) the old way broke?

@hon2a
Copy link

hon2a commented Aug 7, 2019

I want to focus our efforts on new features instead of fighting bundlers.

That sentiment is completely understandable, but unfortunately this:

So far the current state only breaks CRA (which doesn't allow custom webpack config & that's on them)

is seriously off the point here. It doesn't much matter that it's technically possible to use react-intl@3 if using it requires unreasonable amount of additional setup. Every package out there using react-intl will have to make transpile/bundle adjustments specifically for it? The project I'm working on right now has 700 dependencies so far … what if they started doing the same?

@paolostyle
Copy link

Why is this package using .mjs, anyway? I have a medium sized project (~50k lines of code) with a lot of dependencies and none of them is using mjs. Quite a lot of them provide ES modules builds, but it's usually named index.es.js or esm.js and it works perfectly fine, also with treeshaking. Don't quite understand the need to use .mjs here. If it's because of Node compatibility I wonder how many people actually use it in Node considering it's named react-intl, unless it's relevant for things like next.js, but I'm not sure here.

I don't know what's your goal with this project but if you want people to use it, making it work on CRA without any additional config, like majority of React-related libraries do, should be a very high priority.

@longlho
Copy link
Member

longlho commented Aug 8, 2019 via email

@paolostyle
Copy link

I don't either. I'll try to tackle this on Saturday, but my main goal will be making it work on a typical CRA based app without any additional config, hopefully without breaking what you currently have.

@longlho
Copy link
Member

longlho commented Aug 8, 2019

https://codesandbox.io/s/fervent-hypatia-f855r uses vanilla CRA & react-intl & it works so I also don't know what's wrong. I personally don't use CRA so I can't debug.

@polson136
Copy link

Why is this package using .mjs, anyway? I have a medium sized project (~50k lines of code) with a lot of dependencies and none of them is using mjs. Quite a lot of them provide ES modules builds, but it's usually named index.es.js or esm.js and it works perfectly fine, also with treeshaking. Don't quite understand the need to use .mjs here. If it's because of Node compatibility I wonder how many people actually use it in Node considering it's named react-intl, unless it's relevant for things like next.js, but I'm not sure here.

I don't know what's your goal with this project but if you want people to use it, making it work on CRA without any additional config, like majority of React-related libraries do, should be a very high priority.

Well, and on top of that, is that the way they are implementing .mjs is just straight wrong. It clearly violates the closest thing I could find to a spec: https://nodejs.org/api/esm.html#esm_differences_between_es_modules_and_commonjs
Specifically, it does not include file extensions: https://nodejs.org/api/esm.html#esm_mandatory_file_extensions
and it does a named import of a commonjs module: https://nodejs.org/api/esm.html#esm_code_import_code_statements
If they were to fix both of those things, it would work just fine in webpack. But I also don't know what they're doing using .mjs as it is still experimental and thus shouldn't be used in production code.

@polson136
Copy link

PR’s welcome. As I said I don’t have bandwidth to cross check all the bundlers & transpilers combo.

Fix: revert 5fd070d
I don't see any documentation on what problem that commit was attempting to solve or why that change occurred.

@longlho
Copy link
Member

longlho commented Aug 9, 2019

it was attempting to solve importing from the same path & get cjs or esm if supported, e.g import foo from 'foo/dist/bar' and not import foo from 'foo/dist-es/bar'/import foo from 'foo/dist-cjs/bar'. Again, if u have a better way to solve this, PR's welcome.

@polson136
Copy link

@longlho I'm not putting the time into opening a PR unless there is a chance that it might be accepted, and right now it's quite clear that we disagree on what the solution should be, and you are the only representative of the project on this thread.

Regarding import foo from 'foo/dist/bar', I don't see this in the documentation anywhere. Is this intended as a future feature? I'm not sure if there's an official term for this, I will refer to it here as 'subpath imports'.

Generally, most people know whether their environment supports ESM or commonjs, so I assume that using subpath imports consistently between commonjs and esm is intended for people using a bundler such as webpack, as well as environments which do not natively support ESM, such as tests or SSR?

If you were instead to revert to the 3.0 build system, then people who wanted to do subpath imports could do import foo from 'foo/dist-cjs/bar' and then in the webpack config use a resolve alias to map it to the esm version (https://webpack.js.org/configuration/resolve/#resolvealias). Most bundlers have a similar feature, as does typescript.
The key difference between the 3.0 build system and the 3.1 build system is that the 3.1 build system requires special configuration for people that use a bundler (nearly everyone because it's a client side library), where the 3.0 build system only requires a special configuration for projects that both execute as CJS and ESM AND use subpath imports. Given that subpath imports are not a documented feature right now, this will be a vast minority of users.

The other option is to fix the build process so that it correctly follows the .mjs spec by including the file extensions in the import paths and correctly importing commonjs modules. I don't think that is feasible at this time, since there is no tooling available to do that because no one will implement it until the spec is finalized (/~https://github.com/nodejs/modules/blob/master/doc/plan-for-new-modules-implementation.md#phase-3-path-to-stability-removing---experimental-modules-flag). Once the spec is finalized in October and the tooling catches up, then something like this will probably make a lot of sense, and this can be revisited.

@polson136
Copy link

@longlho Thank you.

@JustFly1984
Copy link

JustFly1984 commented Aug 12, 2019

It does break not only CRA, but our Gatsby.js typesctipt projects too. Typescript does not support mjs files yet.

@redonkulus
Copy link
Member

@JustFly1984 this was fixed and released yesterday. Please try it out. Thanks!

@joker7blue
Copy link

if you have imported ======> import { process } from 'postcss-preset-env'; then remove it!

Yuyz0112 added a commit to smartxworks/sunmao-ui that referenced this issue Oct 27, 2021
@vue-reactivity/watch use tsup as its bundler, which create .mjs
file as the ES module output.
But webpack4 do not like .mjs extension which cause tools like
create-react-app failed when using meta-ui. Even users can add some
trick to let webpack4 bundle .mjs file, the watch function still
not working.

Refs:
1. facebook/create-react-app#10356
2. formatjs/formatjs#1395 (comment)
@Aadil-Shabir
Copy link

This is a huge problem for most users, and increases the time needed to configure react-intl. I was able to make it work by following reactioncommerce/reaction-component-library#399 (comment). I am using customize-cra, so my solution became:

// config-overrides.js
const { override } = require("customize-cra");

const supportMjs = () => (webpackConfig) => {
    webpackConfig.module.rules.push({
        test: /\.mjs$/,
        include: /node_modules/,
        type: "javascript/auto",
    });
    return webpackConfig;
};

module.exports = override(
    supportMjs()
);

This is not working

@mauriciord
Copy link

@Aadil-Shabir Have you found any solution for that?

xzdry pushed a commit to smartxworks/sunmao-ui that referenced this issue Nov 3, 2022
@vue-reactivity/watch use tsup as its bundler, which create .mjs
file as the ES module output.
But webpack4 do not like .mjs extension which cause tools like
create-react-app failed when using meta-ui. Even users can add some
trick to let webpack4 bundle .mjs file, the watch function still
not working.

Refs:
1. facebook/create-react-app#10356
2. formatjs/formatjs#1395 (comment)
MorevM added a commit to MorevM/utils that referenced this issue Jan 17, 2023
To prevent ESM errors for external packages.
Kinda explanation: formatjs/formatjs#1395 (comment) (2)
@anubhavKumawat92
Copy link

following, facing the same problem

@thesmashten
Copy link

Framer motion you suck ass!!!!

@thesmashten
Copy link

Honestly this entire library (framer motion) should be deleted.. it's utterly useless and not to mention the fact impossible to install. It's a joke of a library, and it's a disgrace that they still proudly display their 'work'.

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.