feat: support reading config from package.json (#3196) · nodejs/node-gyp@1822dff · GitHub
Skip to content

Commit 1822dff

Browse files
authored
feat: support reading config from package.json (#3196)
`npm@11` has deprecated setting arbitrary config values (npm/cli#8153), which was the previously recommended place for users to set node-gyp related config. The new recommendation from npm is to use the `config` object in package.json for this (npm/cli#8153 (comment)). I think it makes sense to follow npm's recommendation here. When a user sets a value in `package.json#config` it will be set in the environment by npm with the prefix `npm_package_config_<KEY>`. I think it makes sense to allow prescribe that they keys be prefixed with `node_gyp_`. So as an example: **package.json** ```json { "config": { "node_gyp_devdir": "/tmp/.gyp" } } ``` Then in `node-gyp` we can read the env var `npm_package_config_node_gyp_devdir`. If a user wants to set a global value, they can set that env var on their system. Fixes #3156
1 parent 0773615 commit 1822dff

3 files changed

Lines changed: 73 additions & 27 deletions

File tree

‎README.md‎

Lines changed: 22 additions & 3 deletions

‎lib/node-gyp.js‎

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -122,31 +122,41 @@ class Gyp extends EventEmitter {
122122
}
123123

124124
// support for inheriting config env variables from npm
125+
// npm will set environment variables in the following forms:
126+
// - `npm_config_<key>` for values from npm's own config. Setting arbitrary
127+
// options on npm's config was deprecated in npm v11 but node-gyp still
128+
// supports it for backwards compatibility.
129+
// See https://github.com/nodejs/node-gyp/issues/3156
130+
// - `npm_package_config_node_gyp_<key>` for values from the `config` object
131+
// in package.json. This is the preferred way to set options for node-gyp
132+
// since npm v11. The `node_gyp_` prefix is used to avoid conflicts with
133+
// other tools.
134+
// The `npm_package_config_node_gyp_` prefix will take precedence over
135+
// `npm_config_` keys.
125136
const npmConfigPrefix = 'npm_config_'
126-
Object.keys(process.env).forEach((name) => {
127-
if (name.indexOf(npmConfigPrefix) !== 0) {
128-
return
129-
}
130-
const val = process.env[name]
131-
if (name === npmConfigPrefix + 'loglevel') {
132-
log.logger.level = val
133-
} else {
137+
const npmPackageConfigPrefix = 'npm_package_config_node_gyp_'
138+
139+
const configEnvKeys = Object.keys(process.env)
140+
.filter((k) => k.startsWith(npmConfigPrefix) || k.startsWith(npmPackageConfigPrefix))
141+
// sort so that npm_package_config_node_gyp_ keys come last and will override
142+
.sort((a) => a.startsWith(npmConfigPrefix) ? -1 : 1)
143+
144+
for (const key of configEnvKeys) {
134145
// add the user-defined options to the config
135-
name = name.substring(npmConfigPrefix.length)
136-
// gyp@741b7f1 enters an infinite loop when it encounters
137-
// zero-length options so ensure those don't get through.
138-
if (name) {
146+
const name = key.startsWith(npmConfigPrefix)
147+
? key.substring(npmConfigPrefix.length)
148+
: key.substring(npmPackageConfigPrefix.length)
149+
// gyp@741b7f1 enters an infinite loop when it encounters
150+
// zero-length options so ensure those don't get through.
151+
if (name) {
139152
// convert names like force_process_config to force-process-config
140-
if (name.includes('_')) {
141-
name = name.replace(/_/g, '-')
142-
}
143-
this.opts[name] = val
144-
}
153+
this.opts[name.replaceAll('_', '-')] = process.env[key]
145154
}
146-
})
155+
}
147156

148157
if (this.opts.loglevel) {
149158
log.logger.level = this.opts.loglevel
159+
delete this.opts.loglevel
150160
}
151161
log.resume()
152162
}

‎test/test-options.js‎

Lines changed: 23 additions & 6 deletions

0 commit comments

Comments
 (0)