What is the difference between `npm run-script build` vs `npm build`? - node.js

When I run npm build, it gives this error:
npm WARN build `npm build` called with no arguments
So, what's the difference between npm run-script build and npm build?

npm run-script is a way to execute arbitrary commands specific to the project/package. Check your applicable package.json file, which will have defined what happens when you execute npm run-script build for that package. It may also include what happens when you run common commands, such as npm run-script test.
As you can see in the documentation for npm run-script, this arbitrary command can include arguments, which you need to refer to your package.json to learn more about.
npm build is not a unique command to the package, and is a native command that ships with npm, as you can see in its documentation.

The best answer is in this SO article.
Basically...
npm run == npm run-script
Plus, certain common tasks are aliased so that the following are true...
npm test == npm run-script test
npm build == npm run-script build
For common tasks, use...
npm start
npm build
npm test
npm restart
And for all others, use...
npm run <my-task>

TLDR
npm build is an old CLI command that npm stopped exposing via their CLI after version 6 of the CLI.
"build" is a common name chosen by developers for the user-defined script that builds their project. Developers define this in their package.json file and run with some variant of npm run-script build. If this user-defined script is not defined in package.json, the npm CLI will throw an error, just as it does when a user attempts to pass any other non-existent user-defined script to npm run-script.
Alias in Wonderland
First of all, I'll try not to go down the rabbit hole, but let me get something out of the way. At the time of writing this, run is just an alias for run-script, as are rum and urn, believe it or not. In the remainder of this answer, I will just use run-script, since it seems to be the "main" name (and not an alias) for this command. But in any of the usages below, feel free in your mind to replace run-script with run, or even rum or urn, if you are feeling quirky.
npm is a CLI
OK great, what next? Well, to avoid confusion, let's separate our concerns and first focus on the difference between npm COMMAND and npm run-script SCRIPT, in general. Here I am just using COMMAND and SCRIPT to denote some arbitrary command/script, respectively.
First, think about what npm is. It's a CLI tool. And like any other CLI tool you can think of, it has some built in commands or "verbs". For example, if we do npm ls, we can see a list of installed packages. Here ls is the COMMAND or the "verb" passed to npm.
The npm run-script command
One of the commands i.e. verbs that the npm CLI supports is run-script. This particular command will:
[run] an arbitrary command from a package's "scripts" object. If no "command" is provided, it will list the available scripts.
(source)
So for any user-defined SCRIPT you have in your package.json file, you can run it, using npm, by doing:
npm run-script SCRIPT
SCRIPT can be almost anything you like*. It's user defined. You can call a command build if you like, or you can call it billy or bilbo. Clearly, you want to call it something sensible. And that's why a lot of developers use the term build for a script which builds their project.
*There are some naming restrictions on the SCRIPT so it's not totally free-form. See here.
npm build and npm run-script build
Now that we understand npm is a CLI tool, we can finally tackle the problem of npm build. Here, we are passing build as the verb to the npm CLI. This is completely different to passing build as the name of a custom-script to run with npm run-script build.
Now, the question is, is the build command even a valid verb of the npm CLI? The answer is: it depends on the version of npm you are using:
Version 8: There is NO build command.
Version 7: There is NO build command.
Version 6: There is a build command.
So npm build is only valid in version 6, and possibly earlier versions, of the npm CLI.
It's likely that NPM intentionally removed the build command from their CLI to avoid confusion. Many developers use build as the name of one of their user-defined scripts in package.json, so having another build verb in the npm CLI causes the two to be confused - hence questions like this one.
Tests
To confirm that npm build and npm run-script build are indeed different, I tested them on Docker Playground for various Node/npm versions. Here are the results:
Node Version
npm version
Result of npm build
Result of npm run-script build
node:10.0.0-slim
npm#5.6.0
No output (command apparently succeeded but didn't seem to do anything)
npm ERR! missing script: build
node:12.0.0
npm#6.9.0
No output (command apparently succeeded but didn't seem to do anything)
npm ERR! missing script: build
node:18.6.0
npm#8.13.2
Unknown command: "build" (the command failed)
npm ERR! missing script: build
Old Source of Confusion
While writing this answer, I discovered a bug in the npm version 6 docs, which, like many of us confused folk visiting this SO question, were erroneously conflating npm build with npm run-script build and adding to the confusion. I have since submitted a PR for this issue which has been merged. Hopefully it will be reflected in the npm docs soon.
Hopefully the links in this answer stay alive for a while, but please comment if they go stale.

In short "npm build" is a inbuilt command or as NPM creator calls it... it is a lifecycle event (predefined) where as npm run-script is a task that executes a script and hence can be defined by user differently from the lifecycle event 'build'.

Related

How to fix `sh: ___: command not found` for NPM Modules

I'm relatively new to Node development and I'm trying out various modules, frameworks, etc.. I'm on macOS Catalina. I've changed my NPM root and $PATH while trying to get things to work, and I think I broke something, though I'm not exactly sure what. My issue is very specifically with NPM, which is having a persistent problem running installed modules both locally and globally. When I try to install a dev tool like Nodemon or a framework like Electron, I get error codes like:
sh: electron: command not found
npm ERR! code ELIFECYCLE
npm ERR! syscall spawn
npm ERR! file sh
npm ERR! errno ENOENT
npm ERR! electron-quick-start#1.0.0 start: `electron .`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the electron-quick-start#1.0.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
I've consulted a lot of resources and a lot of questions on this site, but I'm not experienced enough to accurately troubleshoot this issue and identify what's going on. While I'm shooting in the dark, I may be fixing one thing and breaking another, so I'm coming here to see if I can get a comprehensive answer.
I'll add that I've found a few workarounds, if this makes the issue clearer at all. I can get some modules (in this example Nodemon) to run by adding this "dev" script to the package.json:
"scripts": {
"dev": "node ./node_modules/.bin/nodemon server.js"
}
So I can access local project modules by specifying the path of the Module, but I can't just say "nodemon server.js", either in the dev script or from the command line, where it should have been installed globally. If I look in the specified npm -g root folder, the packages I'm trying to run are definitely in there, so it's not an installation issue.
Any guidance y'all have is greatly appreciated, as I don't know what to make of all this.
There are 2 installation style, local and global, on npm.
It is highly recommended to not mix both on the same environment, at least for a given module.
Global installation
e.g. npm install -g <module name>
The executable(s) provided by the module you have installed will be added into the place which PATH environment variable includes.
You can then use this command everywhere (here electron or nodemon), but you cannot use different versions for each project in your environment. You can isolate this behavior with nvm, or better in a container.
Local installation
e.g. npm install --save <module name>
The executable(s) will be installed into the project node_modules directory and saved in the package.json.
You can then use different versions of the module for each project and easily manage it with package.json.
PATH environment variable does not include there, so you have to use ./node_modules/.bin/<command>, as you did in your workaround, or $(npm bin)/<command>.
You can also use any command provided by the module in npm-scripts even if it's a local install because npm adds ./node_modules/.bin to PATH before npm run-script command.
See also: https://docs.npmjs.com/cli/v7/commands/npm-run-script

Can anyone explain this error when I run "npm run ng new app"?

So I'm trying to make a new angular app for the first time, and I installed it using npm i -g #angular/cli. When I try to make a new app using npm run ng new app, it gives me this error:
npm ERR! path E:\ddii\package.json
npm ERR! code ENOENT
npm ERR! errno -4058
npm ERR! syscall open
npm ERR! enoent ENOENT: no such file or directory, open 'E:\ddii\package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users...\AppData\Roaming\npm-cache_logs\2018-09-10T20_22_50_118Z-debug.log
In short, you are running the command incorrectly. Remove the npm run from the front of your command, and it should work.
When you say npm run blah, npm does a lookup in your package.json for a script called blah or in your case ng. So... if you are running npm run ng new app, npm wants there to be a package.json in your current directory, and in that package.json, npm expect a script called ng. So if you don't have a package.json in your current dir, then you are going to get an error.
Instead, close your terminal, and open a new terminal and run simply ng new app.
I struggled to find this answer myself, as the other answers on this question do not address the real underlying issue.
All the other answers suggest to install ng GLOBALLY using (npm i -g ...), with the side effect that a symlink to ng will be on your PATH.
Based on OP's question, I do concede he was most likely attempting to scaffold a new Angular app from the GLOBALLY installed ng. So this handles 90% of people's questions, and is all fine and nice.
I, however, want to use the LOCALLY INSTALLED ng, which is why I have an npm-script in my package.json for it:
{
...
"scripts": {
...
"ng": "ng",
...
}
If this describes your use case like it does mine, then read on.
npm run ng update succeeds for me, whereas other more complex commands with more arguments—including command-line switches—fail outright (npm run ng -- update #angular/cli --migrate-only tslint-version-6).
The answer lies in that you must delimit the start of arguments being passed to npm run-script with -- (see https://stackoverflow.com/a/14404223/1438576):
npm run ng -- update #angular/cli --migrate-only tslint-version-6
So in OP's case, assuming he already had a locally-installed copy of ng with a package.json (which I admit is doubtful), he could have done:
npm run ng -- new app
Anyway, hope this helps others.
If you want to run it without the npm run ..., you need to install ng globally, I would do npm install -g #angular/cli, however I'm running linux, for windows I've found this thread ng is not recognized as an internal or external command
It should help you install a global version of angular-cli, you'll basically do two things:
Install globally angular-cli (if you don't have it).
Make sure it's in your environment variable's PATH.
Check the question answers, details are there.
Could help for future references
At least for me this work.
Sometimes, the reference to the file ng.cmd (in case of Win users) is not well formed and you have to call it and pass the arguments directly
e.g.
< path-where-ng.cmd-file-is-located >\ng.cmd new app
Running calling ng.cmd file directly
It says: ' "ng" is not recognized as an internal or external command, operable program or batch file.'
And it works even if you do not have admin permissions for any reason

What is the difference between npm install and npm run build?

What is the difference between npm install and npm run build?
I have noticed in my project that sometimes npm starts failing when npm install is performed, but, upon running npm run build, it works just fine.
How do the inner workings of these two targets namely install and run build differ?
npm install installs dependencies into the node_modules/ directory, for the node project you're working on. You can call install on another node.js project (module), to install it as a dependency for your project.
npm run build does nothing unless you specify what "build" does in your package.json file. It lets you perform any necessary building/prep tasks for your project, prior to it being used in another project.
npm build is an internal command and is called by link and install commands, according to the documentation for build:
This is the plumbing command called by npm link and npm install.
You will not be calling npm build normally as it is used internally to build native C/C++ Node addons using node-gyp.
NPM in 2019
npm build no longer exists. You must call npm run build now. More info below.
TLDR;
npm install: installs dependencies, then calls the install from the package.json scripts field.
npm run build: runs the build field from the package.json scripts field.
NPM Scripts Field
https://docs.npmjs.com/misc/scripts
There are many things you can put into the npm package.json scripts field. Check out the documentation link above more above the lifecycle of the scripts - most have pre and post hooks that you can run scripts before/after install, publish, uninstall, test, start, stop, shrinkwrap, version.
To Complicate Things
npm install is not the same as npm run install
npm install installs package.json dependencies, then runs the package.json scripts.install
(Essentially calls npm run install after dependencies are installed.
npm run install only runs the package.json scripts.install, it will not install dependencies.
npm build used to be a valid command (used to be the same as npm run build) but it no longer is; it is now an internal command. If you run it you'll get: npm WARN build npm build called with no arguments. Did you mean to npm run-script build? You can read more on the documentation: https://docs.npmjs.com/cli/build or https://docs.npmjs.com/cli/v6/commands/npm-build
Extra Notes
There are still two top level commands that will run scripts, they are:
npm start which is the same as npm run start
npm test ==> npm run test
The main difference is:
npm install is a npm CLI-command which does the predefined thing i.e., as written by Churro, to install dependencies specified inside package.json.
npm run %command-name% or npm run-script %command-name% is also a CLI-command predefined to run your custom scripts with the name specified in place of "command-name". So, in this case npm run build is a custom script command with the name "build" and will do anything specified inside it (for instance echo 'hello world' given in below example package.json).
Points to note::
One more thing, npm build and npm run build are two different things, npm run build will do custom work written inside package.json and npm build is a pre-defined script (not available to use directly).
You cannot specify some thing inside custom build script (npm run build) script and expect npm build to do the same. Try following thing to verify in your package.json:
{
"name": "demo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "echo 'hello build'"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {},
"dependencies": {}
}
and run npm run build and npm build one by one and you will see the difference. For more about commands kindly follow npm documentation.
npm install installs the depedendencies in your package.json config.
npm run build runs the script "build" and created a script which runs your application - let's say server.js
npm start runs the "start" script which will then be "node server.js"
It's difficult to tell exactly what the issue was but basically if you look at your scripts configuration, I would guess that "build" uses some kind of build tool to create your application while "start" assumes the build has been done but then fails if the file is not there.
You are probably using bower or grunt - I seem to remember that a typical grunt application will have defined those scripts as well as a "clean" script to delete the last build.
Build tools tend to create a file in a bin/, dist/, or build/ folder which the start script then calls - e.g. "node build/server.js". When your npm start fails, it is probably because you called npm clean or similar to delete the latest build so your application file is not present causing npm start to fail.
npm build's source code - to touch on the discussion in this question - is in github for you to have a look at if you like. If you run npm build directly and you have a "build" script defined, it will exit with an error asking you to call your build script as npm run-script build so it's not the same as npm run script.
I'm not quite sure what npm build does, but it seems to be related to postinstall and packaging scripts in dependencies. I assume that this might be making sure that any CLI build scripts's or native libraries required by dependencies are built for the specific environment after downloading the package. This will be why link and install call this script.

Lifecycle of npm install

Npm install executes certain scripts like preinstall , postinstall and others.
I couldn't find explicit list and ordering of these scripts. It would be great to get some clarification and detailed overview of this process.
It is described on the NPM page: npm-scripts.
It is a bit cryptic, but the logic is straightforward.
E.g. running
npm install will do preinstall install postinstall prepublish - this is rather exceptional case, prepublish only runs if there are no arguments, i.e. run locally. Also check which version of npm you are running, as prepublish with local install has been deprecated in 4.x in favour of another approach, described in issue 10074 and has a nice explanation in this blog. It comes down to the fact that npm install without arguments runs when you clone a package and it makes sense to prepare it. But people dislike this behaviour, so it was decided to split prepublish into two stages. prepare runs instead of prepublish during publishing and local npm install. prepublishOnly runs only with npm publish.
Hence
npm publish will do prepublish publish postpublish or prepare prepublishOnly publish postpublish on 4.x
Finally, with version 6.x, npm install runs preinstall install postinstall prepare while npm publish runs prepare prepublish publish postpublish.
As far as I know, all other commands follow the logic of preX, X, postX.

Why am I getting Unexpected token '\u0000' when using npm install -g package

This is probably a Windows specific issue but I haven't found any information when googling this issue. I had been using ionic framework which relies on Cordova (or Phonegap). However, the problem is not specific to any of these packages. I see this error quite often. So, the error is when I run a command such as the following:
npm install -g cordova
However, I could substitute various other packages and get the same error. I'll paste the snippet (very brief) below of the error message. What is strange is that I had an ionic project working in that directory earlier. Then today it told me that ionic could not be found. My hunch is that this is a different issue than the main issue I am describing here.
I installed git bash so I do have a linux-like environment that I could try. I would just select Git Bash for a bash window with various bash commands. If there is an easier way to fix this for Windows users, please let me know. I have seen courses on Pluralsight where the instructors seem to be happily using npm with no problems. Also, when I use yeoman, I also at some point, in many cases, get the same error.
The error is
npm ERR! Failed to parse json
npm Unexpected token '\u0000' at 1:1
npm ERR!
npm ERR! ^
npm ERR! File: c:\Users\Bruce\AppData\Roaming\npm-cache\amdefine\1.0.0\package\package.json
npm ERR! Failed to parse package.json data.
npm ERR! package.json must be actual JSON, not just JavaScript.
npm ERR!
npm ERR! This is not a bug in npm
npm ERR! Tell the package author to fix their package.json file. JSON.parse.
Thanks in advance for any help/advice,
Bruce
Via this question on SO it could be that you just have to do:
npm cache clean.
But, also try the other methods suggested there like adding the registry option:
npm install <packagename> --registry http://registry.npmjs.org/.
Or, if you've been mingling with the package.json file by yourself, check if it's valid.

Resources