Reputation: 13085
I have a project that depends on the websocket package. However, for node 10.x, the latest version (1.0.31) of websocket works, while on node 4.x version 10.0.24 works but the 10.0.31 does not. Is it possible to specify different package (versions) per nodejs version to handle cases like this, e.g. like so
Preferable it should work in both npm and yarn, but if it only works in either that's fine as well.
The node 10 version is used in dev setups, while the node 4.x is used in a legacy embedded platform that cannot run docker or be upgraded.
Upvotes: 2
Views: 1189
Reputation: 25042
Consider utilizing a postinstall
script in the scripts
section of your projects package.json. For instance:
package.json
"scripts": {
"postinstall": "node install-websocket"
},
As you can see, the postinstall
script invokes a nodejs script, arbitrarily named install-websocket.js
.
install-websocket.js
const execSync = require('child_process').execSync;
const nodeMajorVersion = process.version.replace(/^v/, '').split('.')[0];
const websocketVersion = nodeMajorVersion <= '4' ? '1.0.24' : '1.0.31';
execSync('npm install websocket@' + websocketVersion, {
cwd: __dirname,
stdio: 'inherit'
});
The install-websocket.js
script essentially performs the following tasks:
Gets the version of node.js using process.version
which returns a string, e.g. v13.10.1
To obtain the Major version from that string (i.e. 13
in that aforementioned example) we use a combination of the replace() and split()
methods.
The conditional (ternary) operator ascertains
which version of websocket
to subsequently install - based on whether the value of nodeMajorVersion
is <= 4
.
Finally we "shell out" the appropriate npm install [email protected]
command using execSync
.
Note: If you're concerned about execSync
being synchronous, then utilize the asynchronous exec
instead.
Given the code shown above it assumes the install-websocket.js
file resides in the root of your project directory, i.e. at the same level as package.json.
my-project
├── package.json
├── install-websocket.js
└── ...
It's important for the install-websocket.js
file to exist at this location for following two reasons:
Primarily, and most importantly, because you'll have noticed that we specify __dirname
for the value of execSync
's cwd
option. The value of __dirname
in this context is the pathame to the parent directory of wherever the install-websocket.js
file resides.
Essentially by setting the cwd
option to this specific pathname, (i.e. the path to the project directory), we ensure that when the npm install [email protected]
command is run it gets installed in the same location as where your project resides - regardless of whether it's installed locally or globally.
The postinstall
script in package.json expects the install-websocket.js
file to reside there too. Note how it currently runs; node install-websocket
, and doesn't assume the file exists elsewhere, i.e. it's not running something like: node ./some/path/to/install-websocket
If consumers of your package have npm configured to ignore-scripts then websocket
's simply will not be installed because the postinstall
script will not be invoked.
Upvotes: 1