Skip to content

Ng Build doesn't always fill Errors array for the Webpack 'done' hook #13870

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
Usurer opened this issue Mar 11, 2019 · 4 comments
Closed

Ng Build doesn't always fill Errors array for the Webpack 'done' hook #13870

Usurer opened this issue Mar 11, 2019 · 4 comments

Comments

@Usurer
Copy link

Usurer commented Mar 11, 2019

🐞 Bug report

Command (mark with an x)

- [ ] new
- [x] build
- [ ] serve
- [ ] test
- [ ] e2e
- [ ] generate
- [ ] add
- [ ] update
- [ ] lint
- [ ] xi18n
- [ ] run
- [ ] config
- [ ] help
- [ ] version
- [ ] doc

Is this a regression?

No

Description

When using Webpack done hook together with ng build --watch command, the stats object, passed to the hook as a parameter doesn't always have stats.compilation.errors array filled even if there are errors and the build has failed.

Although it could be seen as a minor issue, it makes impossible using of popup build notifiers like the webpack-notifier because these rely on errors presence in the stats object.

🔬 Minimal Reproduction

The sample code could be found at
https://github.com/Usurer/bugreports.NgCliBuildWebpackHooks

  • Create a new Angular app via ng new my-app
  • Create a simple Webpack plugin that would use the done hook:
var MyWebpackPlugin = module.exports = function() {};

MyWebpackPlugin.prototype.compilationDone = function(stats) {
    console.log('Errors:');
    console.info(stats.compilation.errors);
};

MyWebpackPlugin.prototype.apply = function(compiler) {
  if (compiler.hooks) {
    var plugin = { name: 'My Plugin' };

    compiler.hooks.done.tap(plugin, this.compilationDone.bind(this));
  } else {
    compiler.plugin('done', this.compilationDone.bind(this));
  }
};
  • Add custom webpack config by following instructions for ngx-build-plus:

    • run ng add ngx-build-plus

    • add webpack.partial.js to the project root with the following contents:

      const MyWebpackPlugin = require('./myWebpackPlugin');
      module.exports = {
          plugins: [ new MyWebpackPlugin() ]
      }
  • run ng build --watch --extra-webpack-config webpack.partial.js
    Result as expected: no build errors and an empty errors array logged to console.

  • Now open /src/app/app.component.ts and add the following new line to the end of the file: xxx;

  • Check the build console.
    Expected: "Cannot find name xxx" error logged twice - as a part of an error object in an errors array and as a regular build error message.
    Actual: errors array logged as an empty array, "Cannot find name xxx" error is shown in the console as a regular build error message.

  • Now cancel the build --watch. Make sure that you still have an xxx line in the app.component.ts and run ng build --watch --extra-webpack-config webpack.partial.js again.

  • Check the build console.
    Result as expected: "Cannot find name xxx" error logged twice - as a part of an error object in an errors array and as a regular build error message.

  • Remove the xxx line and check the console.
    Result as expected: Errors array is empty, build succeeded.

  • Once again add the xxx line and check the console
    Expected: "Cannot find name xxx" error logged twice - as a part of an error object in an errors array and as a regular build error message.
    Actual: errors array logged as an empty array, "Cannot find name xxx" error is shown in the console as a regular build error message.

🌍 Your Environment



Angular CLI: 7.3.5
Node: 10.13.0
OS: win32 x64
Angular: 7.2.8
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.13.5
@angular-devkit/build-angular     0.13.5
@angular-devkit/build-optimizer   0.13.5
@angular-devkit/build-webpack     0.13.5
@angular-devkit/core              7.3.5
@angular-devkit/schematics        7.3.5
@angular/cli                      7.3.5
@ngtools/webpack                  7.3.5
@schematics/angular               7.3.5
@schematics/update                0.13.5
rxjs                              6.3.3
typescript                        3.2.4
webpack                           4.29.0

@Usurer
Copy link
Author

Usurer commented Mar 13, 2019

As far as I was able to understand right now, the reason is that in watch mode, after the first time compilation was executed, further syntactic errors are emitted by the TypeChecker and aren't passed along the Webpack build pipeline. Still, I have no idea if there's any way to force the compilation and make it throw the same errors. Probably should research a bit more into Webpack itself.

@Usurer
Copy link
Author

Usurer commented Mar 13, 2019

At last, I was able to tweak the behaviour by changing the diagMode during the _emit, see how does it look like in the angular_compiler_plugin:

benchmark_1.time('AngularCompilerPlugin._emit');
const program = this._program;
const allDiagnostics = [];
const diagMode = (this._firstRun || !this._forkTypeChecker) 
    ? gather_diagnostics_1.DiagnosticMode.All 
    : gather_diagnostics_1.DiagnosticMode.Syntactic;

So by keeping the diagMode as All all the time, I'm able to get an error as a compiler error.

It seems that the kind of error, I have in my example isn't syntactic but semantic. I don't really see how does TS compiler differentiate one from another (stupid me), but much more interesting is how do I force it to run in All mode without changing the sources in my node_modules.

@Usurer
Copy link
Author

Usurer commented Mar 13, 2019

It seems that the issue could be solved by adding a forkTypeChecker: false to the angular.json.

Still, I wonder whether we could keep the fork type checker process just pass the results back to the anbular_compiler_plugin and further to the emit diagnostics.

Gonna add a feature request for that.

@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 Sep 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant