Include package.json dependencies from another file - npm

The Webpack/Vue ecosystem is a very fragile one, with minor updates to loaders regularly breaking the build. It's basically a dedicated job to curate a working Webpack config together with a list of the exact dependency versions that are needed to make it work.
This Webpack config can easily be kept in a repository and then copied to many different projects and imported in their local webpack.config.js because webpack.config.js is just Javascript.
I'd like to do the same thing with package.json, i.e. have the curated list of dependencies in a separate file and when running npm install have them added to any other dependencies a project might have.
Do npm or yarn or any other external tools offer such a functionality?

Are you specifically trying to use a js file? If so, I don't have an answer, but if json is enough, you can just make an node package that just has the dependencies you want in it. Someone that includes your package will then pull in all the dependencies listed in your package because npm pulls in the dependencies of a project's dependencies.
Also see https://stackoverflow.com/a/55483109/14144258

Related

Do NPM workspaces make sense for server-side project where all the dependencies needs to be released using CI alongside the server code

NPM can be used for different things
front-end projects where the final artifacts often have all their dependencies included.
service side services where the node_modules directory is available to the runtime server code.
NPM currently hoists dependencies to the root node_modules folder in a workspace project. Even their new proposal https://github.com/npm/rfcs/blob/main/accepted/0042-isolated-mode.md still doesn't seem to allow for all dependencies to be installed just alongside the node_modules folder next to the package.json for that workspace folder. You either have to copy the root node_modules folder to a parent directory, which gets complicated releasing multiple services (since it's a shared resource), or you must merge the two which is also not trivial.
This becomes a problem when you want to build in a CI environment and then move the code and all dependencies somewhere else
Does anyone have thoughts on how they've solved/avoided/approached this problem?
I ended up going with Lerna, since it seems to handle this situation perfectly. Lerna basically treats every "sub-project" independently.
https://lerna.js.org/
I don't think npm workspaces fits this type of workflow, or it wasn't designed to be in the first place

NPM5, What is the difference of package-lock.json with package.json?

After updating NPM to version 5, I found package-lock.json file with package.json.
What is the difference between this two files?
What are the advantages of package-lock.json?
A package.json file: lists the packages that your project depends on. allows you to specify the versions of a package that your project can use using semantic versioning rules.
According to the npm docs,
package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json . It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.
This file is intended to be committed into source repositories, and serves various purposes:
Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies.
Provide a facility for users to "time-travel" to previous states of node_modules without having to commit the directory itself.
To facilitate greater visibility of tree changes through readable source control diffs.
Basically package-lock.json is used to optimize the installation process by allowing npm to skip repeated metadata resolutions for previously-installed packages.
Before npm 5.x.x, package.json was the source of truth for a project. What lived in package.json was law. npm users liked this model and grew very accustomed to maintaining their package file. However, when package-lock was first introduced, it acted contrary to how many people expected it to. Given a pre-existing package and package-lock, a change to the package.json (what many users considered the source of truth) was not reflected in the package-lock.
Example: Package A, version 1.0.0 is in the package and package-lock. In package.json, A is manually edited to version 1.1.0. If a user who considers package.json to be the source of truth runs npm install, they would expect version 1.1.0 to be installed. However, version 1.0.0 is installed, despite the fact that v1.1.0 is listed is the package.json.
Example: A module does not exist in the package-lock, but it does exist in the package.json. As a user who looks to package.json as the source of truth, I would expect for my module to be installed. However since the module is not present in package-lock, it isn’t installed, and my code fails because it cannot find the module.
Read more about package-lock.json in the Official npm Documentation!
package.json records only your direct dependencies and their versions.
package-lock.json records not only your direct dependencies and exact versions, but also those of all dependencies of your dependencies - the entire dependency tree, in other words, with exact versions.
It's the fact that package-lock.json records the exact versions of all dependencies of a project, including sub-dependencies, that ensures that builds will be identical each time. (This is why npm ci bases its build on package-lock.json, not package.json.)
Builds based on package.json (as with npm i) cannot guarantee that all sub-dependencies are the exact same versions each build (e.g., if the subdependency of one of your dependencies releases an update, but the version of your direct dependency doesn't change), even if exact version numbers for direct dependencies are specified in the package.json.

How to handle chained dependencies in Sass projects with npm?

I have two Sass projects which I'm working on. Let's call them ProjectBase and ProjectExtended. ProjectExtended depends on ProjectBase, and the ProjectBase depends on a third party node module, namely Bootstrap.
ProjectBase should be independent but also work when used as a dependency.
ProjectBase has this include in it's Sass file:
#import '../node_modules/bootstrap/scss/bootstrap';
ProjectExtended then has this include:
#import '../node_modules/ProjectBase/scss/ProjectBase';
ProjectBase can build this without issues after running npm install because the included file is in that path under node_modules.
The problem arises in ProjectExtended because now after running npm install, the Bootstrap source is not in the same relative location anymore from the point of view of ProjectBase:
-node_modules/
|--bootstrap
|--ProjectBase
As you see in this case Bootstrap is suddenly a sibling instead of a dependency like so:
-node_modules/
|--bootstrap
|--ProjectBase
|--node_modules
|--bootstrap
As a workaround, I manually go into node_modules/ProjectBase and then run npm install in there, which installs those dependencies a second time under that folder.
Is there a better way to handle this?
This problem can be solved by providing custom importer to node-sass. I have simple implementation of such importer that you can try to use, it will allow you to configure all necessary paths and rules to resolve imports inside your .scss files.
In your case configuration may look like {roots: ['node_modules','../node_modules']} if I understand your directories structure properly.

Why doesn't Yarn install all executables in .bin folder?

I've just started using the Yarn package manager and I downloaded a starter Ionic 2 project.
In this project, we have a lot of help from scripts that compile, minify, lint and bundle our code. All of this is provided by ionic-app-scripts, which has several dependencies which it uses to run commands.
The problem is when I use Yarn to install, the node_modules/.bin/ folder does not contain all the necessary executables, like tslint, which is a dependency of ionic-app-scripts, so it is not directly in my package.json.
The result is that when I use Yarn, ionic-app-scripts doesn't work because it expects that the .bin folder contains a tslint executable!
What can I do? Are the ionic-app-scripts's definitions a problem?
[note]: npm install works, but Yarn is much faster!
This is a known issue, and there's a pull request with more information.
In short, if you want to fix this now, you'll have to explicitly include the packages from which you need binaries in your dependencies.
I had this issue but a different solution.
The solution was from this ticket https://github.com/yarnpkg/yarn/issues/992#issuecomment-318996260
... my workaround is going to file manager, right click on /node_modules main folder, selecting properties, and check-uncheck "read-only". You can do it also using attrib in command line. Then you retry installation and it works.

Change entry point to npm dependency

I'm dependending on a library that publishes different module packages to npm (commonjs, ES2015, UMD bundles..) and specifies commonjs/index.js as the main point of the application.
However, I need my app to use the UMD bundle instead so I would need it to be bundles/index.umd.js instead.
I figured I could do this by looking into installed 'node_modules' and changing it directly in the package.json of downloaded library, but thats a very hacky thing to do.
Is there some other way of chanding the main file for the dependency?