node-sass --watch doesn't work for directories

Created on 6 Mar 2014  Â·  21Comments  Â·  Source: sass/node-sass

I noticed that the --watch command line switch added by #147 isn't documented in README.md, so I was going to fork and add it, but shortly realized that --watch doesn't actually seem to work. A couple issues here:

First of all, I imagine that node-sass --watch should work without specifying an input file, like the SASS Ruby gem. However, it doesn't appear to work that way:

peterjmag@peterjmags-iMac ~/node/node-sass-watch 
$ node-sass --watch scss/
Compile .scss files with node-sass.
Usage: node-sass [options] <input.scss> [<output.css>]

Options:
[...]

Argument check failed: function (argv){
    if (argv.help) { return true; }
    if (argv._.length < 1) { return false; }
  }
peterjmag@peterjmags-iMac ~/node/node-sass-watch 
$ node-sass --watch=scss/
Compile .scss files with node-sass.
Usage: node-sass [options] <input.scss> [<output.css>]

Options:
[...]

Argument check failed: function (argv){
    if (argv.help) { return true; }
    if (argv._.length < 1) { return false; }
  }

If I then add an input file argument (a dummy file for instance, just to satisfy the requirement), I get the following:

peterjmag@peterjmags-iMac ~/node/node-sass-watch 
$ ls scss/
test.scss  test2.scss
peterjmag@peterjmags-iMac ~/node/node-sass-watch 
$ node-sass scss/ --watch=scss/
error reading file "scss/"

peterjmag@peterjmags-iMac ~/node/node-sass-watch 
$ node-sass scss/test.scss --watch=scss/
Rendering Complete, saving .css file...
Wrote CSS to /Users/admin/node/node-sass-watch/test.css
[saved a minor change to test2.scss, which triggers the following]
NaN
Rendering Complete, saving .css file...
Wrote CSS to /Users/admin/node/node-sass-watch/test.css
[saved test2.scss again]
NaN
Rendering Complete, saving .css file...
Wrote CSS to /Users/admin/node/node-sass-watch/test.css

It's also entirely possible that I'm missing something obvious here, so let me know if that's the case. Either way, I'm happy to update the docs once this is resolved! :-)

Bug - Confirmed Community - Help Wanted

Most helpful comment

Use '-r' to recursively watch
node-sass -r --watch scss -o css

All 21 comments

I got a chance to dig into this myself a bit today. As it turns out, --watch works fine for single files, like the following:

peterjmag@peters-imac ~/node/node-sass-watch 
$ node-sass scss/test.scss --watch

However, it didn't work properly for directories (as in my previous comment). I adapted the code to allow for a directory as an argument, and I took a first shot (albeit a bit of a hacky one) at actually rendering the right files inside a watched directory: https://github.com/peterjmag/node-sass/compare/master...cli-watch-directory.

I've updated the issue's title to reflect this.

@arian: Perhaps you can take a look, since you added the watch option in #147?

A few things that would still need to happen here:

  • Check that the given argument is actually a directory (if the watch switch is given). Right now, it pretty much just checks for a string and then fails silently if the directory isn't valid.
  • Adapt the CLI tests: https://github.com/andrew/node-sass/blob/master/test/cli.js
  • Find a more elegant approach to passing around and modifying options within the watch() call (particularly options.inFile and options.outFile).
  • Perform initial render before the watch starts (I imagine this would require the ability to process directories recursively).

Thanks for investigating @peterjmag, a very nice, clearly outlined issue :+1:

I know this issue has been open up a while ago, but I managed to simulate the functionality you would get from coffee --watch, which mirrors the file structure in the output directory. I made it for personal use and it's very hacked together, but I wouldn't mind cleaning it up for others to use. There were a couple things I had to change:

  • argv.d, or the -d option is the output directory. It also affects the input for single files.
  • Removed throttle. Not only was the callback function not firing at all, but unnecessary with this kind of functionality. render() should be called for every relevant file that changes.
  • Removed isSassFile() check. The node-watch documentation had an example for an inline filter function I thought might have been easier to read, plus the function is only going to be used once.
  • argv.w only accepts one directory to watch, not an array. I actually don't see a problem with being able to watch multiple directories, I'll see if I can throw that in.
  • File changes are extended to removed or renamed files.

(As a side note, I accidentally ruined a lot of the formatting due to a bad :retab. Will fix)

That would be great @barkimmadog, are you going to send a pull request?

@andrew I'm still a little new on contributing. I hope I did everything correctly! :)

Do we know if watching is safe in node-sass? It doesn't look like libsass itself is being careful with memory management, so letting it live in a long-running process may not be beneficial. Perhaps someone with more experience can weigh in?

Any news on this? Directory watch support would be really nifty for avoiding Grunt/Gulp etc in simple projects.

(sorry if I sound oblivious..)

I don't know how it works here. But in Web Essentials, for bundle files, we watch each constituent file as well as the bundle file. If anything is touched, it triggers compilation. (even with sprites, if you photoshop one of the constituent images, it regenerates the sprite).

Is this the same mechanism used here?

Any taker for #312?

I'll take a look.

Thanks @kevva :grey_exclamation: :+1:

