babel-plugin-dynamic-import-node: Inconsistency with Webpack v4

So when using dynamic imports with Webpack v4, Webpack is now using a namespace object.

https://github.com/webpack/webpack/releases/tag/v4.0.0 https://medium.com/webpack/webpack-4-import-and-commonjs-d619d626b655

This matches what is done when you use ESM modules and you import Commonjs. You have to reference “default” now in Webpack v4 when attempting to reference module.exports. This is not the same as doing a deferred require on the server. My workaround has been to do something akin to this

const EXIFModule = await import(/* webpackChunkName: "exif-js" */ 'exif-js');
// Gets around dynamic import inconsistencies between browser and server
const EXIF = EXIFModule.default || EXIFModule;

Ideally, there would be some way to at least have a setting for this plugin to turn on namespace object dynamic imports.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 4
  • Comments: 16

Most upvoted comments

Maybe I’m not being clear but I am not saying we need to drop everything and conform to Webpack v4 because there is no other use case. I am saying that Webpack is used much more than Rollup and Browserify (https://stateofjs.com/2017/build-tools/results) and that this is a legitimate issue. My suggestion would be to add a config option in babel for a slightly different require to handle both cases if you are using Webpack v4. Is there anything specific that I am saying that you think is false?

It is my understanding that the purpose of this plugin is to take Javascript code that uses a dynamic import and then have that code run with Node.js. The primary reason somebody would be using a dynamic import is for use with Webpack. Then, they may want to run that same Webpack code in a test or on a server with isomorphic Javascript which is where this plugin comes in to help. I’m not attempting to be argumentative, but this inconsistency is going to cause problems for people that are trying to reuse Webpack code in Node.

I’ll figure out differences and will make a PR in a few days.

Whether Webpack is making the wrong choice or not, this is still a significant inconsistency. Webpack is currently the primary use case for dynamic imports and if the spec isn’t settled, shouldn’t this plugin handle different scenarios? Otherwise, if you are using a dynamic import on a commonjs module, you will have to work around this issue nearly every time.

I still get .default not resolved automatically when using this plugin.

I had this problem too. Turns out I had installed babel-plugin-transform-dynamic-import which actually points to this GitHub repository.

Installed babel-plugin-dynamic-import-node and all is working fine now.

I’ve found this to be helpful:

const dynamicImport = import('./my_module').then(x => x.default || x);

this catches both cases, if it’s exported as an es module the default export is returned, otherwise the whole thing is returned.

@ixth I’m fine adding an option, but not with the stated motivation of “for webpack”. An option to match node’s experimental behavior seems fine.

From our perspective there are a lot more webpacked react apps which are pulling in dynamic import node when testing with jest as perpetuated in a lot of examples. Is this wrong? If the use case is an implementation issue and there is a peer dependency that needs to be listed maybe doing that and listing it in the README is all this package has to do.

The primary reason somebody would be using a dynamic import is for use with Webpack.

Again, this is false. It’s also useful in node, or with browserify or rollup or other bundlers.

When I use the term primary, I am referring to usage (which I should have specified). If a developer is using a dynamic import, they are most likely using Webpack.

Webpack is currently the primary use case for dynamic imports

I very much dispute this; there are many use cases for it, and webpack is only one of them.