lalexa
lalexa

Reputation: 453

How to create multiple output files with npm scripts?

I am trying npm scripts instead of gulp. And I've ran into the issue, could I have one npm script, for example, to compile scss files with node-sass for development and for prod or should I have multiple scripts for that purposes:

here is my package.json:

...

"scripts": {
    "scss": "node-sass app/src/styles/main.scss --output app/.tmp/styles/",
    "autoprefixer": "postcss -u autoprefixer -r app/.tpm/styles/*",
    "scss:prod": "node-sass app/src/styles/main.scss --output app/dist/styles/",
    "autoprefixer:prod": "postcss -u autoprefixer -r app/dist/styles/*",
    "cssnano": "postcss -u cssnano -r app/dist/styles/main.css",
    "build:styles": "npm run scss:prod && npm run autoprefixer:prod && npm run cssnano"
},

Is it possible to split my scss task into single script with multiple outputs for dev and prod folders?

Upvotes: 1

Views: 3866

Answers (1)

RobC
RobC

Reputation: 24952

short answer: It's best to use multiple scripts for that purpose


For example:

...
"scss:dev": "node-sass app/src/styles/main.scss --output app/dev/styles/"
"scss:prod": "node-sass app/src/styles/main.scss --output app/dist/styles/"
...

(Note the only difference is to the output/destination path)

Then consider grouping all the styles related tasks as dev or prod. For example:

...
"build-styles:prod": "npm run scss:prod && ..."
"build-styles:dev": "npm run scss:dev && ..."
...

You can also aim to have one script for dev and one for build that does all the tasks, i.e. those in addition to just handling the styles related tasks. For example:

...
"dev": "build-styles:dev && ..." 
"build": "build-styles:prod && ..."
...

Then you can simply run either $ npm run dev or $ npm run build via your CLI as necessary and all the tasks are carried out.

Note: You will find that sometimes a script name does not need to be distinguished with either a :prod or :dev suffix as one script can serve either purpose (both dev or build). However, typically when output/destination paths differ then consider prefixing with either :dev or :prod as necessary.


Why ?

Yes, admittedly it's rather verbose and not particularly DRY, yet it's easier for humans to read and maintain. IMO "easier to read" and better maintainability wins every time.

Besides, you may find that sometimes it's not only the output/destination path that differs between the requirements for dev and build. As an example, for dev purposes you may want to your task named "scss:dev" to also include sourceMaps option for easier debugging - yet you don't particularly want source maps included with the final build/dist code.


But, I must have one script or the world's gonna stop spinning :)

Is it possible to split my scss task into single script with multiple outputs for dev and prod folders?

Yes it's possible to have one script. Given the script named "scss" in your OP you could use chaining (&&) like this:

...
"scss": "node-sass app/src/styles/main.scss --output app/.tmp/styles/ && node-sass app/src/styles/main.scss --output app/dist/styles/"
...

Or, with an additional project dependency:

...
"scss": "node-sass app/src/styles/main.scss --output app/.tmp/styles/ && catw app/.tmp/styles/main.css > app/dist/styles/main.css"
...

This compiles the main.scss which outputs an initial main.css. We then cat the main.css and output a duplicate copy to the dist folder. (Note: This is using catw instead of cat because cat does not work cross platform)

Upvotes: 4

Related Questions