-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Fix watching of CSS files to avoid infinite build cycle #1925
Conversation
Previously when the src and dest dirs were the same, whenever a CSS file changed (either manually or as the result of a build) it was recursively recompiled in an infinite loop, unless a build finished in less than 500ms (Gaze's default file watching debounce). Now, when the input and output dirs are the same, CSS files are treated like includes (files starting with an underscore) in that they are never built into CSS, but they are watched in case they are included in a Sass file. When the input and output dirs differ, functionality is unchanged.
4f013b8
to
487c885
Compare
I appreciate you taking the time, however we cannot accept this change. This is a significant breaking change for node-sass users. Additionally causes node-sass to differ from other LibSass bindings i.e. sassc, libsass-python, perl-sass etc.. This behaviour is due to a known bug in LibSass. The bug, although easy to fix, cannot be patched because it would unnecessarily disrupt the community. Sass 4 will introduce first class modules that will allow us to support importing of CSS files in an official way. For now our advice for now is to not use the same directory for input and output. Alternative explicitly add a |
Thanks for taking the time to look at this. I wonder though whether I may not have explained the changes clearly, as I do not believe this is a breaking change. I tried to track down the bug you mentioned, but I'm not sure I found it. Perhaps sass/libsass#2096, or #1758? In this PR, the behavior of watching CSS files remains unchanged. They must be watched because they can be included into Sass files. The only thing this changes is that when watching files, if the input dir is the same as the output dir, CSS files will not be built on top of themselves recursively. They'll still be watched, and can be included into other files. They become more like |
@xzyfer Is this documented anywhere? This is a very surprising issue that is very hard to search for, e.g. these people over at |
AFAIK, the current best workaround for this issue is to use node-sass-chokidar. |
Cherry-picked from sass#1925. Fixes sass#1916 Spec sass/sass-spec#732
Previously when the src and dest dirs were the same, whenever a CSS file changed (either manually or as the result of a build) it was recursively recompiled in an infinite loop, unless a build finished in less than
500ms (Gaze's default file watching debounce). Now, when the input and output dirs are the same, CSS files are treated like includes (files starting with an underscore) in that they are never built into CSS, but
they are watched in case they are included in a Sass file.
When the input and output dirs differ, functionality is unchanged.
I'm not sure the best way to go about writing tests for this. The infinite cycle only starts when builds takes longer than Gaze's default debounce timeout of 500ms (which is happening in a project I'm working on). A small logic bug in Gaze (incorrect operator short-circuiting) prevents setting the timeout to 0 (poking into
node_modules
is how I demonstrated this issue while testing my changes). The one symptom you could test for is that if you modify a CSS file node-sass will process it and reformat it.Currently, for reasons unknown to me, all the watch tests are being skipped (except the check that node-sass doesn't immediately exit). This causes me think the authors have been unable to get the watch tests passing. As someone unfamiliar with the project I would most likely be unable to get watch tests passing either.
This is related to #1758 (Inconsistent behavior when using directory input with --watch and without --watch). It would make the most sense to not compile CSS files at all (or at least make it consistent with and without --watch). As, @xzyfer points out though, changing it now could break builds that rely on node-sass compiling CSS files to another directory. However, this change only affects the scenario where the input directory is the same as the output directory, and therefore should not cause a problem.