npm script command to run a script command from another package.json - npm

I have two separate projects that use npm - so I have both :
some_base_folder/projectA/package.json and some_base_folder/projectB/package.json
Each of those files has a scripts section in it.
If I go to some_base_folder/projectA/ and run npm run-script test it executes the test command from the scripts section of some_base_folder/projectA/package.json as it should.
What can I put as the value of "scripts": {test_projectA:'????' in some_base_folder/projectB/package.json so that when I am in some_base_folder/projectB/ and I run npm run-script test_projectA it will be
execute the test script of Project A?
I tried ../projectA/npm run-script test but it says:
'..' is not recognized as an internal or external command,
operable program or batch file.
I am running under windows 7 but would prefer a solution that would also work properly on linux.

well it turns out to be quite simple:
"scripts": {
test_projectA:"cd ../projectA && npm run-script test"
}

You should use --prefix.
npm run [command] --prefix path/to/your/other/folder
And for yarn:
yarn --cwd path/to/your/other/folder [command]

I ended up using:
"scripts": {
"job": "cd ./sub && \"$npm_execpath\" run subjob",
...
}
because this also works with yarn.

Related

Using command line arguments in npm run script

I am trying to change the {variable} part in my custom-defined npm run deploy script
"scripts":{
"deploy": "npm run build && scp -r ./public example#192.200.0.11:/home/{DIRECTORY}/index.js",
}
I want to run it like npm run deploy --DIRECTORY:project99
You can pass arguments to npm run as Environment variable. See Npm Docs
"scripts": {
"deploy": "npm run build && scp -r ./public example#192.200.0.11:/home/${NPM_CONFIG_DIRECTORY}/index.js"
},
This should work
npm run deploy --DIRECTORY=project99

What does " yarn build " command do? Are " npm build " and "yarn build" similar commands?

What does yarn build command do ?
Are yarn build and npm build the same? If not what's the difference?
yarn build and npm build are not existing commands by default. I think you mean yarn run build or npm run build.
build is a command which can be specified in your package.json file on the scripts property. See the example below.
{
"name": "mypackage",
"version": "0.1.0",
"scripts": {
"build": "webpack --config webpack.dev.js"
}
}
In this example, build is a shortcut for launching command webpack --config webpack.dev.js. You can use every keyword you want to define some shortcuts to launch commands.
And the only difference between the two commands it's the JS dependency manager you're using, yarn or npm.
More infos :
https://yarnpkg.com/lang/en/
https://www.npmjs.com/
"yarn build
Bundles the app into static files for production." from Create React App by MAD9135.
https://mad9135.github.io/F2020/modules/week3/02-react-tooling/07-create-react-app.html
yarn build is a shortcut of yarn run build
from original documentation:
Reference: https://classic.yarnpkg.com/lang/en/docs/cli/run/#toc-yarn-run-script
its the same i guess the real difference between yarn and npm is the performance and security that yarn provides.
yarn actually installing packages in parallelly and Npm only install one package at a time
And Yarn have more secure dependency.
Yarn is a package manager for your code. Yarn build makes a bundle of apps in one format and shows errors if the app has any problem that will make an error on the server.

Pass command line args to npm scripts in package.json

I have the below scripts in my package.json:
"scripts": {
"vumper": "node node_modules/vumper/index.js",
"format": "prettier --single-quote -width=80 --write package.json"
},
The 'vumper' package takes in a command line argument (such as 'dv'). What I would like to be able to do is have a command that runs both of these in succession.
Essentially, I would like to be able to run:
npm run vumber dv
and then
npm run format
but in one command, something like
npm run my-build dv
which would run both of the above commands, correctly accepting the command line argument 'dv' and passing it to the first npm run vumper. Is this possible?
Short Answer:
Essentially, what you're wanting is to have an npm-script something like this, whereby <arg-here> is provide via the CLI;
...
"scripts": {
"my-build": "npm run vumper <arg-here> && npm run format",
...
},
...
However, unfortunately npm does not have a built-in feature to achieve this.
The special npm option --, (refer to the end of Solution 1 below for further info about this option), can only be used to pass an argument to the END of a script but NOT into the MIDDLE. So, if your two commands were in the opposite order, the -- option could be used like this:
...
"scripts": {
"my-build": "npm run format && npm run vumper --",
...
},
...
To overcome the limitation of there being no built-in feature to pass an argument into the MIDDLE of a script consider the following solutions:
For a Bash only solution refer to the "Solution 1" section.
If cross platform support is required then follow the solution described in the "Solution 2" section.
Solution 1 - Bash (MacOS/Linux/ etc..):
Configure your my-build script in the scripts section of package.json to invoke a Bash shell function, as shown below:
package.json
...
"scripts": {
"my-build": "func() { npm run vumper \"$1\" && npm run format; }; func",
"vumper": "node node_modules/vumper/index.js",
"format": "prettier --single-quote -width=80 --write package.json"
},
...
Explanation:
The Bash function named func does the following:
Firstly runs npm run vumper <arg>. Whereby <arg> will be the shell argument passed via the CLI. It is referenced in the script using $1 (i.e. the first positional parameter/argument).
Subsequently it runs the script named format via the command npm run format.
These two npm run commands are chained using the && operator, so the second npm run format command will only run if the initial npm run vumper <arg> command completes successfully (i.e. returns a 0 exit code).
Running my-build script:
To invoke my-build via your CLI you'll need to run:
npm run my-build -- dv
Note:
In this instance the trailing dv part is the argument that will be passed to your vumper script.
The special option -- must be specified before the argument. The docs describe the -- option as:
... The special option -- is used by getopt to delimit the end of the options. npm will pass all the arguments after the -- directly to your script: ... The arguments will only be passed to the script specified after npm run and not to any pre or post script.
Solution 2 - Cross-platform:
For a cross-platform solution, (one which works successfully with Bash, Windows Command Prompt / cmd.exe, and PowerShell etc..), you'll need to utilize a nodejs helper script as follows.
run.js
Let's name the nodejs script run.js and save it in the projects root directory, at the same level as package.json.
const execSync = require('child_process').execSync;
const arg = process.argv[2] || 'dv'; // Default value `dv` if no args provided via CLI.
execSync('npm run vumper ' + arg, {stdio:[0, 1, 2]});
execSync('npm run format', {stdio:[0, 1, 2]});
package.json
Configure your my-build script to invoke run.js as follows:
...
"scripts": {
"my-build": "node run",
"vumper": "node node_modules/vumper/index.js",
"format": "prettier --single-quote -width=80 --write package.json"
},
...
Running my-build script:
As per Solution 1, to invoke my-build via your CLI you'll need to run:
npm run my-build -- dv
Explanation:
run.js utilizes process.argv to obtain the argument passed via the CLI (e.g. dv). If no argument is provided when running npm run my-build the default value, (i.e. dv), is passed to the vumper npm-script.
run.js also utilizes child_process.execSync(...) to shell-out/invoke the two npm run commands.
Npm now has a built-in option to pass cli arguments directly to scripts.
The cli arguments are stored in environmenet variables with prefix npm_config_<flagname>, and they required a very strict syntax, with the form --<flagname>=<flagvalue>.
Example:
"my-build": "npm run vumper %npm_config_myflag% && npm run format",
In the terminal, run npm run my-build --myflag=my_value to execute npm run vumper my_value && npm run format.
Note:
To refer the environment variable in the npm script, you have to use the platform specific syntax, ie %npm_config_myflag% in Windows or $npm_config_myflag in Linux.
UPDATE:
To avoid risks of conflict with the npm_config variables used to configure npm itself, just prefix your arguments with a unique prefix, such as the name of your app.
The potential conflict is a very common problem, which applies in many contexts: any application could use environment variables already used by other applications; for this reason, the environment variables are usually prefixed with the name of the application (eg NVM_HOME, JAVA_HOME). But this potential conflict is not a good reason to avoid using environment variables. The same in my opinion applies to npm params / npm_config env vars. The doc does not say anything about the risk of conflicts, implying I guess they should be managed as usual.
My preferred method is by using environment variables:
{
"scripts": {
"ncc-build": "ncc build $ACTION/src/index.ts -o $ACTION/dist",
"build:pr-changelog": "ACTION=pr-changelog npm run ncc-build",
}
}
It should work in UNIX systems. I'm not sure about windows platfrom compatibility though.
a different approach for doing this - to reach super deep into you dependency chain:
npm scripts section:
"test:local": "cross-env-shell UPDATE_BASELINE=false UPDATE_MODULE=%npm_config_vizdifsingle% run-p koa:ci wdio:local",
"test:remote": "cross-env-shell UPDATE_BASELINE=false UPDATE_MODULE=%npm_config_vizdifsingle% run-p localtunnel:start koa:ci wdio:remote"
by using crossenv and npm's value placement you can pass args to env.args
like this:
npm run test:local --vizdifsingle=some,value,or,values
it will be available to you in
process.env.npm_config_update_module

What does npm run bundle do?

I'm trying to understand and follows https://github.com/DMPRoadmap/roadmap/wiki/Installation
But I don't understand something they use.
What does these do?
1) npm run bundle
I know it equals to npm run-script bundle as according to npm doc about run script but I don't really understand where the bundle come from; in other words, I don't understand what npm doc about run script mean by
an arbitrary command from a package's script object
2) npm run bundle -- -p
Since I don't know where the bundle come from, I don't know how to work out the meaning of -- -p option. I want to find its documentation and see the details.
I'm not sure if npm doc about bundle is related, but it seems to be replaced by install as documented in npm doc about install.
And why is this option got so many - characters (3 in this case) before p? I normally see 2 - for long option name and 1 - for abbreviated option name
Any time you see npm run [x] anywhere it means that it's executing a command located in the scripts section of the package.json file. Therefore npm run bundle runs the bundle command located here: https://github.com/DMPRoadmap/roadmap/blob/master/lib/assets/package.json#L8 which in this case looks like all it's doing is running webpack
"scripts": {
"test": "./node_modules/.bin/karma start",
"bundle": "./node_modules/.bin/webpack",
"lint": "./node_modules/.bin/eslint --ext .js --cache ./javascripts/ || true"
}

