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.
Related
I create private npm registry with verdaccio.
I want to able to run npm install --registry="http://localhost:4873" and get all dependencies from private registry.
I need to publish all packages from my project node_modules directory.
I had to run npm publish in each package in node_module directory.(I could't find any better way.)
more of them published successfully But in some case, I encountered with the error. for example in zone.js package:
npm ERR! code ELIFECYCLE npm ERR! errno 2 npm ERR! zone.js#0.8.29
prepublish: `tsc && gulp build` npm ERR! Exit status 2 npm ERR! npm
ERR! Failed at the zone.js#0.8.29 prepublish script. npm ERR! This is
probably not a problem with npm. There is likely additional logging
output above. npm WARN Local package.json exists, but node_modules
missing, did you mean to install?
or in acorn package:
acorn#5.7.3 build:main C:\Users\Admin\Desktop\test ng\ng-prj\node_modules\acorn
rollup -c rollup/config.main.js
'rollup' is not recognized as an internal or external command,
operable program or batch file.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! acorn#5.7.3 build:main: `rollup -c rollup/config.main.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the acorn#5.7.3 build:main script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?
Is there a simple way of doing this?
here Verdaccio maintainer.
I want to able to run npm install --registry="http://localhost:4873" and get all dependencies from private registry.
What do you want is to have an offline registry with all your dependencies. Publish all node_modules is not practical and almost impossible.
more of them published successfully But in some case, I encountered with the error. for example in zone.js
That's the point, you would need to build each dependency, it just does not make sense. A regular project can easily have thousands of dependencies and sub dependencies. Not to mention you would lose the adventage of future dependencies updates.
So, what you need is cache properly all dependencies in your storage folder.
Run verdaccio $> verdaccio
Be sure you are online
Run npm install --registry="http://localhost:4873
When the finish to install, inspect your local cache, see here how to find it. You should be able to see all the resolved dependencies in the cache.
If you want a real offline experience, comment the proxy from the config file as follows
packages:
'#*/*':
access: $all
publish: $authenticated
# proxy: npmjs
'**':
access: $all
publish: $authenticated
# proxy: npmjs
If you comment out proxy Verdaccio won't ask for any update to the remotes, by default is npmjs, thus, no connection to external networks will be performed.
Restart Verdaccio
Repeat process as much time you need.
So, here, the advantages of this approach.
When yo back offline (you must comment out the proxy section again) you will allow Verdaccio to resolve wether you have new dependencies to be cached (in case you are using semver eg: lodash: ^1.5.6)
You will have a real installation experience, no fear to remove node_modules and clean the npm cache as well.
Storage is just a folder, so you can port it to another place (via USB or LAN)
Share cache with multiple projects and node package manager tools (yarn, npm or pnpn)
You don't have to publish each package in node_modules, thus see point 2).
I hope this helps you. Furthermore, there are other practices related with offline mode, but only with yarn.
We used Juan Picado's advice above. Here's what we did:
edit verdaccio's config file at /home/verdaccio/config.yaml
make sure that proxying is allowed
set the npm registry to point to your verdaccio instance
create a folder (any folder) on the system and run npm install commands to download packages
check the /home/verdaccio/storage/ directory. The downloaded packages plus their dependencies should now be in that directory.
edit verdaccio's config file, commenting out the two "proxy" lines so that proxying is turned off
restart verdaccio
At this point running npm install commands will only point to your verdaccio instance without going out to registry.npmjs.com and the packages in /home/verdaccio/storage will be your offline-available packages.
What is the order of execution when we use npm install.
As of now when I use npm install, It looks like-
dev dependencies
preinstall script
dependencies
install
postinstall
But in different condition it behave differently.
What is correct order of Execution?
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'.
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.
Is it possible to run any post processing script after installing NPM module automatically.
I have a case where, I can install some specific NPM modules in my node.js project. After installation of NPM module, I need to update some places in project automatically.
Is it doable?
Yes. Add a postinstall script to your package.json as described in the npm documentation