Skip to content

feat: support for noEmitOnErrors property in webpack.config #337

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

Merged
merged 3 commits into from
Oct 25, 2019

Conversation

Fatme
Copy link
Contributor

@Fatme Fatme commented Sep 25, 2019

Currently noEmitOnErrors property is not respected from webpack compilation in case it is set in webpack.config.js. As a result, the files are emitted even when there is an error in the source code. However, it turns out that ts-loader is working correctly in transpileOnly: false mode and the problem is only in case when ts-loader is started in transpileOnly: true + ForkTsCheckerWebpackPlugin.

After investigating the issue, it turns out that the problem is here. Webpack has a logic that checks if the files should be emitted based on compilation.errors array. This logic is executed on shouldEmit hook as can be seen here. So, we need to put our reported diagnostics and lints in compilation.errors before shouldEmit.

The afterCompile hook seems as a perfect solution as it is executed before shouldEmit and is an async hook. As supporting this feature is important for our error handling story, we implemented the change, spent a little time testing it and it works for our cases.

However, we're not absolutely sure for the impact of the mentioned change so we'd be glad to hear your opinion and suggestions.

Rel to: #57

@Fatme Fatme mentioned this pull request Sep 25, 2019
Fatme added a commit to NativeScript/nativescript-dev-webpack that referenced this pull request Sep 26, 2019
Webpack doesn't notify NativeScript CLI when there is a compilation error. So, NativeScript CLI build the app, install it on device and start it. In most cases the application crashes runtime as the webpack compilcation is not successful. Most probably there would be a red/yellow message in the console printed during the compilation. The users don't see the error message as there is too much log outputed in the console. They don't understand the exact reason why their app crashes runtime.

Webpack has a mechanism to skip the emitting phase whenever there are errors while compiling. This can be achieved using `optimization.noEmitOnErrors` property as it is described [here](https://webpack.js.org/configuration/optimization/#optimizationnoemitonerrors). This PR adds `noEmitOnErrors` property in all webpack.config files:
* The default value is based on `noEmitOnError` property from `tsconfig.json` for `angular` and `typescript` projects
* The default value is `true` for `javascript` and `vue` projects.

Also this PR fixes the following problems:

1. Check for syntactic errors when running webpack compilation in ts projects

Currently `ts-loader` is started in `transpileOnly` mode and  webpack plugin (`ForkTsCheckerWebpackPlugin`) runs TypeScript type checker on a separate process in order to report for compilation errors. By default the plugin only checks for semantic errors and adds them to `compilation.errors` as can be seen [here](). On the other side, webpack relies on [compilation.errors]() array when deciding if should skip emitting phase. However, `ts-loader` used in `transpileOnly` mode still reports syntactic errors but adds them to `compilation.warnings`. This is a problem, as actually the compilation is not stopped when there is a syntactic error. Setting `checkSyntacticErrors: true` will ensure that `ForkTsCheckerWebpackPlugin` will check for both syntactic and semantic errors and after that will be added to `compilation.errors`.

2. Respect `noEmitOnError` from `tsconfig.json` when compiling in `ts` projects

The problem is in `ForkTsCheckerWebpackPlugin` and in the way it is integrated with webpack hooks - TypeStrong/fork-ts-checker-webpack-plugin#337.

3. Send the hash of compilation to NativeScript CLI

The `hmr` generates new hot-update files on every change and the hash of the next hmr update is written inside hot-update.json file. Although webpack doesn't emit any files, hmr hash is still generated. The hash is generated per compilation no matter if files will be emitted or not. This way, the first successful compilation after fixing the compilation error generates a hash that is not the same as the one expected in the latest emitted hot-update.json file. As a result, the hmr chain is broken and the changes are not applied.

Rel to: NativeScript/nativescript-cli#3785
@piotr-oles
Copy link
Collaborator

piotr-oles commented Oct 13, 2019

Thank you for your findings and for the PR :)
Unfortunately, changing the hook from emit to afterCompile is a breaking change in my opinion. There is a custom hook: fork-ts-checker-emit - and as it's a part of public API, some developers could assume that it will run on the emit event.
Because of that, we need to find a method to deprecate the fork-ts-checker-emit hook and add a new one (fork-ts-checker-after-compile) + keep default behavior of using webpack's emit event (probably we will have to add a new configuration option to control that behavior).

I know that it can be frustrating that we cannot just fix this bug and change the hook, but our responsibility is to introduce breaking changes gracefully :)

@Fatme
Copy link
Contributor Author

Fatme commented Oct 23, 2019

Hey @piotr-oles,

Thank you very much for taking a look at this PR.

but our responsibility is to introduce breaking changes gracefully

I totally agree that we have to ensure seamless transition for the users.

keep default behavior of using webpack's emit event (probably we will have to add a new configuration option to control that behavior)

Yep, maybe introducing a new configuration option is a good solution. Having that option with default value false will ensure the new version of the plugin will not break existing users and applications. So we need a name for the new option 😸 - maybe useAfterCompile or noEmitOnErrors or something else? I'm opened to any ideas and suggestions.

