Npm 获取配置的顺序(由高到低):Command Line Flags > Environment Variables > npmrc Files > Default Configs
- Command Line Flags:
--flag1 --flag2 bar -- flag3
结果:flag1=true,flag2=bar,flag3为命令参数。 - Environment Variables:以 npm_config_ 开头的环境变量将被解释为配置参数。
npm_config_flag=bar
可通过process.env.npm_config_flag
获取 - npmrc Files:根据存放位置不同,优先级不同 – https://docs.npmjs.com/cli/v8/configuring-npm/npmrc
- Default Configs:内置配置参数,可通过
npm config ls -l
查看
相关配置命令:
代码语言:javascript复制npm config set <key> <value>
npm config get [<key>]
npm config delete <key>
npm config list [--json]
npm config edit
npm set <key> <value>
npm get [<key>]
这里重点讲述的是:npm 是如何对这些配置做“统一管理”。
核心思路:统一入口
- 枚举了每个“配置”【必选】【可选】属性,对此做统一强校验,后续无需再做是否存在判断。
Object.assign(this, def)
【扩充实例属性】这里包括 key、def- 统一定义【校验方法】,关联到当前实例中(挂载到了类的 prototype 属性上面)
Class 类方法都定义在类的
prototype
属性上面。 class Person { constructor (name) {} say(){} } console.log(Person.prototype) // {constructor: f, say: f} p.hasOwnProperty('say') // false p.__proto__.hasOwnProperty('say') // true 在类的实例上面调用方法,其实就是调用原型上的方法。 const p = new Person('ligang') p.constructor === Person.prototype.constructor // true 类的所有实例共享一个原型对象。 const p1 = new Person('li') const p2 = new Person('gang') p1.__proto__ === p2.__proto__ // true
definition.js 描述配置属性
代码语言:javascript复制// 配置项必须具备的属性
const required = ['key', 'type', 'default']
// 配置项可选属性
const allowed = [...required, 'description', 'name', 'flatten']
/* 统一结构定义 */
class Definition {
constructor (key, def) {
this.key = key
// 扩充实例属性
Object.assign(this, def)
// 校验
this.validate()
// 统一处理
if (!this.defaultDescription) {}
if (!this.typeDescription) {}
if (!this.hint) {}
}
validate () {
for (let req of required) {
// 校验必须存在的属性
if (!Object.prototype.hasOwnProperty.call(this, req)) {
throw new Error(`缺失必须属性 ${req}: ${this.key}`)
}
// 校验是否存在未知属性
for (let field of Object.keys(this)) {
if (!allowed.includes(field)) {
throw new Error(`存在未知属性 ${field}: ${this.key}`)
}
}
}
}
}
definitions.js 定义相关配置
代码语言:javascript复制// basic flattening function, just copy it over camelCase
const flatten = (key, obj, flatOptions) => {
const camel = key.replace(/-([a-z])/g, (_0, _1) => _1.toUpperCase())
flatOptions[camel] = obj[key]
}
const definitions = {}
const define = (key, def) => {
definitions[key] = new Definition(key, def)
}
define('registry', {
type: url,
default: 'https://registry.npmjs.org/',
description: 'The base URL of the npm registry.',
flatten
})
define('user-agent', {
type: String,
default: 'npm/{npm-version} node/{node-version} {platform} {arch} workspaces/{workspaces} {ci}',
description: 'Sets the User-Agent request header.',
flatten (key, obj, flatOptions) {
// 特殊处理
}
})
参考地址:
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes
- https://github.com/npm/cli/blob/HEAD/lib/utils/config/definition.js
- https://github.com/npm/cli/blob/HEAD/lib/utils/config/definitions.js
- https://blog.csdn.net/jiaojsun/article/details/99831112