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

Will/does Webpack support "module" field? #1979

Closed
TehShrike opened this issue Feb 2, 2016 · 77 comments
Closed

Will/does Webpack support "module" field? #1979

TehShrike opened this issue Feb 2, 2016 · 77 comments

Comments

@TehShrike
Copy link

To allow importing of ES6 modules with an ES5 module in the package.json's "main" field.

As proposed by rollup.

@IngwiePhoenix
Copy link

I +1 this.

Proposed:

However... Should jsnext:main be treatened in a way that it can't be ignored? Just a thought.

Kind regards,
Ingwie.

@SimenB
Copy link
Contributor

SimenB commented Feb 28, 2016

#1612 (comment)

@taion
Copy link

taion commented Apr 16, 2016

Coming from remix-run/react-router#3333, I'd really like if there were a way to specify the location of the ES module build for webpack users.

I'm a little bit frightened that people are importing from the subdirectory containing the ES modules directly.

@rosskevin
Copy link

rosskevin commented Jun 20, 2016

+1 to be a default as @IngwiePhoenix says.

Is there a current way to plugin a resolver to webpack 2 to prefer jsnext:main and otherwise fallback to main? I can currently alter resolve.mainFields (until it is in the default list) but don't we still have to either include that dynamically as part of the src loading?

@TheLarkInn
Copy link
Member

@sokra I could take a stab at this if this is as easy as it appears to be.

@taion
Copy link

taion commented Jun 27, 2016

Why do you need a plugin for this? Just set e.g.

mainFields: ['jsnext:main', 'browser', 'main']

in your webpack config.

@rosskevin
Copy link

@taion - The problem with this approach is transitive dependencies (or so it seemed when I tried it). I don't think it is as simple as it looks to simply configure or plug-in, it needs to be considered in the primary resolution so that we can take advantage of tree-shaking etc.

@taion
Copy link

taion commented Jun 27, 2016

It works just fine transitively.

@rosskevin
Copy link

That is my error in that case; if you have figured it out I'm sure all the participants here would like to see an example of this running.

@taion
Copy link

taion commented Jun 27, 2016

In webpack.config.js, just do e.g.

resolve: {
  mainFields: ['jsnext:main', 'browser', 'main'],
},

That's all you need.

@rosskevin
Copy link

hmm, that didn't work for me when I tried it and I had multiple transitive dependency failures. Several projects including react-router provide these sources yet my imports failed. I was sure to allow sources to be pulled (not excluded) from node_modules.

@TheLarkInn
Copy link
Member

I'd assume this would be a desired default with fallback for main. No?

@adamdicarlo
Copy link

Besides adding 'jsnext:main' to mainFields, don't you need to somehow teach Babel "you actually need to process some stuff in my node_modules folder"?

@avocadowastaken
Copy link

@adamdicarlo

That works for me

{
  test: /\.js$/,
  loader: 'babel',
  exclude: /node_modules\/(?!(([^\/]+?\/){1,2}(src|es6)))/,
}

Tested it here

@adamdicarlo
Copy link

that matches /node_modules/react-router/node_modules/foo/es6/index.js. but anyway, I don't think checking for a folder named src or es6 is a long term/general solution.

Webpack supports callbacks for exclude/include; in the past, I've set up logic to do this:

  1. figure out which package the file is a part of (by recursively scanning folder & parent folders for a package.json), and
  2. inspect that package.json to figure out whether its source needs transpilation

but if Webpack will support jsnext:main out of the box, it seems pretty silly to manually need to set up this kind of mechanism for every project...

@taion
Copy link

taion commented Jul 23, 2016

Babel doesn't need to process anything in node_modules. By convention, an ES module build is the same as the CJS build, with the only exception being the module system. The rest of the ESNext features should still be transpiled.

@taion
Copy link

taion commented Jul 23, 2016

Take a look at e.g. how Redux and React Router do this.

@adamdicarlo
Copy link

Hmm, right. That's maybe good enough in general. There are downsides, though: your host project's babel plugins do not get applied to the (e.g.) React components you npm installed. So you can't, for instance, use babel-plugin-rewire to mock a package in node_modules. You can't apply babel-plugin-react-transform to those components either.

And when npm linking packages and working on them in the context of a host app—which is already a pain, of course—you'd have to have the linked package's build watcher running, too.

@adamdicarlo
Copy link

