Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

npm script to rename files with the version specified in package.json

In the script section of my package.json file, I'm trying to rename some files in a directory, however I would like to inject a value in the command line that is taken from the package.json itself (version).

So in the case below, the build:rename script, I would like it to replace a token in the script (somevalue) before executing it.

In this case I would like to pass in the npm_package_version so that it's part of the name of the file. I'm at a loss...

"scripts": {
    "build:copy": "mkdirp dist && cp src/*.js dist/",
    "build:rename": "renamer --regex --find '(.+)(.js)' --replace '$1**somevalue**$2' dist/*"
}
like image 283
Ronald Phillips Avatar asked Dec 19 '22 08:12

Ronald Phillips


1 Answers

The current version specified in package.json can be referenced via the script using package.json vars as follows:


bash

In bash shells using the syntax - (note the dollar $ prefix):

$npm_package_version


Windows

In cmd.exe and Powershell using the syntax - (note the percentage % prefix and suffix):

%npm_package_version%


cross-patform

To achieve this cross-platform utlize cross-var:

$ npm i -D cross-var

The build:rename script can be revised as follows:

"scripts": {
  ...
  "build:rename": "cross-var \"renamer --regex --find '\\.js$' --replace '$npm_package_version.js' dist/*\""
},

Note: the additional change to the --find regular expression as cross-var doesn't seem to play nice when the --replace value includes dollar references ($1, $2) to the parenthesised substrings/groups in the --find value. The new regex simply matches the files/strings part ending in .js instead.


Example directory

Running the updated build:rename script, (when the version in package.json is 0.3.0), will rename the .js files in the dist directory from this:

.
├── dist
│   ├── a.html
│   ├── b.css
│   ├── foo.js
│   ├── bar.js
│   └── quux.js

...to this:

.
├── dist
│   ├── a.html
│   ├── b.css
│   ├── foo0.3.0.js
│   ├── bar0.3.0.js
│   └── quux0.3.0.js

Additional note

The cp command used in the build:copy script will also not work cross-platform. This can be substituted with the copyfiles package:

$ npm i -D copyfiles

... and the build:copy script then replaced with the following:

"scripts": {
  "build:copy": "copyfiles -u 1 \"src/*.js\" \"dist\"",
   ...
},

The mkdirp dist && part in your script then becomes redundant as copyfiles with create the necessary directory (i.e. dist).

If cross-platform is not necessary for your use-case then simply leave the build:copy script as-is, and change your build:rename script to:

"build:rename": "renamer --regex --find '\\.js$' --replace $npm_package_version'.js' dist/*"
like image 98
RobC Avatar answered Feb 05 '23 17:02

RobC