Run NPM package for multiple files (using the example of csso-cli)

Some NPM packages already offer the possibility to be applied to several files of a directory at the same time – for instance, node-sass can convert a whole directory of SCSS files into CSS files. The minifier tool csso-cli does not offer an option to minify multiple files at once – here I show a workaround to do this anyway.

The initial situation and the problem

First of all, the reason why I need this. Since a few days, I try to use NPM scripts instead of Gulp for the build process. For a WordPress theme, I create the main CSS file from multiple SCSS files and generate an RTL version of the styles. Afterwards, a minified version of both files should be created. There are minification tools, which can handle a directory as input (for example, Minifier), but I would like to use csso-cli, to keep the source maps.

Of course, I could simply run one csso-cli call for each file, but there are various issues:

  1. Don’t repeat yourself.
  2. If another CSS file is added which should be minified, I would need to modify the build script.

So this would not be the best solution, and that was the reason I searched for a way to run csso-cli (or every NPM package or other commands) automatically for multiple files.

My solution

The solution is based on the find command from Linux. I came closer to the solution via different sites – I found the decisive answer on askubuntu. com. And that is it (without a few csso-cli options which are not relevant here):

find assets/css/ -iname '*.css' -and -not -iname '*.min.css' -exec sh -c 'node_modules/csso-cli/bin/csso {} --output ${0%.css}.min.css' {} \;
Code language: JavaScript (javascript)

We take all .css files from assets/css without files ending with .min.css. Afterwards, we execute a shell script for each of the found files, namely the csso-cli. With {} we get the file name with the path of the current CSS file – exactly what csso-cli needs as the first option.

We use ${0%.css} for the --output parameter to get the file’s name and path without the file ending and add .min.css (${0} lets us access {}, the first positional parameter of the shell script, which contains the file name and path again). The end of the script is marked by \;.

If we use this line as a node script, we will get the following error:

npm ERR! Failed to parse json npm ERR! Unexpected token ';'
Code language: JavaScript (javascript)

To solve that, we change the ending to \\;. This is how the script looks in the "scripts": part of my package.json (including all used options now):

"minify-css": "find assets/css/ -iname '*.css' -and -not -iname '*.min.css' -exec sh -c 'node_modules/csso-cli/bin/csso {} --input-map auto --map inline --output ${0%.css}.min.css' {} \\;"
Code language: JavaScript (javascript)

Via npm run minify-css I now can minify all CSS files from assets/css without processing .min.css files. Of course, you can change the script to use it with over NPM packages.

If you have any suggestions on how this can be improved, feel free to write a comment (also if you have something else to say, of course ?)!

Leave a Reply

Your email address will not be published. Required fields are marked *