Skip to content

@ngtools/webpack: Misleading documentation & Config Refactor Proposal #9063

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
daniel-nagy opened this issue Jan 2, 2018 · 6 comments
Closed
Labels
area: docs Related to the documentation area: @ngtools/webpack
Milestone

Comments

@daniel-nagy
Copy link

daniel-nagy commented Jan 2, 2018

I think the docs for skipCodeGeneration are wrong? According to the docs,

skipCodeGeneration: Optional, defaults to false. Disable code generation and do not refactor the code to bootstrap. This replaces templateUrl: "string" with template: require("string") (and similar for styles) to allow for webpack to properly link the resources.

However, rewriting the Urls seems to be the responsibility of the @ngtools/webpack loader, which can be used standalone without the AngularCompiler as long as a tsConfigPath is specified.

const ngToolsLoader = {
  loader: '@ngtools/webpack',
  options: {
    tsConfigPath: TS_CONFIG_FILE
  }
};

So it seems to me the @ngtools/webpack loader is equivalent to a typescript compiler plus the ability to rewrite templateUrl and syleUrls.

This brings me to 2 things,

  1. In development it makes more sense to use the JIT compiler. Is there any reason you would want to use the compiler plugin in development with skipCodeGeneration set to true as opposed to just not using the plugin at all?

  2. If the @ngtools/webpack loader is responsible for compiling the typescript then I think any options that affect the typescript compilation process should be moved to the loader. For example, if I am only using the loader in development then there is no way for me to enable type checking unless I also include the plugin and set typeChecking to true in the plugin options.

I believe it is good to use the same loaders for development and production builds because different loaders may behave slightly different. For example, I could use the ts-loader and the angular2-template-loader in development and not use the @ngtools/webpack loader at all but the angular2-template-loader is able to resolve files without a file extension (maybe using Webpack resolve config?) where as the @ngtools/webpack will fail without the file extension. All of a sudden when you build for production you will get an error like

Couldn't resolve resource foo.template from C:/path/to/project/app/components/foo/foo.component.ts

You can probably imagine how confusing this might be.

Also, I think the docs should mention that the generated code is held in memory along side the source code because this is something that could easily trip up people trying to use the plugin. It might also be good to include an option to write the generated factories to disk somewhere for debugging purposes.

One last thing, thank you to everyone working on these Webpack integrations!

@filipesilva
Copy link
Contributor

It is true that the loader can be used alone, but that is more an artifact of backwards compatibility than a feature. It was there in the early versions, we don't use it, but didn't remove it prior to 1.x. It is not a feature we plan on developing further either as it is a very limited form of TS compilation.

Functionality wise the loader is meant to communicate with the plugin. The plugin is the one doing the real full-features compilation. The loader waits for the plugin to perform TS compilation, and retrieves the artifacts. The two are needed due to the overall Webpack architecture.

There are code transformations performed by the plugin in both JIT and AOT so it is needed due to that. Type checking overall also needs the plugin. We don't intend the loader to be used with other plugins, or other loaders to work with the plugin.

Regarding the code being held in memory, that is generally true of any webpack based setup. The only setups that save artifacts on disk are the ones that cache the intermediate webpack format, which isn't overall usable outside webpack. For that reason I don't think it's really worth mentioning that the artifacts are held in memory.

There is a request to keep the generated code around somewhere for debugging purposes though: #6203.

I hope that answers your questions.

@daniel-nagy
Copy link
Author

@filipesilva thank you for the explanation. Are there other code transformations performed by the compiler in JIT other than replacing templateUrl and styleUrls with require statements? In other words, is there anything different between using the loader and the plugin with skipCodeGeneration set to true opposed to just using a typescript compiler and some other tool to replace the templateUrl and styleUrls?

What tripped me up about the code being generated in memory is the compiler ignores the genDir option. I also didn't know that the plugin will automatically use platformBrowser and the generated factory file for AOT compilation. So I had code like

if (PRODUCTION) {
  const AppModuleFactory = require('path/to/genDirOption/app.module.factory');
  const platformBrowser = require('@angular/platform-browser');
  
  platformBrowser().bootstrapModule(AppModuleFactory);
}

I think it is worth mentioning these things, even just briefly, in the docs.

@daniel-nagy
Copy link
Author

I noticed the typeChecking option is not available for the AngularCompilerPlugin. Is there a way to disable type-checking with the AngularCompilerPlugin or are there plans to add a way to disable type-checking?

@filipesilva
Copy link
Contributor

We have a couple of code transformations that we apply according to the platform and JIT/AOT mode. You can find

It's mostly resource replacement, bootstrap replacement, decorator removal, and exporting extra stuff. But it's still a fair number of things.

On the topic of the typeChecking option, there is no way to disable it with AngularCompilerPlugin, nor do we intend to add it. AngularCompilerPlugin is meant to be full featured and overall it doesn't make sense to disable type checking for it. Some of the code transforms need type checking, for instance. But it forks the type checker to a different process to speed up things. For usecases where one wants a simple TS transpiler without type checking I think you're better served with ts-loader or awesome-typescript-loader.

Regarding genDir, I think that option doesn't exist anymore in the Angular 5 compiler and up. But you're not the first to get tripped up by the bootstrap replacement, so I agree that it's worth mentioning. Let me reopen the issue to track that.

Would you be interested in making a PR that mentions how the bootstrap is replaced? There are two places I think should contain this information and mostly in the same form:

@alan-agius4
Copy link
Collaborator

Thanks for reporting this issue. This issue is now obsolete due to changes in the recent releases. Please update to the most recent Angular CLI version.

If the problem persists after upgrading, please open a new issue, provide a simple repository reproducing the problem, and describe the difference between the expected and current behavior.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jun 23, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: docs Related to the documentation area: @ngtools/webpack
Projects
None yet
Development

No branches or pull requests

4 participants