配置工具介绍与应用
细心的朋友会发现除了前文提到的一系列 defineXxx
函数外,还有一些 define
打头的函数没有提到,这些函数是一些方便用户进行个性化配置的一些工具函数。
这些工具函数构建的配置项有两大分类:SpecialConfig
和 RuntimeSpecialConfig
,其中 RuntimeSpecialConfig
从前者派生。
从名字很容易可以看出来,RuntimeSpecialConfig
的生命周期要更长一些,实际上也正是如此,SpecialConfig
的生命周期为构建配置到配置完成导入,而 RuntimeSpecialConfig
的生命周期会从构建配置持续到 swpp 结束运行。
这一系列函数的用法非常简单:
import {defineConfig, defineXxx} from 'swpp-backends'
// noinspection TypeScriptUnresolvedReference
defineConfig({
runtimeDep: {
// 注意这些工具函数可以也只能在配置项名称后方使用
example: defineXxx(...args)
}
})
⚠️注意:如非特别声明,这些 define
函数不能嵌套使用。
不可分割配置
继承关系:IndivisibleConfig
<- SpecialConfig
默认情况下,swpp 会对产生冲突的配置项按照优先级进行合并,当定义一个对象配置时,将允许从其它配置文件中合并一部分配置到对象中,比如:
import {defineXxx} from 'swpp-backends'
// 当前配置
defineXxx({
value: {
example1: 'hello world'
}
})
// 如果还有一个配置文件中也声明了这个配置
defineXxx({
value: {
example2: 'hello swpp'
}
})
// 最终将合并生成如下配置
// value: {
// example1: 'hello world',
// example2: 'hello swpp'
// }
该函数用于定义一个无法分割的对象配置,这对一些强依赖对象内部属性的设置很有用,可以避免对象被错误地拼接。
通过该函数,可以禁止 swpp 合并配置时仅选取对象的部分字段,要么全部使用 [value]
的值,要么完全不使用 [value]
的值。
放入到上述例子中,假如两个对象中任意一个或多个通过 defineIndivisibleConfig({ xxx: xxx })
设置,最终的值将取决于两个配置文件的优先级, 若 example1
的优先级高将产生:
import {defineXxx, defineIndivisibleConfig} from 'swpp-backends'
// 当前配置
defineXxx({
value: defineIndivisibleConfig({
example1: 'hello world'
})
})
// 如果还有一个配置文件中也声明了这个配置
defineXxx({
value: {
example2: 'hello swpp'
}
})
// 最终将合并生成如下配置
// value: {
// example1: 'hello world'
// }
注意事项:
- 仅有在两个对象中存在使用
defineIndivisibleConfig
定义的配置时才会禁用配置合并,假设现在有A
>B
>C
三个配置项都产生了冲突,其中A
优先级最高,但是只有C
使用了defineIndivisibleConfig
,那么A
将与B
完成合并后再与C
进行尝试合并,由于C
不能分割且优先级低,所以最终将产生A
与B
合并后的结果。 - 如果次级配置文件中使用
defineIndivisibleConfig
定义了某项配置,如果您需要覆盖这个配置,注意您无法使用这个配置中的内容,需要手动重写整个配置项。 - 除
IndivisibleConfig
外,所有的RuntimeSpecialConfig
都会携带与IndivisibleConfig
相同的副作用。
上下文配置
继承关系:ContextConfig
<- SpecialConfig
有些时候您可能希望在本地和远程环境使用不一样的配置,如果是大量的配置项不相同,那么您可以使用两个配置文件来编写配置,然后依靠前端实现来区分本地和远程的配置文件;如果是少量配置不相同,那么可以直接使用该函数来进行定义。
import {defineXxx, defineContextConfig, defineLazyInitConfig} from 'swpp-backends'
defineXxx({
example: defineContextConfig({
dev: 'hello dev',
prod: defineLazyInitConfig(() => 'hello prod')
})
})
这样,example
在开发环境将是 hello dev
,在生产环境将是 hello prod
。
该配置项内可嵌套 RuntimeSpecialConfig
。
不可缓存配置
继承关系:NoCacheConfig
<- RuntimeSpecialConfig
<- SpecialConfig
默认情况下,swpp 会缓存配置项的结果,下一次读取同一个配置项时便不需要经过类型检查等操作。有些时候您可能希望每一次读取值时都动态读取,那么可以使用此方法禁用缓存。
注意:该选项禁用缓存后对于性能有些许影响,计算结果和校验的成本越高影响越大,一般情况下无显著影响。
对于下方这个例子,第一种写法每次读取该项配置时,结果都将相同,如果第一次为 123456
那么以后永远都将是 123456
;而对于第二种写法,则每次调用时都能动态地获取当前系统时间。
import {defineXxx, defineNoCacheConfig} from 'swpp-backends'
// config 1
defineXxx({
example: Date.now()
})
// config 2
defineXxx({
example: defineNoCacheConfig(() => Date.now())
})
延迟初始化配置
继承关系:LazyInitConfig
<- RuntimeSpecialConfig
<- SpecialConfig
默认情况下,swpp 会在加载配置文件时对各项配置的值进行计算,此时就出现了一个问题,您无法在设置配置时访问其它配置内容。
如果您希望能够延后计算配置项的值以访问其它配置项,则可以使用该函数定义配置。
例:
// noinspection TypeScriptUnresolvedReference,JSUnusedLocalSymbols
import {defineXxx, defineLazyInitConfig} from 'swpp-backends'
defineXxx({
example: defineLazyInitConfig((runtime, compilation) => {
// 这里的代码将在第一次读取配置时执行
// do something
return _result
})
})