How do I run an npm script of a dependent package

I have a package that itself has a script in its package.json that I would like to be able to run in my top-level project. This package is one of my top-level projects dependencies. I'm looking for a way to directly or indirectly call the dependency packages script.
Let us assume the module name I'm working with is named foo and the script I want to run is updateFooData.
I tried using the syntax npm run-script <package> <...> to run it, but this appears to be deprecated functionality as I can't find it in the current official documentation but I see it in other (very old) search results.
npm run-script foo updateFooData
# npm ERR! missing script: foo
I also looked into the npm api and while npm.commands.run-script(args, callback) will do what I want, I can't figure out how to load the module into npm
{
...
"scripts":{
"foo:updateFooData": "node --eval \"... ??; npm.commands.run-script('updateFooData', callback)\""
}
}
npm run foo:updateFooData
# Obviously fails
The only thing I've found that works so far is to CD into the submodule directory and run npm from there. This is not the preferred solution for me.
cd node_modules/foo
npm run updateFooData
I ran into this trying to run the updatedb script for geoip-lite. You should use the npm explore command which will spawn a new shell in a dependencies' directory.
So for your use case, try npm explore foo -- npm run updateFooData
Note:
This isn't a very good idea. You have no guarantee which node_modules folder module will be installed in as NPM will attempt to optimise space by installing shared packages at the highest level possible. – #superluminary
Something I've found that does work:
If the script you are running runs a script file, you can look at the path of the file it's running and run the script using a require:
# if node_modules/foo/package.json looks like this
{
"scripts": {
"updateFooData":"scripts/updateFooData.js"
}
}
# then package.json can look like this
{
"scripts": {
"foo:updateFooData":"node --eval \"require('foo/scripts/updateFooData.js')\""
}
}
# or package.json can look like this
{
"scripts": {
"foo:updateFooData":"node node_modules/foo/scripts/updateFooData.js"
}
}
# and you can run it like this
npm run foo:updateFooData
I don't like this solution because it only works if the npm script you are running is a file. It won't apply in all