1

For the Node.js world, we can use NVM to switch between Node.js versions, and also switch out which global packages are in scope (in the $PATH).

However, what if I want to ensure that I use typescript version 3.3.334 at the command line? Obviously, I could install that version of typescript to my local project, but if I wanted to avoid a local dependency, how can I use a shell program to use an exact version of typescript at the command line?

I am thinking something like this:

package="typescript@3.3.334"
dir="$HOME/.temp/$package";

if [ ! -d "$dir" ]; then
    mkdir -p "$dir"
    (cd "$dir" && npm i "$package")
fi

export PATH="$dir/node_modules/.bin:$PATH"

do_the_original_thing_you_wanted_to_do foo bar
Alexander Mills
  • 1
  • 80
  • 344
  • 642

2 Answers2

1

Given that npm comes with npx bundled, you simply might want to run TypeScript with npx and specify the desired version number, such as:

$ npx typescript@3.3.334

This will download the typescript package in the desired version and run it (and throw it away afterwards). The only downside of this is that the package will be reinstalled over and over again, everytime you run npx.

You can work around this by installing typescript locally: If it is already installed locally, this local copy is being used, which speeds up things, but generally speaking this is the easiest way to ensure on each single call that you get the version you expect (in contrast to a global installation via npm -g typescript@3.3.334, which might be overwritten by someone else without you even noticing.

However, this is what you explicitly mentioned that you want to avoid it. So, the way described above may the best choice you have.

Golo Roden
  • 112,924
  • 78
  • 260
  • 376
  • yeah I definitely don't want to reinstall it. I wonder if there is a command for npx that can cache it? – Alexander Mills Apr 10 '19 at 19:03
  • Yes, `npm install typescript` run locally . Maybe the question is why you want to avoid a local install, since this is intended exactly for scenarios like this (and if you install it as a dev dependency, it does not even increase your production footprint)? – Golo Roden Apr 10 '19 at 19:04
  • I want to avoid local dependencies for libraries/packages, whereas local dependencies are ok for applications, if that makes sense – Alexander Mills Apr 10 '19 at 19:06
  • And again: Why? This sounds like "I want to, because I want to" – Golo Roden Apr 10 '19 at 19:07
  • Because disk space and speed of installs, that's all. Say your application has 5 dependencies, and each dependency has a version of typescript installed. That's retarded lol, especially because of versioning mismatch. – Alexander Mills Apr 10 '19 at 19:08
  • How much does disk space cost in the 21st century? And seriously: How often do you re-install that speed of install actually is an argument? Besides, if you install it as dev dependency everywhere, you don't install if 5 times, only if it is being used as dev dependency on the top level of your modules. – Golo Roden Apr 10 '19 at 19:10
  • it's also about changing the version, on the fly, I can do that with the CLI / PATH more easily – Alexander Mills Apr 10 '19 at 19:38
0

I will probably end up writing some shell script or bash function to switch versions of global cli tools easily, this works:

#!/usr/bin/env bash

package="typescript"
version="3.4.1"

dir="$HOME/.npz_temp/$package/$version";

json='{"name":"foo"}'

if [[ ! -f "$dir/success.json" ]]; then

    mkdir -p "$dir"
    (
        cd "$dir" &&
        echo "$json" > "$dir/package.json" &&
        npm install "$package@$version" &&
        echo 'npm install success' > "$dir/success.json"
    )

fi

export PATH="$dir/node_modules/.bin:$PATH"

tsc --version

all you have to do to generify it is have some arguments for the package and version. this technique should work with compiled/native-code packages also, I don't foresee a problem with that.

Alexander Mills
  • 1
  • 80
  • 344
  • 642