metalz
metalz

Reputation: 11

watch SASS/SCSS and nodemon together

I want to run Nodemon and node-sass watcher together.

I tried following script on the package.json file.

"build-css": "node-sass --include-path scss scss/main.scss public/css/main.css",
"watch-css": "nodemon -e scss -x \"npm run build-css & nodemon server.js\""

and devDependencies are:

"devDependencies": {
    "node-sass": "^4.9.0",
    "nodemon": "^1.17.5"
},

It does work, but my question is if I don't add & nodemon server.js in the watch-css script, it doesn't run the server and web app.

Is there any good solution for that?

Thanks.

Upvotes: 1

Views: 4060

Answers (3)

package.js
-e is list of extensions
https://www.npmjs.com/package/nodemon

"scripts": {
  "start": "nodemon app.js -e js,scss,pug"
},

app.js
https://www.npmjs.com/package/node-sass

var result = sass.renderSync({
  file: scss_filename,
  [, options..]
});

Upvotes: 4

metalz
metalz

Reputation: 11

Thank you very much for your help. I followed your instruction. I got the concept from that and applied as follows that worked for me:

buildcss.js (at root):

const sass = require('node-sass');
const fs = require('fs');
const path = require('path');

var path_style = path.resolve(__dirname, "scss")
var path_dist = path.resolve(__dirname, "public")

sass.render({file: path.join(path_style, '/main.scss')}, function (err, results) {
    if(err){
        console.log(err);
    }
    fs.writeFile(path.join(path_dist, '/css/main.css'), results.css, function (err) {
        console.log(err);
    });
   console.log('scss --> css completed.');
});

ecosystem.json(at root):

{
  "apps" : [
    {
      "name": "My App",
      "script": "app.js",
      "watch": ["app.js"]
    },
    {
      "name": "SCSS to CSS",
      "script": "buildcss.js",
      "watch": ["./scss/main.scss"]
    }
  ]
}

And package.json:

  "scripts": {
    "start": "pm2 start ecosystem.json && pm2 logs --out"
  },

According to your code on package.json, "start": "pm2 logs && pm2 reload ecosystem.json && pm2 logs --out", that did not work for me. I experienced the following error:

[TAILING] Tailing last 15 lines for [all] processes (change the value with --lines option)
[PM2][ERROR] No file to stream for app [all], exiting.npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `pm2 logs && pm2 reload ecosystem.json && pm2 logs --out`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

From log file:

12 info lifecycle [email protected]~start: Failed to exec start script

Upvotes: 0

ippi
ippi

Reputation: 10177

Ok I got so much now I'll make it an answer instead, but I think the question is very open ended! I think you have to change things up depending on requirements anyway. Basically if it works then don't worry about it.

There are various solutions, like npm-run-all or concurrently but I think a third script like "run-both": "npm run build-css & npm run watch-css" is fine in most cases if you keep in mind the & is not cross-platform or even cross-shell (like windows cmd vs powershell). So I'd say if you work in a team it'll probably be easier to just add another dev-dependency.

But I'll toot a horn for pm2 which I think works great in both production and development. The ecosystem-files are particularly useful. I also think pm2 replaces nodemon completely. Not that nodemon is bad, but pm2 is great for multiple processes. Here are some of my npm scripts:

"winsrv": "pm2 flush & pm2 reload server/ecosystem-win.json & pm2 logs", 
"winprod": "webpack --config ./webpack.config.js & npm run winsrv",
"windev": "set NODE_ENV=development webpack --config webpack.dev.config.js"

And as a last thing I'll add that the post/pre hooks in npm scripts are plenty useful. Run one command for three scripts:

"preprod": "./preprod.sh", // Makes backup of old files, changes symlink to the backup
"prod": "webpack --config ./webpack.config.js && pm2 flush && pm2 reload server/ecosystem-production.json",
"postprod": "./postprod.sh", // check files exist and relinks public to the new build

Sorry for the delay, I got distracted and hit some snags.

I decided to try node-sass programmatic api, I'm not sure how smart that was, but I learned a thing or two.

buildcss.js:

var sass = require("node-sass");
var fs = require("fs");
sass.render({file: "styles.scss"}, (err, results) => {
  if (err) { console.log(err); }
  fs.writeFile("styles.css", results.css, err => console.log);
  console.log('scss -> css complete!');
});

Fake server.js

console.log("server.js...");
setInterval(function() {
  console.log("interval that prevents our so called server from exiting" );
}, 1000 * 60 * 60);

ecosystem.json (restarts the scss-script on change. hmm...)

{
  "apps": [
    {
      "name": "My Server",
      "script": "server.js",
      "watch" : ["server.js"]
    },
    {
      "name": "SCSS to CSS",
      "script": "buildcss.js",
      "watch": ["styles.scss"],
      "autorestart": false
    }
  ]
}

And package.json

...
"scripts": {
    "start": "pm2 logs && pm2 reload ecosystem.json && pm2 logs --out"
},

npm start

And I'd like to add that I usually handle my scss-compiling through webpack and can't really speak for the process used here (but it seems to work well enough!).

Upvotes: 0

Related Questions