Sending command line arguments to a package.json script

Do you need to pass command line arguments dynamically to a package.json script? This is how to do it.

Static command line arguments can be set with the scripts.

  ...
  "scripts": {
    "cli": "node ./src/build-helper-cli.js -V"
  }
  ...

The script can be called as follows.

 $ npm run cli

Now lets pass it a command line argument dynamically.

$ npm run cli -- add-eslint-disable --dest build

The trick are the two dashes (–) which tell npm what follows are command line arguments for the script being executed. That is it. Easy right?

Adding aliases with Babel

Had enough of complicated import and require statements in your Node/JavaScript files? I’m used to developing in Vue which uses Webpack aliases that by default sets up the @ alias that points to the src directory. I’m working on a project that I am using Babel but not Webpack. It turns out Babel has the cool plugin babel-plugin-module-resolver that also setup aliases.

Install the plugin.

$ npm i --save-dev babel-plugin-module-resolver

So we have the following directory structure.

project
├── src
│  └─ MyCoolService
│    └─index.js
│  └── index.js
├── test
│  └── MyCoolService.spec.js
│  .babelrc
│  package.json

In the spec file I want to test MyCoolService. Importing is messy.

import MyCoolService from '../src/MyCoolService'

I want to do it the Vue way.

import MyCoolService from '@/MyCoolService'

Can it be done? O yes, babel-plugin-module-resolver to the rescue! Create a .babelrc file with the following contents.

// .babelrc
{
  "plugins": [
    ["module-resolver", {
      "root": ["./src/**"]
      "aliases": [
        "@": "./src"
      ]
    }]
  ]
}

Now we can import with the @ alias. Alternatively as the root points to src you can also import as follows.

import MyCoolService from 'MyCoolService'

How cool is that? Happy coding!

Find the location of NPM global packages on Windows

Today I wanted to add a file from a package that I had installed globally with NPM to Webstorm. Where does NPM install the global packages on Windows? How to find the location?

As always, once you know how it is simple. Just execute the following command from cmd.

npm config ls -l | grep prefix

That will show you the location. Which is probably something like C:\Users\\AppData\Roaming\npm.

Installing a module from a git repo with npm

I recently needed to add internationalization (i18n) functionality to an existing GitHub repository. I made the changes and put in a pull request. That pull request has not been processed yet. In the mean time I wanted to use my updated version. After some googling around I found out it is possible to manage modules directly from GitHub (git) with npm.

Such a cool feature. It means I can use my updated version until the main repository is updated. It is really easy, just change the line in the package.json file if you already have the module imported.

  ...
  "dependencies": {
    "@babel/polyfill": "^7.0.0-rc.1",
    "@feathersjs/feathers": "^3.2.3",
    "@feathersjs/rest-client": "^1.4.5",
    "axios": "^0.18.0",
    "vue": "^2.5.17",
    "vue-analytics": "^5.16.0",
    "vue-i18n": "^8.2.1",
    "vue-meta": "^1.5.5",
    "vue-recaptcha": "^1.1.1",
    "vue-router": "^3.0.1",
    "vue2-flip-countdown": "https://github.com/nidkil/vue2-flip-countdown",
    "vuelidate": "^0.7.4",
    "vuetify": "^1.3.1"
  },
  ...

And then run npm install command. The module will be replaced with the git version.

If you have not installed the module yet just execute the following command.

npm install --save <module name> <git repo> 

Example:

npm install --save vue2-flip-countdown https://github.com/nidkil/vue2-flip-countdown

Is this cool or what?

Installing npm modules globally without sudo

I needed to install pm2 globally and run it as non root. This meant installing it with npm without using the sudo command. However, when you do this npm will throw an error.

“Error: EACCES: permission denied”

The npm documentation does provide a solution that works, which has a caveat.

  1. Make a directory for global installations:
    mkdir ~/.npm-global
  2. Configure npm to use the new directory path:
    npm config set prefix '~/.npm-global'
  3. Open or create a ~/.profile file and add this line:
    export PATH=~/.npm-global/bin:$PATH
  4. Back on the command line, update your system variables:
    source ~/.profile

As a side note, an easier way to execute step 3 is:

echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.profile

When I initially executed these steps it worked. However, after logging out and in again the pm2 command was no longer available. It turns out that on login the .bash_profile file is loaded instead of the .profile. Actually bash will try loading ~/.bash_profile, ~/.bash_login and ~/.profile, in that order. Once it finds one of them it will not try and load any of the others. After adding the statement to .bash_profile it worked like a dream.

echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bash_profile

Hope this helps someone.