Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

webpack 4 compatibility issue #1737

Closed
ooflorent opened this issue Feb 28, 2018 · 14 comments
Closed

webpack 4 compatibility issue #1737

ooflorent opened this issue Feb 28, 2018 · 14 comments

Comments

@ooflorent
Copy link

Intended outcome:

I'm migrate a project that uses react-apollo@2.1.0-beta.3 from webpack 3 to webpack 4. Once the configuration updated, the build must succeed.

Actual outcome:

The build fails in webpack 4:

ERROR in ./node_modules/react-apollo/query-hoc.mjs
81:27-46 Can't import the named export 'createElement' from non EcmaScript module (only default export is available)
 @ ./node_modules/react-apollo/query-hoc.mjs
 @ ./node_modules/react-apollo/react-apollo.browser.umd.js
 @ ./src/client.js
 @ multi ./src/client.js

ERROR in ./node_modules/react-apollo/ApolloConsumer.mjs
8:12-28 Can't import the named export 'object' from non EcmaScript module (only default export is available)
 @ ./node_modules/react-apollo/ApolloConsumer.mjs
 @ ./node_modules/react-apollo/react-apollo.browser.umd.js
 @ ./src/client.js
 @ multi ./src/client.js

…

webpack 4 favors .mjs over .js files and applies stricter rules when dealing with Harmony modules. Within a Harmony module, you can only import CJS modules as default. The following imports would raise an error since react is not a Harmony module:

import {Component} from "react";
import * as React from "react";

In react-apollo, react-apollo.browser.umd.js is evaluated by webpack as javascript/auto (webpack 3 default mode). It is a loose mode to preserve compatibility that support both CJS and ESM within the same file. When webpack parses require("./ApolloProvider") it will look at ./ApolloProvider.mjs first. Files ending with .mjs are parsed as javascript/esm, a stricter mode. This mode does not allow to import CJS modules like ESM ones.

While this issue looks like a webpack one, it is not: react-apollo should correctly import non-ESM dependencies, in this case react.

How to reproduce the issue:

Install dependencies:

yarn add apollo-client react react-apollo@2.1.0-beta.3
yarn add --dev webpack webpack-cli

Create src/index.js:

import {ApolloProvider} from "react-apollo"
console.log(ApolloProvider)

Build:

yarn webpack --mode production

Version

  • apollo-client@2.2.5
  • react-apollo@2.1.0-beta.3
@refresco12
Copy link

Seems to be the same/similar issue as #1734

@ooflorent
Copy link
Author

@RubenPA Not the same. #1734 is because CRAP uses an old version of uglify-js that does not support ES2015.

@eldh
Copy link

eldh commented Mar 2, 2018

Does anyone know of a workaround?

@jdalton
Copy link

jdalton commented Mar 7, 2018

This is a webpack issue. Named exports of CJS modules are still being ironed out in Node so the lack of support by webpack or the lack of enabling folks to support them seems premature.

Update:

It looks like the solution is to not use .mjs just yet (since it's still being ironed out) and instead use .js with module.rules[].type of "javascript/auto".

Update:

If you use ESM with .js then no type config is needed. It with automatically use javascript/auto and also give you named exports of CJS modules in ESM 🙌

@eldh
Copy link

eldh commented Mar 14, 2018

Adding this to the webpack config rules section worked for me:

{
  type: 'javascript/auto',
  test: /\.mjs$/,
  use: []
}

@ooflorent
Copy link
Author

@eldh I used a similar approach:

{
  test: /\.mjs$/,
  include: /node_modules/,
  type: "javascript/auto",
},

@jdalton
Copy link

jdalton commented Mar 14, 2018

@eldh @ooflorent Nice! Just remember Webpack's defaults are the way they are for a reason. .mjs is limited because it's not fully baked and it's support story isn't finished yet. If you need javascript/auto you should really be using .js.

@eldh
Copy link

eldh commented Mar 14, 2018

Yeah for sure, definitely not meant as a long-term solution!

Is there a specific reason react-apollo uses .mjs? Should that perhaps be changed to .js for now? (Seems like a tiny change to the build script to do so.)

@jdalton
Copy link

jdalton commented Mar 14, 2018

@eldh (I'm not a maintainer) but it looks like it was done as part of a PR to provide esm and cjs variants and they just used .mjs as the distinguisher, likely unaware of the limitations .mjs imposes since they also had require calls in their .mjs which isn't allowed either.

@eldh
Copy link

eldh commented Mar 14, 2018

Yeah, I know. :) Maybe @rosskevin @jaydenseric @jbaxleyiii wants to chime in?

@jdalton
Copy link

jdalton commented Mar 14, 2018

FWIW Inferno.js just switched from .mjs to .esm.js to avoid similar complications in their project.

@jaydenseric
Copy link
Contributor

@eldh I have been pushing for a proper adoption of native ESM hard here for a while now as I have had great success using it in production for my GraphQL API servers and would love to be able to use it everywhere else too. Propper .mjs for react-apollo would particularly benefit people who want to SSR in a native ESM server environment.

The best issue to track regarding support for native ESM via .mjs in Apollo is apollographql/apollo-link#537.

@jdalton I've explained basics in the contributor Slack before, during and after every Apollo .mjs attempt yet issues like still #1589 come up.

react-apollo should only use .mjs if it is properly implemented and tested to work, otherwise you send an incorrect signal to a myriad of tools and stuff breaks and there is zero benefit to using the extension. The gold standard to testing it out is to console.log the named imports in a test.mjs file and run node --experimental-modules test.mjs. Other tools may or may not try to workaround a dodgy implementation.

I'm less invested in bringing native ESM to client side Apollo packages now that graphql-react is on the scene with full support:

screen shot 2018-03-15 at 11 16 04 am

@rosskevin
Copy link
Contributor

rosskevin commented Mar 28, 2018

Note: mjs was dropped in #1801, looks to be released in 2.1.1 https://unpkg.com/react-apollo@2.1.1/

@rosskevin
Copy link
Contributor

Confirmed reverted/working in 2.1.1 as cjs with webpack 4.

terski added a commit to terski/sls-gql that referenced this issue Oct 15, 2018
yuya-takeyama added a commit to yuya-takeyama/keyakizaka46-rss that referenced this issue Oct 20, 2018
danoc added a commit to danoc/react-use-clipboard that referenced this issue Jun 22, 2019
There seems to be a compatability issues with the `.mjs` file extension:

apollographql/react-apollo#1737

This moves away from that extension so that this works in more environments.

Fixes #2.
SpadarShut added a commit to SpadarShut/react-resize-aware that referenced this issue Oct 15, 2019
tried to switch to beta 6 and got the following webpack errors:
> Can't import the named export 'createElement' from non EcmaScript module (only default export is available)
A bit of searching showed that there's a problem with default webpack config and packages that export .mjs files. More details here apollographql/react-apollo#1737
This PR removes the mjs entry from package.json.
FezVrasta pushed a commit to FezVrasta/react-resize-aware that referenced this issue Oct 15, 2019
tried to switch to beta 6 and got the following webpack errors:
> Can't import the named export 'createElement' from non EcmaScript module (only default export is available)
A bit of searching showed that there's a problem with default webpack config and packages that export .mjs files. More details here apollographql/react-apollo#1737
This PR removes the mjs entry from package.json.
danoc added a commit to danoc/react-use-clipboard that referenced this issue Nov 26, 2019
There seems to be a compatability issues with the `.mjs` file extension:

apollographql/react-apollo#1737

This moves away from that extension so that this works in more environments.

Fixes #2.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants