IAMtheIAM / angular-webpack-nodejs-starter

Starter project featuring Angular 4+, (with AOT compilation), TypeScript, Webpack 3 (with Tree Shaking, Hot Module Replacement, and SASS), Debugging Webpack Build, Debugging Angular Application, and Gzip Compression of assets. Integrated with a NodeJS webserver backend with example API routes.
36 stars 5 forks source link

AoT with Webpack loader #4

Closed unsafecode closed 7 years ago

unsafecode commented 7 years ago

Is there a way to make ngc use not files on disk, but rather output processed from Webpack loaders?

My issue is, beyond Sass styles, I need a pre-processing step for my .html templates, which is done through a simple custom loader. AFAIK, there is now way so far to do that, but to emit all those files on disk as well (which would be highly problematic in my case).

IAMtheIAM commented 7 years ago

From what I know, AOT build is not yet setup to read from webpack memory. Although that is a curious idea. Can you explain in more detail what the output of your loaders looks like? There might be a way to get them to output your custom loader files to disk in a way that is compatible with NGC.

unsafecode commented 7 years ago

To put it shortly, I have Handlebars views, developed from one team, that need to pass through a "refactoring" process to become Angular2 templates for the second one.

That is performed by a custom loader by means of an associated, per file configuration. The output is then inlined in place of the original view, by angular2-template-parser.

Since we have lots of templates, I would like to integrate AoT as part of the build. Otherwise, in order to run this step before ngc, I would need to put it outside Webpack, which would come with many disadvantages.

IAMtheIAM commented 7 years ago

I did some more research and I think I found a solution for you. I recommend to take advantage of webpack-shell-plugin which allows you to run command line scripts either before or after a webpack build.

Since you need to run webpack build with custom loader, then ngc, then main webpack build, you could do it like this:

  1. Remove the custom loader from your main webpack build, this will now become 2nd webpack build. Rename to webpack.main.js (or whatever you want)
  2. Create a new webpack config called webpack.handlebars.config (or whatever you want) and program the config to run your special handlebars loaders, and entry point to bootstrap file using JIT mode (one that uses bootstrapModule(AppModule) rather than AOT mode bootstrapModuleFactory(AppModuleNgFactory). This will output your transformed handlebars files which will be ready for ngc to compile.
  3. Now in your main webpack build, install the webpack-shell-plugin here, and make the shell plugin run beforeBuild and run command ngc -p ./tsconfig.aot.json (or whatever your AOT tsconfig is named) which looks at the folder where the compiled handlebars templates were made by 1st webpack build.
  4. Also in your main webpack config, tell webpack to look the entry point for your AOT bootstrap file, which uses bootstrapModuleFactory(AppModuleNgFactory). Make sure you import the AppModuleNgFactory in your AOT bootstrap file.
  5. Finally, use npm scripts in package.json to execute this chained sequence of build events, doing 1st webpack build followed by 2nd webpack build. Something like webpack --config webpack.handlebars.js && webpack --config webpack.main.js. Or you can do in gulp/grunt if you prefer.

That should accomplish what you want. Essentially you need 2 webpack builds, 1st does transformation of your handlebars templates using JIT bootstrap file. 2nd has webpack-shell-plugin which runs ngc "beforeBuild" on the output templates of the 1st webpack build, and then finally compiles the main AOT entry point using the files output from ngc, the .component.ngfactory.ts files .

I hope that makes sense. Let me know how it goes. If you post a link to your code in a github repo, I can try to see if I can make it work to help you out.

unsafecode commented 7 years ago

@IAMtheIAM Thanks for your response, it's very complete!

In the meanwhile, I discovered and tried out @ngtools/wepack, which actually can skip the intermediate compilation (step 1 in your proposal), and integrate directly in a regular webpack build.

IAMtheIAM commented 7 years ago

Very cool, glad you got it working. I'll check out the @ngtools/webpack - seems very useful. Can we make the thread as closed now?