As this PR is really important for us and our error handling story, I'll prepare the needed changes once we have an agreement about the name of the new option.

@piotr-oles
Copy link
Collaborator

I would suggest useAfterCompileHook, @johnnyreilly, what do you think?

@johnnyreilly
Copy link
Member

We could do... I'm just wondering if it might make more sense to do a breaking changes version? After all, do we want to maintain two behaviours in the long term? If we all agree this is a more sensible behaviour then having a breaking changes version seems like a way to not break existing users and move the plugin in the direction we want to go... Thoughts?

@Fatme
Copy link
Contributor Author

Fatme commented Oct 24, 2019

Hey @piotr-oles, @johnnyreilly

It seems we have 2 options:

  • Release a breaking change version of the plugin - If we agree on that, I suppose it'll be released as a major version e.g 2.0.0.
  • Add a configuration option and support the both behaviors.

The both solutions will work for us and will address our problem. However, personally to me, I prefer releasing a major version and introducing it as a breaking change. That will be the most beneficial solution in the long term.

Let me know about your decision, so I can apply the required changes on the PR.

@piotr-oles
Copy link
Collaborator

piotr-oles commented Oct 24, 2019

Ok, maybe breaking change is a better option - it will probably not break anything for 99% of users.

Please update the documentation (Plugin hooks section) and add BREAKING CHANGE section to the commit message :)

@Fatme Fatme force-pushed the fatme/no-emit-on-errors branch from 10273e7 to 83112ba Compare October 24, 2019 11:12
@Fatme
Copy link
Contributor Author

Fatme commented Oct 24, 2019

@piotr-oles,

I changed the commit message with BREAKING CHANGE: footer and updated the plugin section in the documentation.

Let me know if I've missed something or there is something else that I can do.

@johnnyreilly
Copy link
Member

Could you catch up this branch with master please?

@Fatme Fatme force-pushed the fatme/no-emit-on-errors branch from 83112ba to a685243 Compare October 24, 2019 16:58
@Fatme
Copy link
Contributor Author

Fatme commented Oct 24, 2019

@piotr-oles, @johnnyreilly,

I've rebased the PR on the latest master branch.

johnnyreilly
johnnyreilly previously approved these changes Oct 24, 2019
Copy link
Member

@johnnyreilly johnnyreilly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

@Fatme
Copy link
Contributor Author

Fatme commented Oct 24, 2019

@johnnyreilly, @piotr-oles,

It seems there are failing CI builds https://travis-ci.org/TypeStrong/fork-ts-checker-webpack-plugin/jobs/602424646?utm_medium=notification&utm_source=github_status:

error An unexpected error occurred: "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz: Request failed \"503 Service Unavailable\"".
info If you think this is a bug, please open a bug report with the information provided in "/home/travis/build/TypeStrong/fork-ts-checker-webpack-plugin/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
The command "yarn install --frozen-lockfile" failed and exited with 1 during .

Maybe we should rerun the travis builds.

@johnnyreilly
Copy link
Member

Retriggered. Travis has been pretty flaky this week

@Fatme
Copy link
Contributor Author

Fatme commented Oct 25, 2019

@johnnyreilly, @piotr-oles

We have a green build! 🎉

Do I need to rebase it again on master as there are additional commits merged into master or you can merge the PR directly?

@johnnyreilly
Copy link
Member

Yes please - update the branch!

Fatme added 3 commits October 25, 2019 09:04
The afterCompile hook should be blocked instead of emit in order to handle correctly noEmitOnErrors property from webpack.config.js

BREAKING CHANGE: The emit hook is replaced with afterCompile hook.
@piotr-oles piotr-oles merged commit dd410b0 into TypeStrong:master Oct 25, 2019
@Fatme
Copy link
Contributor Author

Fatme commented Oct 25, 2019

@piotr-oles, @johnnyreilly,

Thank you very much for merging the PR!
When do you plan to release it officially?

@piotr-oles
Copy link
Collaborator

It will be released automatically by 📦 🚀 semantic-release when CI build finish :)

@Fatme
Copy link
Contributor Author

Fatme commented Oct 25, 2019

@piotr-oles,

What about the version - will it be updated to 2.0.0 as we're releasing a breaking change?

@piotr-oles
Copy link
Collaborator

🎉 This PR is included in version 2.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@piotr-oles
Copy link
Collaborator

The CI is performing very badly last time - I had to re-run the release job. And yes - as you can see semantic-release do all the magic ✨ 😃

@Fatme
Copy link
Contributor Author

Fatme commented Oct 25, 2019

Yeep, it's really cool magic! 😃

Fatme added a commit to NativeScript/nativescript-dev-webpack that referenced this pull request Oct 25, 2019
We have a limitation that webpack compilation doesn't stop on error in typescript applications. That was due to the issue in fork-ts-checker-webpack-plugin. After merging [the PR that fixes the issue](TypeStrong/fork-ts-checker-webpack-plugin#337) and releasing 2.0.0 version of the plugin, we can update it on our side and that way webpack compilation will stop on syntax/semantic errors within the application.

Rel to: NativeScript/nativescript-cli#3785
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants