webpack: ES6 import implementation does not handle circular dependencies for "default"

Filing since it would be cool if this could be consistent with Babel. The current import logic for default exports does not handle circular dependencies properly. The presence of a ‘default’ properly is not enough to ensure proper functionality, at least with the current export implementation.

For example

// a.js
import b from './b';
export default 'a-default';

// b.js
import a from './a';
export default 'b-default';

// main.js
import './a';

will cause the b.js import to require a.js before it has executed its body, so "default" will not yet exist, and a in b.js will end up being the exports object rather than the default properly.

One option would be to hoist the initial assignment of exports['default'] so a.js is more like

exports['default'] = undefined;
import b from './b';
exports['default'] = 'a-default';

This issue is solved in Babel similarly, but in Babel, a __esModule flag is used instead to also avoid treating ES5 modules that happen to have a ‘default’ property as default exports, where they may not expect to be.

Either way, something needs to be set on the exports object of anything that has ES6 exports, before any of that module’s dependencies are executed. It’d be awesome if we could all standardize on __esModule though.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 51
  • Comments: 28 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Everything behave as specced

Are circular dependencies supported now? To be honest, I didn’t get the consensus to this topic.

Can confirm as of today on beta 27 that circular dependencies are NOT handled correctly @sokra if that is spec’d they may need another once over.

| Everything behave as specced

i was considering using webpack going forward. but this comment changed by mind. thanks for clearing that up for me @sokra

What’s the state of this in webpack 2 beta? I’m experiencing a lot of issues presumably caused by cyclic dependencies on ES6 modules using default exports, so I assume it’s not supported yet?

I implemented a tool to check your webpack build for ES6 (or require) cyclical imports 😃 https://github.com/AndrewRayCode/webpack-cyclic-dependency-checker

@lebed2045 @Spongman I don’t really contribute much on Webpack, but in my experience in OSS, comments on old closed issues are unlikely to elicit responses because there’s barely enough time to keep up with new issues, let alone every comment on every existing issue. I no longer have a horse in this race, but if you’re having issues, filing a new bug with clear reproduction would likely be a better way to get the conversation going again.

Three years later and it still doesn’t work.

Ran into this once I switch on the default module imports now supported in webpack by adding {modules:false} in babel presets options.

Error coming is TypeError: __webpack_require__.i(...) is not a function . webpack_require.i is the identity function and the “function” going in it is imported in de-structured manner having cyclic dependency. It comes out to be undefined and hence the error.

@sokra - Do you need an example or are already aware of this? How best to tackle this? Removing {modules:false} and adding back add-module-exports plugin of babel does solve it - but then tree shaking doesn’t work. Any help appreciated!

Ran into this recently as well. Basically the Redux ducks paradigm is useless because you can’t detect circular imports. Does anyone know a real solution and not a hack one? Is this a webpack bug? If I move back to require instead of imports, will it fix it?

EDIT: fwiw I was able to mostly resolve my issues by moving the usage of the imports into function calls instead of trying to use them immediately.

This silently breaks valid, working code. It should probably be labelled as a bug.

We’ve seen accidental and hard-to-spot circular dependencies using “barrel” index.ts files. This is using AngularJS (not at fault here!), TypeScript 2.0, and Webpack 2.x as imported by Angular-CLI. So there is a tall stack… but it appears to be this same underlying issues.

Hi @gund, see my solution here: https://gist.github.com/gund/fa244bfef5024ebe2aba72d31d565cb0#gistcomment-1957158

(Note, I made a typo, which I mentioned in a following comment)

@thinkingmedia there’s a plugin linked above that can help you identify them out helps a lot

I’m hitting this problem with a deep circular dependency. It’s taken me many hours to even see that it’s a circular problem and an issue with webpack.

I don’t even get a reasonable error message, but just this error message when the app bootstraps.

main.bundle.js:22949 Uncaught TypeError: Cannot read property 'prototype' of undefined
    at __extends (main.bundle.js:22949)
    at main.bundle.js:22966
    at Object.<anonymous> (main.bundle.js:22980)
    at __webpack_require__ (inline.bundle.js:53)
    at Object.<anonymous> (main.bundle.js:14103)
    at __webpack_require__ (inline.bundle.js:53)
    at Object.<anonymous> (main.bundle.js:23073)
    at __webpack_require__ (inline.bundle.js:53)
    at Object.<anonymous> (main.bundle.js:14001)
    at __webpack_require__ (inline.bundle.js:53)

@sokra on latest webpack 2 beta?