29

So I'm running tasks in npm package scripts but I want to pass the watch option in npm start.

This works:

"scripts": {
  "scss": "node-sass src/style.scss dist/style.css -w"
}

This doesn't compile, watch, or throw any error:

"scripts": {
  "scss": "node-sass src/style.scss dist/style.css",
  "start": "parallelshell \"npm run scss -- -w\""
}

Doesn't work without parallelshell either or without shorthand.

I assume the problem is the run-script is passing the extra argument in quotes, so the command comes out like:

node-sass src/style.scss dist/style.css "-w"

I'd like this to work without adding any dependencies. What am I missing?

Btw, I'm in Windows 10 with command prompt/git bash.

Ryan Metin
  • 899
  • 2
  • 8
  • 22
  • Please consider my answer( [how-can-i-get-node-sass-watch-and-live-reload-to-work-from-a-single-npm-script](https://stackoverflow.com/questions/34350417/how-can-i-get-node-sass-watch-and-live-reload-to-work-from-a-single-npm-script/45183762#45183762)) on this one! – Evgeny Bobkin Jul 19 '17 at 07:35
  • if you use vcode , I prefer to use extention watching sass live-server it's very useful way – ALI ATTALAOUI Apr 25 '20 at 09:35

7 Answers7

37

This is my setup for css building

"scripts": {
  "css": "node-sass src/style.scss -o dist",
  "css:watch": "npm run css && node-sass src/style.scss -wo dist"
},
"devDependencies": {
  "node-sass": "^3.4.2"
}

The -o flag sets the directory to output the css. I have a non-watching version "css" because the watching version "css:watch" ~doesn't build as soon as it's run~, it only runs on change, so I call

npm run css 

before calling

node-sass src/style.scss -wo dist

If you only want it to run on change, and not when first run, just use

"css:watch": "node-sass src/style.scss -wo dist"
Ryan White
  • 2,366
  • 1
  • 22
  • 34
  • Is there not a way to escape the double quotes it passes though? Like I said, this works: `node-sass src/style.scss dist/style.css -w` This doesn't: `node-sass src/style.scss dist/style.css "-w"` Thanks for the tips though. I'll use them for now. – Ryan Metin Jan 14 '16 at 20:31
  • You can escape the double quote using backslash. Like: \"-w\", this way the double quotes don't make the JSON invalid, but they show up when you are running the command in the terminal – Ryan White Jan 14 '16 at 20:35
  • I got that. I meant so that `npm run scss -- -w` doesn't pass `node-sass src/style.css dist/style.scss "-w"`. – Ryan Metin Jan 14 '16 at 20:54
  • Wait... nevermind. I'm an idiot. Don't know why I thought changes weren't doing anything before. Thanks for the help. – Ryan Metin Jan 14 '16 at 21:13
35

Building on the previous answers, another option is to leverage NPM's custom script arguments to remain DRY by not repeating the build script arguments in the watch script:

"scripts": {
  "build:sass": "node-sass -r --output-style compressed src/style.scss -o dist",
  "watch:sass": "npm run build:sass && npm run build:sass -- -w"
}

In the above example, the watch:sass script works as follows:

  1. Run the build:sass script. This will compile your CSS.
  2. Run the build:sass script again, but this time include the -w flag. This will compile your CSS when one of your SASS file changes.

Notice the -- option used at the end of the watch:sass script. This is used to pass custom arguments when executing a script. From the docs:

As of npm@2.0.0, you can use custom arguments when executing scripts. The special option -- is used by getopt to delimit the end of the options. npm will pass all the arguments after the -- directly to your script.

John Hildenbiddle
  • 3,115
  • 2
  • 19
  • 14
  • Dude, that's golden, thank you. FYI, for other node-sass options: https://www.npmjs.com/package/node-sass#command-line-interface – Nicholas Petersen Nov 12 '18 at 20:20
  • warning From Yarn 1.0 onwards, scripts don't require "--" for options to be forwarded. In a future version, any explicit "--" will be forwarded as-is to the scripts. the script should be updated as `"watch:sass": "npm run build:sass && npm run build:sass -w"` – Chukwuemeka Ihedoro Jun 18 '19 at 02:04
1

Btw, here's my change:

"scss": "node-sass src/style.scss dist/style.css",
"start": "parallelshell \"npm run scss && npm run scss -- -w\"

Edit: Change was asynchronous script runs, for the initial compile and then with the watch flag.

Ryan Metin
  • 899
  • 2
  • 8
  • 22
  • I had to change the second line to this for the watcher to work (parallelshell 2.0): `"start": "parallelshell \"npm run scss\" \"npm run scss -- -w\""` – Rocco Jan 20 '16 at 11:00
  • Huh, I've got 2.0 as well. What if you run the tasks in sync, like: `npm run scss & npm run scss -- -w`. Works either way on my end.. – Ryan Metin Jan 20 '16 at 16:21
  • not for me - watcher did not actually remain in "watch" mode, so I stuck to parallelshell docs. Also meanwhile I created a "prewatch" task: `"prewatch": "npm run scss"` – Rocco Jan 20 '16 at 21:11
  • 1
    Could you edit and explain the answer? 'Here's my change' is pretty vague. What's parallelshell? – mikemaccana Jun 08 '18 at 18:31
1

package.json:

"scripts": {
"compile:sass": "node-sass ./styles.scss ./styles.css -w}

npm run compile:sass

note if you run this command the styles does'nt get updated into css file immediately, only if it detects changes in the sass file it updates your css file, not on the initial run.

Battle_Bee
  • 11
  • 2
0

Simplest in my opinion, for a smaller quick project, is just open a new bash window and paste:

node-sass src/ -wo dist
Jujhar Singh
  • 129
  • 6
0

If you want to watch and compile changes automatically when you save that changes in your .scss file , you can use this solution:

"scripts": {
  "watch:sass": "node-sass -w path/to/your/scss --output-style compressed", 
  // example  :  node-sass -w public/styles/scss/bootstrap.scss public/styles/style.css --output-style compressed
}
vsync
  • 118,978
  • 58
  • 307
  • 400
Mile Mijatović
  • 2,948
  • 2
  • 22
  • 41
0

I had issues because node-sass is deprecated (plus, depends on node-gyp, python, vs build tools, etc.)

I used this package.json

  "scripts": {
    "css": "sass styles/scss/styles.scss:styles/css/styles.css",
    "css:watch": "sass --watch styles/scss/styles.scss:styles/css/styles.css"
  },
  "devDependencies": {
    "sass": "^1.57.1"
  },

Please remember changing your source and destination folders.