/
context.ts
129 lines (113 loc) · 3.49 KB
/
context.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { createFilter } from '@rollup/pluginutils'
import type { LoadConfigResult, LoadConfigSource } from '@unocss/config'
import { loadConfig } from '@unocss/config'
import type { UnocssPluginContext, UserConfig, UserConfigDefaults } from '@unocss/core'
import { BetterMap, createGenerator } from '@unocss/core'
import { CSS_PLACEHOLDER, IGNORE_COMMENT, INCLUDE_COMMENT } from './constants'
import { defaultExclude, defaultInclude } from './defaults'
export function createContext<Config extends UserConfig<any> = UserConfig<any>>(
configOrPath?: Config | string,
defaults: UserConfigDefaults = {},
extraConfigSources: LoadConfigSource[] = [],
resolveConfigResult: (config: LoadConfigResult<Config>) => void = () => {},
): UnocssPluginContext<Config> {
let root = process.cwd()
let rawConfig = {} as Config
let configFileList: string[] = []
const uno = createGenerator(rawConfig, defaults)
let rollupFilter = createFilter(defaultInclude, defaultExclude)
const invalidations: Array<() => void> = []
const reloadListeners: Array<() => void> = []
const modules = new BetterMap<string, string>()
const tokens = new Set<string>()
const tasks: Promise<void>[] = []
const affectedModules = new Set<string>()
let ready = reloadConfig()
async function reloadConfig() {
const result = await loadConfig(root, configOrPath, extraConfigSources, defaults)
resolveConfigResult(result)
rawConfig = result.config
configFileList = result.sources
uno.setConfig(rawConfig)
uno.config.envMode = 'dev'
rollupFilter = createFilter(
rawConfig.include || defaultInclude,
rawConfig.exclude || defaultExclude,
)
tokens.clear()
await Promise.all(modules.map((code, id) => uno.applyExtractors(code, id, tokens)))
invalidate()
dispatchReload()
// check preset duplication
const presets = new Set<string>()
uno.config.presets.forEach((i) => {
if (!i.name)
return
if (presets.has(i.name))
console.warn(`[unocss] duplication of preset ${i.name} found, there might be something wrong with your config.`)
else
presets.add(i.name)
})
return result
}
async function updateRoot(newRoot: string) {
if (newRoot !== root) {
root = newRoot
ready = reloadConfig()
}
return await ready
}
function invalidate() {
invalidations.forEach(cb => cb())
}
function dispatchReload() {
reloadListeners.forEach(cb => cb())
}
async function extract(code: string, id?: string) {
if (id)
modules.set(id, code)
const len = tokens.size
await uno.applyExtractors(code, id, tokens)
if (tokens.size > len)
invalidate()
}
function filter(code: string, id: string) {
if (code.includes(IGNORE_COMMENT))
return false
return code.includes(INCLUDE_COMMENT) || code.includes(CSS_PLACEHOLDER) || rollupFilter(id.replace(/\?v=\w+$/, ''))
}
async function getConfig() {
await ready
return rawConfig
}
async function flushTasks() {
const _tasks = [...tasks]
await Promise.all(_tasks)
tasks.splice(0, _tasks.length)
}
return {
get ready() {
return ready
},
tokens,
modules,
affectedModules,
tasks,
flushTasks,
invalidate,
onInvalidate(fn: () => void) {
invalidations.push(fn)
},
filter,
reloadConfig,
onReload(fn: () => void) {
reloadListeners.push(fn)
},
uno,
extract,
getConfig,
root,
updateRoot,
getConfigFileList: () => configFileList,
}
}