I have a complex production environment driven by package.json.
The problem: I wish to install locally some additional packages, keep an eye on the list and versions of them.
Solution (how to get there): point npm to use another config file, excluded from git, which would keep my private dependencies. Use the file to add packages to local node_modules with npm install. So actually all I need is to change configuration context of npm.
I have no clue how to point npm to use a different config (something like gulp -gulpfile).
Update from comments The dev-dependencies is not the way to go. I use stuff 90% of other developers do not need to get installed in their node_modules (in fact I could break their environment in a strange way updating dev-dependencies in git-shared core project-wide package.json).
First of all, you should know that what you are trying to is not only weird, but also against a lot of good practices and patterns in NodeJS.
Nevertheless, it's possible and if it's done right will almost never cause any trouble to you, or other developers in different platforms.
You can use something a little inspired on the Meteor build flow. Let's break your project conceptually into two different parts:
Project structure:
- build.js (base build script)
- package.json (base package)
- internal/
- package.template.json (project package template)
- app.js (your actual project files)
- [...] (your actual project files)
The starting point is create a package.json
file to the Base, in the root of the project. This package will hold only the dependencies to build the package file of the Internal project. I strongly advise you to use something like Mozilla's Convict to ensure the configurations are done correctly using ENVs. The goal here is to write another package.json
file at runtime.
Let's also assume in the your environment there's an Environment Variable USE_WEIRD_MODULES="true"
. You can use this fact in the Base project to define which modules you are going to install using the build.js file. You can read it and edit in runtime. When it's ready, save it as internal/package.json
. Then, run npm install
inside the internal/
directory.
build.js
let pkg = require('./package.template.json');
if(process.env.USE_WEIRD_MODULES) {
// Install your weird packages
pkg.dependencies.some_dev_package = '^v0.2.2';
pkg.dependencies.another_dev_package = '^v0.2.2';
}
// Don't forget to save the package.json in the end
fs.writeFileSync('./internal/package.json', JSON.stringify(pkg, null, 2), 'utf8');
Don't forget to put the internal/package.json
file in your repository ignore file (ex: gitignore).
To minimize the impact of this brute changes in the project, you can define in the main package.json
all the building routine in the postinstall
script. It will allow a simple npm install
in the root of the project handle all this steps internally.
Something like this:
package.json
{
[...]
"scripts": {
"postinstall": "node build.js && cd internal/ && npm install",
"start": "node internal/app.js"
}
[...]
}