3

Has anyone ever gotten a lazy-loaded module to work using Webpack2 for a bundler? I feel like I'm going crazy.

I'm using Visual Studio Code to compile my TS files into JS files before bundling them with Webpack2.

I've tried following simple examples showing lazy loading of modules with angular2 routing, e.g.:

{ path: 'feature', loadChildren: './+feature/feature.module#FeatureModule' }

This flat out doesn't work. I've tried every combination of tricks I can think of, including:

  • Every permutation of ./, /, just '+feature', and so on
  • Creating a bundle called 'feature-module' (via the entry in my webpack config) and tried permutations on that

These always result in a blanket "module not found" error in the console when the feature route is activated.

I've tried a hack I dug up on github which requires using some very questionable syntax, e.g.:

{ path: 'feature', loadChildren: ()=> new Promise(resolve => (require as any).ensure([], require => resolve(require('./+feature/feature.module).FeatureModule))) }

This does actually work, in the sense that it will load the module when the route is requested and render it in the browser as expected.

However the primary reason I wanted to use webpack is for hot reloading.

I'm using an express server in place of the webpack-dev-server (e.g., I'm using webpack-dev-middleware and webpack-hot-middleware in express). I don't know that this matters, but I thought I'd mention it.

The result I get using the lambda forChildren hack is that while the page does render the first time, when I make subsequent changes to it and save, I observe that my webpack bundles are recreated (correct - this is the hot behavior I am looking for). The lambda executes a second time to reload the module (also correct, I assume - though it's impossible to tell because Angular's internals are a maze of sewer pipes). This should I assume have the effect of reloading the module (or more aptly, hooking into the webpack HMR runtime that is handling these requests in the browser)... but instead it fails with a "Duplicate module registered" error.

When I don't use lazy loading, everything works totally as expected. My feature modules load when their routes are hit, my feature's subcomponents all work as designed and if I modify any of my components, whether in the top level module or any of feature modules or their components webpack does exactly what I expect and updates the HTML (or css, or script, or whatever it's hot reloading thanks to my change).

I've seen a few examples that claim to work, but they all in some way differ slightly, for example:

  • instead of precompiling TS files, they use TS loaders in webpack (why would you ever do this?)
  • They are using the webpack-dev-server (not sure if this matters?)
  • They are doing lazy loading, but not using webpack
  • Their examples are from RC-n or beta-N which don't resemble current angular2
  • It's @angularClass. Not to cast shade but their github "boiler plate" is not what I'd call 'minimal'.
  • Their examples are just out-of-context single line snippets (like what I've provided so far, I know).

I guess I'm just hoping someone out there has an example of a scenario resembling mine in a github repo somewhere they can point me at that I can study and try to replicate. This is the most frustrating technical issue I have ever dealt with in my entire professional career (about 12 years).

Aluan Haddad
  • 29,886
  • 8
  • 72
  • 84
Evan Machusak
  • 694
  • 4
  • 9
  • @Claies that is not strictly true but AOT is an awful thing nevertheless – Aluan Haddad Apr 08 '17 at 12:41
  • "It's @angularClass. Not to cast shade but their github "boiler plate" is not what I'd call 'minimal'." yeah, thanks for noticing, sometimes I think I'm the only one who notices how bloated their crap is. – Aluan Haddad Apr 08 '17 at 12:42
  • @AluanHaddad I don't get why anyone would *not* use AOT. If I don't compile ahead of time, I lose the compile-time benefits of TypeScript. If I am using an IDE that compiles my code as I work, why would I want webpack to then compile my TypeScript again every time a resource is requested, when I *already* have the JavaScript there? – Evan Machusak Apr 08 '17 at 19:08
  • I'm sorry but your reply implies that you have no idea what any of these things are at all. You don't know what AOT is (since it has nothing to do with type checking), you don't know what TypeScript is and how its type checking works (since is has nothing to do with Angular and thus cannot depend on AOT), and you don't understand what Webpack is. Simply is too many misconceptions for me explain away so, I hope someone will come along and do that for you because you are incredibly misinformed. – Aluan Haddad Apr 08 '17 at 21:20
  • 1
    So I should have clarified as I'm not using full-blown Angular AOT here. I'm simply pre-compiling the TypeScript and therefore am not using any of the Webpack TypeScript loaders. I am still learning how to speak Angular (as in the English, not the framework). There's really no reason to be rude here. I'm trying to learn. – Evan Machusak Apr 09 '17 at 00:51
  • I am sorry for being rude. In the Angular world, a world that, as hint at, is full of complicated and confusing terminology, AOT is very complex and means something very specific. Sometimes I think Angular terminology is designed to confuse people.... Anyway, what you are describing is not AOT it's just standard use of the TypeScript compiler without using loader or packager plugins. There's nothing wrong with that at all. I truly am sorry – Aluan Haddad Apr 09 '17 at 01:04
  • 1
    No worries mate. – Evan Machusak Apr 09 '17 at 01:08
  • I took the liberty of changing aot to precompilation. I also retagged it with webpack HMR – Aluan Haddad Apr 09 '17 at 01:55

0 Answers0