Following the discussion of Move forward with warn-as-error by default - #16 by Hongbo, we introduce an enhanced workflow for warnings/errors handling.
Conclusion: we will treat all warnings as non-critical errors (warning numbers are configurable per project or per file), but the build system will not be blocked so that for non-critical errors, it will still type checking your whole projects and lists all your non-critical errors.
Motivation
We would like to improve the error diagnostics for editor integration. Traditionally, the editor relies on Merlin or other tools for error reporting, however, it is not reliable since such third party tools don’t have a global view of the project organization. There’re lots of frustration when the editor reports an error but in real world, the build system tells you everything is okay.
The build system is always correct except one case: warnings.
When the build system do the clean build, it will report warnings faithfully, however, during the second time, since the existing targets are already built, the warnings are completely gone, the build output can not faithfully report those missing warnings.
We need inform the build system when a warning happens to one file and rebuild it again, that’s why we are making the changes: always enforce warn-as-error.
The traditional pitfalls of turning on warning-as-errors
One major drawback of turning on warning-as-error is that it stops immediately without telling your other potential errors.
For example, suppose we have three modules, A, B, and C; the dep graph is B call A and C call B. When A has a non-critical error, the build system stops at compiling A and we don’t know the status of B or C, so we have to actually fix A first to see how it’s going with B or C.
Introduce soft-failure to improve the experience of warning-as-errors
Following the graph above, we would like to the build system to continue checking B and C even if we meet a non critical errors in A.
In this case we call A is a soft-failure, we don’t generate JS files for A, however, we still produce the needed binary artifacts for the build system to check B and C. If there are non critical errors in B, we mark B as a soft failure and continue checking C.
So essentially it will check the whole project like just turn it as warnings, there are some subtle differences:
-
When do a rebuild, those soft-failure will remind the build system to do the recheck of those soft failed modules, so the build system will tell you all the non-critical errors in the project in the rebuild. In the future, the editor can rely on it to do the error diagnostics instead of third party tools.
-
In the end, the build process will fail to ask user to fix those non-critical errors, remember the soft-failure module does not generate js file.
-
It will still be very fast. Suppose we fix the non critical error in A, the build system notice the change in A and regenerate A.js, however if its binary artifacts don’t change, B or C will not rebuild (assume it’s previous build is a success)
Potential breaking changes
Any change to the build system is subtle that it may break something. We made it available for testing your repo now in version bs-platform@8.3.0-dev.1
.
To avoid breaking too many packages, when a package is built as a dependency, internally we mark off all non critical errors, in this case, only a toplevel package can fail due to non-critical errors.
For toplevel packages, we assume the developer own the project, they can choose either fix those warnings immediately or turn those numbers off.
Feedback is appreciated!