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.tsapp.module.ts imports second.module.ts.app.module.ts's module record* has the AppModule symbol, but as no code can run until the imports 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.tsimportsapp.module.tsapp.module.tsimportssecond.module.ts.app.module.ts's module record* has theAppModulesymbol, but as no code can run until theimports finish running, it'sundefinedfor now.second.module.tsimportsapp.module.ts.This is ok, and
second.module.tsreceivesapp.module.ts's module record, butapp.module.tshas not yet finished initializing. As it's already initializing,second.module.tshas to execute first.second.module.tsthen tries, immediately, to read the uninitialized value from the module record, which will beundefined.A workaround could be to delay the execution of
new AppModuleuntilapp.module.tshas 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.