Another thought: What about the (not too distant?) future where we want to ship ES2015 code to browsers? Surely packages will mostly be written in ES2016 (or ES2017) then — so they'd need to provide ES5 and ES2015 (and eventually ES2016) builds. ¯_(ツ)_/¯ (WebAssembly support can't come fast enough IMO...)

@taion
Copy link

taion commented Jul 23, 2016

wasm isn't going to fix anything because if for some bizarre reason you decide to compile JS to wasm, you're effectively opting out of the bulk of things that the JIT can do.

Yes, it's true that the "projects ship transpiled code" has some set of disadvantages – but that's orthogonal to the question of the choice of module system used for distribution.

@avocadowastaken
Copy link

@adamdicarlo

I don't think checking for a folder named src or es6 is a long term/general solution.

Webpack 2 still in beta, so it's just temporary workaround

@taion

Babel doesn't need to process anything in node_modules. By convention, an ES module build is the same as the CJS build, with the only exception being the module system. The rest of the ESNext features should still be transpired.

Yep, but modules like redux-form or moment use /src dir in jsnext:main

@scopsy
Copy link

scopsy commented Oct 1, 2017

@hccampos Hey Hugo,
I'm currently running in an issue where a library I'm using is dependent on a package that uses "module" field in its package.json file.
When compiling ng build --aot --prod I'm getting an error:

Unexpected token: name (CalendarVietnamese) [0.a821737870a81bd01043.chunk.js:8779,6]

When I removed the "module" from that package compilation works fine.

Any suggestions?

@hccampos
Copy link

hccampos commented Oct 1, 2017

@scopsy the only solutions I know of at the moment are:

  1. Eject the webpack config and fix it manually.
  2. Fork the library, the update package.json and use the fork in your project.

We are using option 2 and just maintaining forks of the original repos for libraries that don't work with the Angular CLI

@scopsy
Copy link

scopsy commented Oct 1, 2017

@hccampos When ejecting the webpack config what needs to be changed there?

@gaearon
Copy link
Contributor

gaearon commented Oct 26, 2017

Since we are using the Angular CLI which has no transpiling other than Typescript, any modules which specify a module field will be imported as es2015 modules. And a lot of times things will only really break when you run it in an older browser that doesn't support class, something which you normally don't do everyday when developing.

I think we might be conflating two different things here. The module entry point should point to code with ES6 modules but not necessarily other ES6 features. People who want their libraries to be in ESM format can/should still precompile other ES6 features so that older browsers don't break.

@donaldpipowitch
Copy link

People who want their libraries to be in ESM format can/should still precompile other ES6 features so that older browsers don't break.

I asked for this as a feature request to support this as a native webpack feature a while ago, if someone is interested in this topic: #2933.

@hccampos
Copy link

@gaearon absolutely! That is what MobX does, for example. However, more and more libraries seem to be popping up which don't transpile the rest to es5, breaking builds which run without babel/bubble. The worst part is that you only notice the breakage when testing on older browsers, which usually happens on a CI environment or manually after deploy.

saki7 added a commit to saki7/nagato that referenced this issue Oct 29, 2017
…ck's tree shaking.

This is currently *not* supported by Webpack (see webpack/webpack#1979 (comment) and webpack/webpack#2933 for rationale).

We workaround this by exposing our babel config to the wild (i.e. js/nagato/babel-options.js). This way we can give full controls for both bundling (i.e. 'tree shaking' in Webpack) and module building (i.e. 'transpiling') to the library users (I hope).

We just can't enforce our users to use some huge-sized arbitrary bundle.

Users with ES2015+ (or whatever) environment shall `require()` this config file inside their 'webpack.config.js', and use it as a hash object for the `babel-loader`'s `option: ` option. This could be achieved by looking into the `module: ` option in `package.json`; which (I believe) is the default behavior for Webpack when you use the native `import Something from 'other-external-library'` syntax.

If this is not desirable, use the fully-transpiled .js file inside our distributed npm package. This could be achieved by referring to the old-school `"main"` value inside the package.json.

Disclaimer:
By using this method we abandon Webpack-specific aggresive transpilation features for our entire library. This means we can't use Webpack-specific custom `import`s (i.e. importing non-JavaScript files like images (.png, .jpg, etc.) inside our library (.js)).

Additional notes:
This issue described in the disclaimer section can be workarounded by specifying your library-specific `npm run build` action inside the `prepare` section of package.json.
gimdongwoo added a commit to jsdevkr/axui-datagrid that referenced this issue Nov 19, 2018
robinloeffel pushed a commit to robinloeffel/mehrsprachig that referenced this issue Dec 29, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests