NPM: To install a package along with its own devDeps - npm

I am just getting myself familiar with command line tools like npm. I've been searching around for the answer but was not able to find a clear one.
What I am trying to do is to install materialize-css package into my test package, as well as its devDependencies, like "autoprefixer". This is materializeCSS's package.json file.
Here's what I do:
Under my newly created and blank folder "testProject", I use npm init to create a package.json file for my test package:
{
"name": "create_project",
"version": "1.0.0",
"description": "Setting up a project",
"main": "index.html",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "shenk wen",
"license": "MIT"
}
Then, I do
npm install materialize-css
I was expecting the above command would install all the dependencies and devDependencies of materialize-css, but only the dependencies is being installed. I read this question and the accepted answer suggests adding --dev to the command. But that seems not the answer I am looking for because --dev would only make materialize-css a devDependency of my test package, but not installing its own devDependencies. The other answers are not so straightforward. Is there any parameter I can use to achieve this? Or do I have to change the env_variable which I don't know how to?

In older npm versions, 'npm install --dev' installed all devDependencies of all your dependencies. This also used to work in a recursive fashion, so you end up downloading also devDependencies of devDependencies of your dependencies and so on. This resulted in enormously long install time / download size.
Also, the purpose of the feature is questionable: Why should you care about devDeps of your deps? For these reasons --dev was removed from npm:
https://github.com/npm/npm/issues/5554
Current behavior for 'npm install' is: install all deps and devDeps for the 'main' package (the one you 'npm install'-ed in the first place), but when recursing, install only deps (and no devDeps).
If you want to install & save the dependency to your package.json, you should use --save or --save-dev, I don't think --dev does this.

If you want the devDependencies of a module you've installed as a dependency to your project, you almost certainly want to git clone that module's repo or fork it instead. When you run npm install in your cloned repo, that will also install all of the module's devDependencies.
(I'm not a developer by trade and my npm-fu was a bit rusty, so I confused myself about what I was trying to do. Tomas Kulich's question "Why should you care about devDeps of your deps?" helped me realize the error of my ways.)

Related

package-lock.json in npm workspaces

Given an npm workspace with the following structure
workspace
package.json
packages
package-a
package.json
package-b
package.json
When I run an install command in package-a this will generate a package-lock.json file in the root of the workspace but not in the package.json file itself.
Is there a way to also generate it in the packages?
I don't know if this solves your problem, but you can specifie the folder in which you would install with --prefix
npm install --prefix ./install/here
you can use the lerna tool to manage your workspace and install dependencies in each package. you can generate package-lock.json files in each package in your workspace.
The Original Tool for JavaScript Monorepos. Monorepo means a repository with multiple packages.
lerna.js.org
I hope this answer will show you the right direction.
In most cases, running npm install within that package directory should do the job. But as you said that this is creating a global package-lock.json. This might be because the package you are installing might be specifying the global path using the prefix field.
The "prefix" field, specifies the location where the package's dependencies should be installed.
So one thing you can do is to go to the package.json in package-a and then either remove the prefix field from the package.json file OR set its value as following :
{
"name": "my-package",
"version": "1.0.0",
"prefix": "./",
"dependencies": {
...
}
}
Now when you run npm install it should install the packages locally and make a local 'package-lock.json`.

How to "npm install packageX" while respecting package-lock.json

I want to update a dependency (packageX) without changing a locked dependency of that package, (packageY). In my package-lock.json, I have:
"packageX": {
"requires": {
"packageY": "1.0.0",
}
},
Each time I do "npm install packageX," I'd like to update packageX but have packageY stay on the defined version. How can I do that?
There is no way to do this, may be this link can explain better https://dev.to/saurabhdaware/but-what-the-hell-is-package-lock-json-b04
The story about package.json vs package-lock.json is tricky: npm install does not ignore package.json versions, nor does it ignore the package-lock.json. What it does is verify that the package.json and package-lock.json correspond to each other. That is, if the semver versions described in package.json fit with the locked versions in package-lock.json, npm install will use the latter completely, just like npm ci would.
Now, if you change package.json such that the versions in package-lock.json are no longer valid, your npm install will be treated as if you'd done npm install some-pkg#x.y.z, where x.y.z is the new version in the package.json for some-package.

Build npm-package from private git on install

I got a private bitbucket repo A that I install via npm in my project B.
npm install git+ssh://git#bitbucket.org....git
That works with no problems.
But now I would like to run a build in A after installing it.
npm in default comes with a lot of scripts for stuff like that https://docs.npmjs.com/misc/scripts
I tryed postinstall, prepare, prepublish, preinstall in my package.json in A:
...
"scripts": {
"prepublish": "npm run build",
"build": "...",
...
On installing my package A in B I get npm Error: npm ERR! premature close
I would like to run the build on install to remove build files from git (A).
In this case the build runs webpack + babel compile.
Project B is made with create-react-app.
I don't want to eject create-react-app, setup webpack or compile all node_modules packages.
Any experience with this workflow?
There is no need to eject Project B just adding your Project A as a dependency in package.json is enough. And for Project A please use "preinstall" it will run before every npm install including when you run npm install on Project B. And in my case I just tested it it working perfectly in my machine. If you encountering issue I think it might be because of the way you building it maybe? So can you show us the build script?
Use prepare since according to the NPM docs it will install dependencies and devDependencies before the package is packaged and installed.
Which is helpful if you are compiling using Typescript, or doing transforms.
...
"scripts": {
"prepare": "npm run build",
"build": "...",
...
Note: If your dist/build directory is ignored in .gitignore. Add an empty .npmignore file to your repository; otherwise the prepare script won't build the directory.
Ref: https://docs.npmjs.com/cli/install

Custom paths for package managers like Nuget/npm/bower/typings

I'm setting up a project in Visual Studio based on AngularJS and Typescript and it's a bit discouraging that I have to deal with yet another package manager as soon as I need to install dependencies.
The issue I have is that package managers require files containing dependencies to be located in a particular place.
Let's take npm for example.
I place packages.json at ./SolutionDirectory/MyApp.Web/
But when I run npm install, I just get ENOENT: No such file or directory. because cwd is ./SolutionDirectory
It works fine if I'm doing cd ./SolutionDirectory/MyApp.Web and run npm install after that.
For bower I was able to handle similar issue by just passing additional arguments like:
bower install --config.cwd=./SolutionDirectory/MyApp.Web/app/lib --config.directory=vendor
This command just gets bower.json from ./SolutionDirectory/MyApp.Web/app/lib and installs packages to ./SolutionDirectory/MyApp.Web/app/lib/vendor
Is there a way to have same thing to pass packages.json location to npm before it installs?
Is there a way to pass typings.json location to typings before it installs? to pass target directory location for typings installed?
Is the same doable for Nuget?
For npm:
npm install <folder>
<folder> is the path to the folder which contains the package.json file.
For typings:
typings install [<name>=]<location>
<location> is the path to the typings.json
For NuGet:
nuget install packageId|pathToPackagesConfig [options]
pathToPackagesConfig is the path to the packages.config file.
So, to answer the question, yes it's possible to specify a path to the config file's location for all of these package managers.
Is there a way to have same thing to pass packages.json location to npm before it installs?
No, there isn't. Currently there is no way to overwrite cwd value in npm. You should move directory and run it:
`$ cd SolutionDirectory/MyApp.Web/ && npm install`
Here is the similar discussion to this: https://github.com/npm/npm/pull/10958
Is there a way to pass typings.json location to typings before it installs? to pass target directory location for typings installed?
Technically yes, but I guess you'd like to just do typings install with typings.json. How about to put typings.json to the same path with package.json and use npm lifecycle script?
$ ls
package.json typings.json
$ cat package.json
{
"name": "name",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"postinstall": "typings install"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"typings": "^0.7.12"
}
}
$ npm install
=> after npm install, typings install will start with typings.json
Is the same doable for Nuget?
Nuget is also package manager, so it should has similar features, like nuget mirror command can be npm config set registry and nuget locales can be npm cache I guess. Technically it's a different software, but I think understanding about both softwares is good way to know the concept and summary of each others.

How to install bower on openshift.redhat? "No compatible version found"

I am testing openshift.redhat free plan. Until now, things were somewhat going fine with my deploy, until I tried installing bower. Search through the internet, some people advised on the following recipe:
HOME=$OPENSHIFT_DAT_DIR # as you cannot write to the home folder
npm install bower
With the following, I get a
No compatible version found for abbrev;
So, did anyone managed to install bower with redhat openshift?
Command line utilities that are usually installed using the -g or --global flag will be automatically be added to the system $PATH, as long as they are included in the dependencies or devDependencies sections of the project’s package.json file.
https://developers.openshift.com/en/node-js-dependency-management.html
This means that if you include bower in your package.json, you will be able to use bower like normal in your application.
"dependencies": {
"bower": "^1.4.1",
}
I found running bower more difficult...
I managed to get bower running by adding this in my package.json
"scripts": {
"postinstall": "HOME=$OPENSHIFT_REPO_DIR bower install || bower install"
}
It works on both my local machine AND Openshift.
Hope this helps