Here's how I managed to work around package.json
to achieve the same purpose. It uses a script that reads from a custom section of package.json
for URL modules, interpolates environment variables in them, and installs them with npm install --no-save
(the --no-save
could be omitted, depending on the usecase).
As a bonus: it tries to read the env variable from .env.json
, which can be gitignore'd, and very useful for development.
- Create a script that will read from a custom section of
package.json
env-dependencies.js
const execSync = require('child_process').execSync
const pkg = require('./package.json')
if (!pkg.envDependencies) {
return process.exit(0)
}
let env = Object.assign({}, process.env)
if (typeof pkg.envDependencies.localJSON === 'string') {
try {
Object.assign(env, require(pkg.envDependencies.localJSON))
} catch (err) {
console.log(`Could not read or parse pkg.envDependencies.localJSON. Processing with env only.`)
}
}
if (typeof pkg.envDependencies.urls === 'undefined') {
console.log(`pkg.envDependencies.urls not found or empty. Passing.`)
process.exit(0)
}
if (
!Array.isArray(pkg.envDependencies.urls) ||
!(pkg.envDependencies.urls.every(url => typeof url === 'string'))
) {
throw new Error(`pkg.envDependencies.urls should have a signature of String[]`)
}
const parsed = pkg.envDependencies.urls
.map(url => url.replace(/\${([0-9a-zA-Z_]*)}/g, (_, varName) => {
if (typeof env[varName] === 'string') {
return env[varName]
} else {
throw new Error(`Could not read env variable ${varName} in url ${url}`)
}
}))
.join(' ')
try {
execSync('npm install --no-save ' + parsed, { stdio: [0, 1, 2] })
process.exit(0)
} catch (err) {
throw new Error('Could not install pkg.envDependencies. Are you sure the remote URLs all have a package.json?')
}
Add a "postinstall": "node env-dependencies.js"
to your package.json
, that way it will be run on every npm install
Add your private git repos to package.json
using the URLs you want (note: they all must have a package.json
at root!):
"envDependencies": {
"localJSON": "./.env.json",
"urls": [
"git+https://${GITHUB_PERSONAL_ACCESS_TOKEN}@github.com/user/repo#semver:^2.0.0"
]
},
(the semver specifier #semver:^2.0.0
can be omitted, but refers to a git tag, which can be very useful, as it makes your git server a fully-fledge package manager)
npm install