Launching "$ npm run"? programmatically with `npm.run()`?

Launching "$ npm run" programmatically with `npm.run()`

Deprecated! Please check out?Fig?or?ni?as possible alternatives!

No need for child_process.exec() etc. Pre and post scripts are respected too.

The problem of?mine

While working on the cypress-wait-until library, I’d like to upload the test videos on the Cypress Dashboard. Doing that is really simple, I only had to update my package.json dedicated script:

{
  "scripts": {
    // from
    "cy:run": "cypress run"
    // to
    "cy:run": "cypress run --record --key YOUR_SECRET_KEY"
  }
}
        

But I had to face a big problem: the YOUR_SECRET_KEY environment variable was going to be available just in the Travis build, not locally. And if you run it on your local machine, without a defined YOUR_SECRET_KEY, the cypress run command failed.

There are a lot of solutions to the above problem (like child_process.exec)but all of them come with a cost and some effects to be managed. More: I needed to change the way I manage the package.json scripts too.

I’d like to have a transparent solution that allowed me to make the YOUR_SECRET_KEY optional but without changing anything in my scripts management.

Npm as a local dependency

While googling I found an interesting solution: installing Npm locally and leveraging its APIs. How it works:

  • first of all, install npm with

$ npm install --save-dev npm
        

  • then, create a?.js file

$ touch index.js && open index.js
        

  • import npm

const npm = require("npm");
        

  • let npm loading the current project

npm.load();
        

  • pass a callback to the npm.load() API and run the script of your

npm.load(() => npm.run("SCRIPT_NAME"));
        

Some notes about the npm.run() API:

  • you cannot run it without calling npm.load in advance. If you try to do that you get a “Error: Call npm.load(config, cb) before using this command.” error
  • the first parameter is the script name, if you need to pass some options you must pass an array of strings

npm.run("test param"); // Error: missing script: test param
npm.run("test", "param"); // "param" is passed to the "test" script
        

I shared a npm-run-programmatically-example repository where you play with it, here a recorded gif of a terminal session of the repository:

The terminal session that shows the result of npm.run()

You can watch the same video on asciicinema too.

How this solution fitted my?needs

I solved the original problem this way:

  • I added one more cy:run-uploading-videos script to be launched instead of cy:run

{
  "scripts": {
    "cy:run-uploading-videos": "node cypress-run.js",
    "cy:run": "cypress run"
  }
}
        

  • the cypress-run.js file looked like this

const npm = require('npm');
npm.load(() => {
  const key = process.env.CYPRESS_RECORD_KEY;
  const options = key ? ['--record', '--key', key] : [];
  npm.run('cy:run', ...options);
});

        

So I could launch the usual cy:run script locally and launching cy:run-uploading-videos on Travis ?? (without duplicating the cypress run call that could have more parameters in the future).

What could I do with npm.run()?

An idea of mine is nprr, a tool that enhances npm run with autocomplete. Have you ever felt the situation when you do not remember the name of the script you want to run? So you open the package.json file, look for the script name and then run it… Well, nprr solves this problem! Watch it in action:

Nprr in action, it enhances the standard "npm run"? with autocomplete.

You can watch the same video on asciicinema too.

The possibilities are endless and if you leverage npm programmatically, please leave a comment with your experiments/packages/utilities, etc. ??



Hi ?? I’m Stefano Magni, I’m a passionate?JavaScript developer, a?Cypress Ambassador, and an instructor. I love creating high-quality products, testing and automating everything, learning and sharing my knowledge, helping people, speaking at conferences and facing new challenges. I work for?Conio, an Italian Bitcoin startup.

You can find me on?Twitter?and?GitHub. You can find all my?recent contributions/talks etc. here.

要查看或添加评论,请登录

社区洞察

其他会员也浏览了