1

I am trying to launch a npm script with a custom argument:

"publish-local": "ng build $PROJECT && cd dist/$PROJECT && npm publish --registry=http://my.local.npm.registry"

This is how I am trying to call it from the prompt:

PROJECT=my-lib npm run publish-local

This is how I have seen it should work on different web sources (for example:here)

Anyway, trying to do that, I get this error:

PROJECT=my-lib: The term 'PROJECT=my-lib' is not recognized as the name of a cmdlet, function, script file, or 
operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try 
again.
At line:1 char:1

What to do?

Igino Boffa
  • 686
  • 1
  • 9
  • 21

1 Answers1

0

Short answer: The example(s) that you've seen that "should work" will only work on *nix. They do not work via PowerShell, nor via Command Prompt on Windows.

Given that you're wanting to pass an argument to a npm-script, whereby that argument is consumed two times in the middle of that script I suggest you consider the following approach instead:

The following suggested approach is very similar to my answer here.


Solution - Cross-platform:

For a cross-platform solution, (one which works successfully with *nix, Windows Command Prompt and PowerShell etc..), you'll need to utilize a nodejs helper script.

Let's name the nodejs script publish-local.js and save it in the projects root directory, at the same level as package.json.

publish-local.js

const execSync = require('child_process').execSync;

const arg = process.argv[2] || 'my-lib'; // Default value `my-lib` if no args provided via CLI.

execSync('ng build ' + arg + ' && cd dist/' + arg +
    ' && npm publish --registry=http://my.local.npm.registry', {stdio:[0, 1, 2]});

package.json

Configure your publish-local script to invoke publish-local.js as follows:

...
"scripts": {
  "publish-local": "node publish-local",
},
...

Running publish-local script:

To invoke publish-local via your CLI you'll need to run:

npm run publish-local -- my-lib

Notes:

  • Inside publish-local.js take note of the line that reads:

    const arg = process.argv[2] || 'my-lib'; // Default value `my-lib` if no args provided via CLI.
    

    It specifies a default value to use when no argument is provide via the CLI.

    So, If you were to currently run the npm script without passing an argument:

    npm run publish-local
    

    or run it with passing an argument:

    npm run publish-local -- my-lib
    

    They are essentially the same. However if you were to provide an argument that is different to my-lib, i.e. one that is different to the default specified in publish-local.js, it will take precedence. For example:

    npm run publish-local -- some-other-lib
    
  • For a further understanding of this solution I suggest you read my answer that I previously linked to.

  • The default shell used by npm is cmd.exe on Windows, and sh on *nix - this given solution will work successfully with either.

  • If you only intend to use/support more recent versions of node.js that support features, such as destructuring, template literals then you could refactor publish-local.js as follows:

    publish-local.js (refactored using ES6 features)

    const { execSync: shell } = require('child_process');
    
    const [ , , projectName='my-lib' ] = process.argv;
    
    shell(`ng build ${projectName} && cd dist/${projectName} && npm publish --registry=http://my.local.npm.registry`, {stdio:[0, 1, 2]});
    
Community
  • 1
  • 1
RobC
  • 22,977
  • 20
  • 73
  • 80