It still won't work properly for me, so I use nodemon instead:

nodemon /usr/local/bin/node-sass main.scss --include-path="bower_components" -e scss

I also don't think the watch option works as expected. I am using version 3.0.0 of node-sass
this command works fine

./node_modules/.bin/node-sass src/styles/ -o www/styles/

however the same with the --watch or -w flag does not

./node_modules/.bin/node-sass src/styles/ --watch -o www/styles/

I get a no directory error
Error: ENOENT, no such file or directory 'path/to/project/src/styles/**'

@kaelig fixed in v3.1.1

I'm sorry for bringing this up again, but I cannot seem to get it to work. I'm trying to node_modules/node-sass/bin/node-sass assets/scss/main.scss -o static/css/ -w assets/scss/, but get the following output:

Rendering Complete, saving .css file...
Error: EISDIR, open '/vagrant/assets/scss'

I've got the same error as @CrowdHailer.

node-sass       3.4.2   (Wrapper)       [JavaScript]
libsass         3.3.2   (Sass Compiler) [C/C++]

CMD:

node-sass --watch sass/* --output css/

Error:

(function (exports, require, module, __filename, __dirname) { // Copyright Joy

^
Error: ENOENT, no such file or directory 'C:sandboxmanagerappassetsstylessass*'
at Error (native)
at Object.fs.lstatSync (fs.js:792:18)
at Object.module.exports.parseDir (C:UsersuserAppDataRoamingnpmnode_modulesnode-sassnode_modulessass-graphsass-graph.js:145:10)
at watch (C:UsersuserAppDataRoamingnpmnode_modulesnode-sassbinnode-sass:233:21)
at run (C:UsersuserAppDataRoamingnpmnode_modulesnode-sassbinnode-sass:303:5)
at Object. (C:UsersuserAppDataRoamingnpmnode_modulesnode-sassbinnode-sass:383:3)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)

Process finished with exit code 1

sass looks for all files inside current working directory, and rebuild if you @import any changed files to your current file.

structure example
main.scss
folder1/_file1.scss
folder2/file2.scss

main.scss

@import 'folder1/file1';

file2.scss

@import '../main';
sass --watch main.scss:style.css

This command fires if you do change on file1.scss, file2.scss and main.scss of course

sass --watch folder2/file2:../style.css

This command fires only when you save file2.scss and doesn't fire if you save main.scss

I'm actually not sure if watching a partial (file beginning with _) is
valid. However your last example would not work because main.scss is not in
your include path. The default include path is the directory of the file
being compiled (or watched). Try using the --include-path=/path/to/main.scss

On Wed., 28 Mar. 2018, 8:02 am Amro Khaled, notifications@github.com
wrote:

sass looks for all files inside current working directory, and rebuild if
you @import any changed files to your current file.

structure example
main.scss
folder1/_file1.scss
folder2/file2.scss

main.scss

@import 'folder1/file1';

file2.scss

@import '../main';

sass --watch main.scss:style.css

This command fires if you do change on file1.scss, file2.scss and
main.scss of course

sass --watch folder2/file2:../style.css

This command fires only when you save file2.scss and doesn't fire if you
save main.scss

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/sass/node-sass/issues/250#issuecomment-376674289, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAjZWA-Z8pWOsmorVCH7CJ5Vs5UTSngEks5tiqjlgaJpZM4BnZ2j
.

Use '-r' to recursively watch
node-sass -r --watch scss -o css

I'm use this script runner in package.json

"scripts": {
   "scss:tocss": "./node_modules/.bin/node-sass --watch ./src/css/scss --output ./src/css/ "
}

One thing with this, that it work only on change in folder. So to rebuild .css you should save your .scss file.

For first build just run without --watch , like:

./node_modules/.bin/node-sass ./src/css/scss --output ./src/css/

I'm still facing this issue when watching folder from cmd.
This is the error that occurs on entering this command:

node-sass --watch ./myFolder/scss/* --output ./myFolder/css/

fs.js:941
binding.lstat(pathModule._makeLong(path));
^

Error: ENOENT: no such file or directory, lstat 'Z:etcdesignshealthcarecommonframeworkclientlibsthemesNasivinbuynow2scss*'
at Object.fs.lstatSync (fs.js:941:11)
at Object.module.exports.parseDir (C:UserstusshuklAppDataRoamingnpmnode_modulesnode-sassnode_modulessass-graphsass-graph.js:153:10)
at Object.watcher.reset (C:UserstusshuklAppDataRoamingnpmnode_modulesnode-sasslibwatcher.js:17:21)
at watch (C:UserstusshuklAppDataRoamingnpmnode_modulesnode-sassbinnode-sass:260:20)
at run (C:UserstusshuklAppDataRoamingnpmnode_modulesnode-sassbinnode-sass:319:5)
at Object. (C:UserstusshuklAppDataRoamingnpmnode_modulesnode-sassbinnode-sass:405:3)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

samayo picture samayo  Â·  3Comments

nagyfej picture nagyfej  Â·  3Comments

goseesomething picture goseesomething  Â·  3Comments

tjistooshort picture tjistooshort  Â·  4Comments

pulkitnandan picture pulkitnandan  Â·  4Comments