I'm submitting a bug report
Webpack version:
The code example is at 1.12.13
but it was tested also at 2.1.0-beta.22
Please tell us about your environment:
Linux
Current behavior:
Getting undefined
when trying to load cyclic es6 module dependencies
Expected/desired behavior:
Should not get undefined
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem along with a gist/jsbin of your webpack configuration.
I've made a simple example app to reproduce the issue -
http://www.webpackbin.com/4ksvPx06W
On the file second.module.ts
, line no. 3 demonstrates the problem -
bin.log('CHECK ' + AppModule);
(make sure the "log window" of webpackbin is opened)
bin.log
is like console.log
for webpackbin.
You can also download the project and test it locally.
If you do, it auto removes the bin.log
line.
So in second.module.ts
just add the following line to see the same problem -
console.log('CHECK ' + AppModule);
Browser:
Chrome
Language:
TypeScript both 2.0.2 and 1.8.7
That is correct behavior.
main.ts
imports app.module.ts
app.module.ts
imports second.module.ts
.app.module.ts
's module record* has the AppModule
symbol, but as no code can run until the import
s finish running, it's undefined
for now.
second.module.ts
imports app.module.ts
.This is ok, and second.module.ts
receives app.module.ts
's module record, but app.module.ts
has not yet finished initializing. As it's already initializing, second.module.ts
has to execute first.
second.module.ts
then tries, immediately, to read the uninitialized value from the module record, which will be undefined
.
A workaround could be to delay the execution of new AppModule
until app.module.ts
has finished initializing; like wrapping the code that circularly depends on it on a Promise.resolve().then
:
import { AppModule } from './app.module.ts';
Promise.resolve().then(() => {
bin.log('CHECK ' + AppModule);
let appModule = new AppModule();
});
export const Test = 'test';
*: webpack doesn't actually use "module record"s internally, but the observable behavior is roughly equivalent.
Working as specced
Thanks @Kovensky
The original issue I had was with trying to use Angular's upgrade adapter, which actually uses a delay mechanism like you suggested.
I ran into this undefined
situation with webpack but not with systemjs,
and I thought I could simulate it using a simple example but apparently not 馃槃
I'll create an example with the delay to demonstrate the real app I have, and the unexpected behavior.
Thanks for the help and the answer!
Most helpful comment
That is correct behavior.
main.ts
importsapp.module.ts
app.module.ts
importssecond.module.ts
.app.module.ts
's module record* has theAppModule
symbol, but as no code can run until theimport
s finish running, it'sundefined
for now.second.module.ts
importsapp.module.ts
.This is ok, and
second.module.ts
receivesapp.module.ts
's module record, butapp.module.ts
has not yet finished initializing. As it's already initializing,second.module.ts
has to execute first.second.module.ts
then tries, immediately, to read the uninitialized value from the module record, which will beundefined
.A workaround could be to delay the execution of
new AppModule
untilapp.module.ts
has finished initializing; like wrapping the code that circularly depends on it on aPromise.resolve().then
:*: webpack doesn't actually use "module record"s internally, but the observable behavior is roughly equivalent.