nuxt3拆包剖析——配置加载
前言
在使用nuxt3
的过程中,我会很好奇nuxt3
的nuxt.config.ts
配置加载是如何做到的,查看源码,发现了一个很有意思的工具——c12
,接下来我们来讲解下这个工具的用法。
c12
Smart Configuration Loader.
点击链接跳到工具仓库
通过README.md
可以看到,该工具能够做到:
- 解析JSON, CJS, TS, ESM格式的config
- 解析RC配置
- 重复配置的合并
- 解析.env配置
- 解析package.json配置
- 配置监听器
以上几个功能足以应付目前市面上绝大多数的配置处理
使用方法
这是代码仓库,直接clone代码下来运行即可
主要使用代码:
import { loadConfig } from 'c12'
(async () => {
const config = await loadConfig({
name: 'wu',
})
console.log(config)
})()
当本地没有配置文件的时候,运行结果如下:
{
config: {},
cwd: 'D:/project/nuxt-c12-demo',
configFile: 'D:/project/nuxt-c12-demo/wu.config',
layers: [ { config: {}, configFile: '.wurc' } ]
}
在本地创建wu.config.js
wu.config.ts
wu.config.json
通过name
属性区分读取的是哪个文件,以下是输出结果
{
config: { name: 'wu-js', age: 18, male: true },
cwd: 'D:/project/nuxt-c12-demo',
configFile: 'D:\\project\\nuxt-c12-demo\\wu.config.js',
layers: [
{
config: [Object],
configFile: 'wu.config',
cwd: 'D:/project/nuxt-c12-demo'
},
{ config: {}, configFile: '.wurc' }
]
}
可以看到,当以上三种格式同时存在时,会优先读取js
文件
其他格式配置读取
RC配置
我们创建.wurc
配置
运行结果:
config: {
wurc: true,
'wurc-only': 'hhh',
wurcOnlyToo: 'xxx',
name: 'wu-js',
age: 18,
male: true
},
全局RC配置
我用的是win11,macos的全局配置在哪我不清楚,你们可以自行查阅
win用户的全局配置在C:/User/xxxx(用户名)/
,创建一个.wurc
(以后不用了记得删)
注意,读取全局配置,我们还需要设置globalRc
属性为true
import { loadConfig } from 'c12'
(async () => {
const config = await loadConfig({
name: 'wu',
globalRc: true,
})
console.log(config)
})()
运行结果如下
config: {
wurcGlobal: true,
'wurc-global-only': 'hhh',
wurc: true,
'wurc-only': 'hhh',
wurcOnlyToo: 'xxx',
name: 'wu-js',
age: 18,
male: true
},
package.json
想偷懒的同学也可以直接把配置放在package.json
中,不过个人不是很建议这样处理,这样会污染package.json
,不利于多人协作后续交接
我们修改package.json
:
同时需要注意,使用package.json
也需要设置配置packageJson
为true
import { loadConfig } from 'c12'
(async () => {
const config = await loadConfig({
name: 'wu',
globalRc: true,
packageJson: true,
})
console.log(config)
})()
运行结果:
config: {
package: true,
packageOnly: 'xxx',
wurcGlobal: true,
'wurc-global-only': 'hhh',
wurc: true,
'wurc-only': 'hhh',
wurcOnlyToo: 'xxx',
name: 'wu-js',
age: 18,
male: true
},
默认配置
我们还可以配置默认配置,使用defaults
属性
需要注意的是,defaults
属性配置的默认参数,是最低优先级的
import { loadConfig } from 'c12'
(async () => {
const config = await loadConfig({
name: 'wu',
globalRc: true,
packageJson: true,
defaults: {
name: 'defaults',
defaultKey: 'defaultValue',
},
})
console.log(config)
})()
运行结果如下
config: {
name: 'wu-js',
defaultKey: 'defaultValue',
package: true,
packageOnly: 'xxx',
wurcGlobal: true,
'wurc-global-only': 'hhh',
wurc: true,
'wurc-only': 'hhh',
wurcOnlyToo: 'xxx',
age: 18,
male: true
},
可以看到,我们配置了默认参数name
和defaultKey
,由于已经有了name
属性,所以默认配置并不会生效
env配置,特别注意
我在尝试读取.env
配置的时候,发现即使配置了dotenv: true
,还是没有读取配置
查阅了源码,发现源码并没有合并env
配置,不知道有意为之还是疏忽,这里我提了个issue,有这方面需求的同学可以关注一下
不过c12
提供了单独读取env
配置的api——loadDotenv
import { loadConfig, loadDotenv } from 'c12'
const env = await loadDotenv({
cwd: '.',
fileName: '.env',
})
console.log(env)
结果如下
[Object: null prototype] {
DOTENV: 'true',
DOTENVONLY: 'QQQ',
_applied: true
}
更新:这里的处理结果请看我发的评论
监听配置修改
c12
还提供了一个有意思的功能,能够监听配置文件的修改并执行回调,这里是封装了chokidar
api是watchConfig
,跟loadConfig
用法类似,多了几个入参,控制回调方法
import { watchConfig } from 'c12'
const config = await watchConfig({
cwd: '.',
name: 'wu',
onWatch: (event) => {
console.log('[watcher]', event.type, event.path)
},
acceptHMR({ oldConfig, newConfig, getDiff }) {
const diff = getDiff()
if (diff.length === 0) {
console.log('No config changed detected!')
return true // No changes!
}
},
onUpdate({ oldConfig, newConfig, getDiff }) {
const diff = getDiff()
console.log(`Config updated:\n${diff.map(i => i.toJSON()).join('\n')}`)
},
})
console.log(config)
可以看到,运行时会先输出监听的文件列表
修改配置文件,也能触发回调方法
该方法可以用于,监听配置文件是否修改,进行系统restart
处理等操作
总结
nuxt3
使用unjs/c12
来进行配置处理,该工具提供了多种配置读取方式,并且具有监听配置修改触发回调等操作
我们在开发类似配置读取功能的时候也可以使用该工具,简单易上手
转载自:https://juejin.cn/post/7236202362204389436