Why does package.json script behave differently than identical terminal command - npm

In my npm project, in my package.json file, I have the following lines of code:
"scripts": {
"build": "webpack"
},
While in my terminal, if I run npm webpack, I get the error message:
Unknown command: "webpack"
But if I run npm run build, I get a prompt from webpack saying I need webpack-cli... so the command is obviously recognized.
I'm confused about the different behavior of these two commands. In this case, isn't running npm run build identical to running npm webpack in my terminal? Why does one command fail and one succeed? What is actually happening when I run npm run build?

If we look at the documentation,
Environment
Package scripts run in an environment where many pieces of information are made available regarding the setup of npm and the current state of the process.
path
If you depend on modules that define executable scripts, like test suites, then those executables will be added to the PATH for executing the scripts.
Maybe this is the reason webpack is not recognized by the command line.

Related

Vite running as npm run dev but not directly in terminal

I'm facing this bizzare problem with my project. Here are the steps I followed
npm create vite#latest
cd to project folder.
npm i
npm run dev
This works well but the vite.config.js file is not generated. I tried to run vite but then it gives this error.
vite: The term 'vite' is not recognized as a name of a cmdlet, function, script file, or executable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Also using npm run dev --host is not making it available on LAN. Works fine with live-server.
I'm using the latest npm.
I was running into a similar problem.
npm run dev|build|preview works from shell.
vite build --mode other does not work from shell.
npm exec vite -- build --mode other works from shell.
I wanted a build that would use a .env.other distinct from .env.development or .env.production.
So running:
npm exec vite -- build --mode other
npm run preview
Correctly launches VITE with site-server set to mode 'other' and correctly uses the '.env.other' ENV settings.
I have no idea why on MacOS, I was seeing VITE not properly installed as a bin by npm. I did all the tricks (delete node_modules, re-install etc.)

How to execute nested "npm run commands" inside an npm#^7.0.0 monorepo set up within the context of the current workspace?

I have a monorepo with several workspaces within it. It has been very common for me to use chained npm scripts for simple tasks instead of using a task runner. So for example, the following configuration (pseudo code) is very common for me and usefull as well, specially for pre and post build scripts
"scripts": {
"prebuild:task1":"task1 --task1-arguments",
"prebuild:task2":"task2 --task2-arguments",
"prebuild": "npm run prebuild:task1 && npm run prebuild:task2",
"build":"build-script --build-arguments",
}
So the above is the package.json for the child worskpace itself and then in the master package.json I have the call to the script that triggers the build for that workspace.
build:packageA: "npm run build -w packageA"
All seems working well but the chained "npm run script" inside the workspace is actually execute in the context of the master monorepo and not inside that particular workspace.
So, in summary, the first call is to run the build script in the workscape and then triggers the prebuild script of that workspace BUT as that script execute chained npm run scripts those are run in the context of the master repo which happens that they don't exist in there. So the callstack might be ...
(master) build:packageA
(packageA) prebuild
(master) npm run prebuild:task1 >>>> EXIT ERROR
The only way I found, up to now, to bypass this issue was to make my child workspace a monorepo itself holding zero woskpaces. Essentially I have a "workspaces" key in its package.json pointing to the root directory. This enables me to use the -w flag in the scripts section so to refer all scripts to itself. So my current workaround looks like this ...
"workspaces": ["."],
"scripts": {
"prebuild:task1":"task1 --task1-arguments",
"prebuild:task2":"task2 --task2-arguments",
"prebuild": "npm run prebuild:task1 -w packageA && npm run prebuild:task2 -w packageA",
"build":"build-script --build-arguments -w packageA"
}
Isn't there already a better way to solve this?
Thanks in advance to everyone!
Following this post https://stackoverflow.com/a/67060676 I found out that npm changed the way it calls nested scripts in workspaces.
I ran into similar issues like you while running npm#7.5, but the feature was introduced in npm#7.7. Updating node to v17 and npm to 8.3 resulted in everything is running as intended.
In my case I wanted to execute nested npm run build commands in workspaces.

npm basics clarification: differences between npm start and npm build

Hi I need some clarification on npm materials.
What are the differences between "npm start" and "npm build"?
When do we use "run" for example, what are the differences between "npm test" and "npm run test"?
Thank you so much! I appreciate the explanation.
What you are finding is that there are some default scripts in NPM. Some of these are:
npm start
npm build
npm test
These are simply just aliases for npm run xxxx. To answer your question, npm run test and npm test are exactly the same. npm test is just a shorthand alias.
These default scripts are there to be used as kind of "universal" commands. For example: you have two different projects that have two different build processes. However, you could run npm build in both to build their respective build processes.
It depends on what you're using. In a react app npm start actually does npm run start but npm have allowed a shorthand version.
If you look in your package.json you'll see a scripts parameter that has all the things you can run using npm run [command]. You can define your own ones in there as well.
To answer your first question. The start and build commands are usually defined by webpack.
start is usually used to serve your app locally. So you can go to localhost and see it running.
build is used to compile your app into a folder, usually called dist/, into a flat html/CSS/JavaScript website so you can put the files onto a production server.

Can "npm run build" only be run from the folder that contains the package.json file?

When running npm run build from the command line, can it only be used in the folder that contains the package.json file?
I think yes because npm build is an internal command and npm build [<package-folder>] So, the folder containing a package.json file in its root.And as per documentation.
This is the plumbing command called by npm link and npm install. It should generally not be called directly.
From here,we can say that the env script is a special built-in command that can be used to list environment variables that will be available to the script at runtime. If an “env” command is defined in your package, it will take precedence over the built-in.
In addition to the shell’s pre-existing PATH, npm run adds node_modules/.bin to the PATH provided to scripts. Any binaries provided by locally-installed dependencies can be used without the node_modules/.bin prefix. For example, if there is a devDependency on tap in your package

How can I use only locally installed npm packages?

For example, to launch locally installed gulp, I have to run the following command from inside of my project:
node_modules/gulp/bin/gulp.js
To be able to launch npm packages only by their name, I want to include node_modules relatively to project's root dir. Is this possible?
P.S
I know how to install npm packages globally, but I'm trying to avoid doing that.
I hope I understand you correctly: You are trying to execute programs like gulp from your local install.
You can set up a npm script like so in your package.json:
package.json
...
"scripts": {
"build": "./node_modules/.bin/gulp"
}
...
Then, you can run gulp via npm run build from your command line. (Or optionally you can type ./node_modules/.bin/gulp)