问题
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).
回答1:
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:
- Base: Handles project initialization.
- Internal The original project.
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"
}
[...]
}
回答2:
npm
already offers a built in feature to handle exactly this requirement. To have different dependencies in your development environment and in production, you can save your dependencies into package.json in two different ways.
You can save it as a normal dependency (available in development and production) using the
save
flag. Ex:npm install <package-name> --save`
You can save it as a development dependency (available only in development and not in production) using the
save-dev
flag. Ex:npm install <package-name> --save-dev
When you run npm install on the server, if the NODE_ENV is set to production, it will not install the dev dependencies.
More on it here: https://docs.npmjs.com/cli/install. There are additional concepts like optional dependencies etc. which you can also use.
回答3:
You can use dev dependencies
instead of using seprate files.
install package using npm install packageName --dev
the package will go in devDependencies
of package.json
eg
"devDependencies": {
"chai": "~3.2.0",
"supertest": "~1.0.1",
"morgan": "~1.6.1",
"nodemon": "~1.8.1"
}
so when you npm install
in dev environment all dependencies will be installed but in production dev dependencies will be ignored
hope it helps :)
回答4:
You can write your own realisation.
You need to write package.json builder that can generate package.json where dependencies will be only needed
USAGE
node package.json.builder.js prod+test
npm install
Here will be created package.json file with dependencies that described in package.dependencies.js.
REALISATION
1.Add package.json to .gitignore
2.Create file package.json.builder.js will create package.json file
let fs = require('fs');
let pkgDep = require('./package.dependencies.js');
let pkgTemplete = fs.readFileSync('./package.json.hbs', "utf8");
let obj = {}, dep = [];
if (process.argv[2]) {
let array = process.argv[2].split('+');
for (let i = 0; i < array.length; i++) {
if (!pkgDep[array[i] + 'Dependencies']) {
console.error(array[i] + 'Dependencies' + ' not found in package.dependencies.js');
} else {
dep.push(array[i] + 'Dependencies');
}
Object.assign(obj, pkgDep[array[i] + 'Dependencies'] || {});
}
}
pkgTemplete = pkgTemplete.replace('{{dependencies}}', JSON.stringify(obj));
fs.writeFileSync('./package.json', pkgTemplete);
console.log('package.json created with ' + dep.join('+'));
3.Create package.json.hbs (package.json without dependencies)
{
"name": "",
"version": "1.0.0",
"dependencies": {{dependencies}},
"scripts": {
}
}
4.Create file package.dependencies.js object that contains only list of packages and its versions
module.exports = {
prodDependencies: {
"babel-core": "6.26.0"
},
devDependencies: {
"core-js": "2.5.5"
},
testDependencies: {
"jest": "23.5.0"
}
}
来源:https://stackoverflow.com/questions/36056788/use-npm-with-different-configuration-than-package-json