Skip to content

Commit 40485e3

Browse files
authored
feat: add side-effects support for VeuiResolver (#128)
1 parent ce4709d commit 40485e3

File tree

1 file changed

+141
-4
lines changed

1 file changed

+141
-4
lines changed

src/core/resolvers/veui.ts

Lines changed: 141 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,150 @@
1-
import { ComponentResolver } from '../../types'
1+
import { join, normalize } from 'path'
2+
import { ComponentResolver, SideEffectsInfo } from '../../types'
3+
import { kebabCase, camelCase, pascalCase } from '../utils'
4+
5+
interface VeuiPeerConfig {
6+
/**
7+
* The package name of the peer module.
8+
*/
9+
package: string
10+
11+
/**
12+
* The directory path of the peer module.
13+
* @default 'components'
14+
*/
15+
path?: string
16+
17+
/**
18+
* The file name template for the peer module.
19+
* @default '{module}.css'
20+
*/
21+
fileName?: `${string}{module}${string}`
22+
23+
/**
24+
* The text transform to be applied to the '{module}' part of the file name.
25+
* @default 'kebab-case'
26+
*/
27+
transform?: 'kebab-case' | 'camelCase' | 'PascalCase' | false
28+
}
29+
30+
type SupportedLocale = 'en-US' | 'zh-Hans'
31+
32+
export interface VeuiResolverOptions {
33+
/**
34+
* The alias of 'veui` package.
35+
* @default 'veui'
36+
*/
37+
alias?: string
38+
39+
/**
40+
* Peer modules to be injected.
41+
*/
42+
modules?: VeuiPeerConfig[]
43+
44+
/**
45+
* Locale modules to be injected.
46+
* @default 'zh-Hans'
47+
*/
48+
locale?: SupportedLocale | SupportedLocale[] | false
49+
50+
/**
51+
* Global modules to be injected to all components.
52+
* @default []
53+
*/
54+
global?: string[]
55+
}
56+
57+
interface ComponentInfo {
58+
name: string
59+
path: string
60+
}
61+
62+
const VEUI_PACKAGE_NAME = 'veui'
63+
let components: Set<string> | undefined
264

365
/**
466
* Resolver for VEUI
567
*
668
* @link https://github.com/ecomfe/veui
769
*/
8-
export function VeuiResolver(): ComponentResolver {
70+
export function VeuiResolver(options: VeuiResolverOptions): ComponentResolver {
71+
const { alias = VEUI_PACKAGE_NAME } = options
72+
73+
if (!components) {
74+
try {
75+
/* eslint-disable @typescript-eslint/no-var-requires */
76+
const componentsData = require(`${alias}/components.json`) as ComponentInfo[]
77+
78+
components = new Set(componentsData.map(({ name }) => name))
79+
}
80+
catch (e) {
81+
throw new Error('[unplugin-vue-components:veui] VEUI is not installed')
82+
}
83+
}
84+
985
return (name: string) => {
10-
if (name.match(/^Veui[A-Z]/))
11-
return { importName: name.slice(4), path: 'veui' }
86+
if (name.match(/^Veui[A-Z]/)) {
87+
const componentName = name.slice(4)
88+
89+
if (!components!.has(componentName)) return
90+
91+
const sideEffects = getSideEffects(componentName, options)
92+
93+
return { importName: componentName, path: alias, sideEffects }
94+
}
95+
}
96+
}
97+
98+
const formatters = {
99+
'kebab-case': kebabCase,
100+
'camelCase': camelCase,
101+
'PascalCase': pascalCase,
102+
}
103+
104+
const peerPaths = new Map<string, boolean>()
105+
106+
function assertPeerPath(peerPath: string) {
107+
if (!peerPaths.has(peerPath)) {
108+
try {
109+
require.resolve(peerPath)
110+
peerPaths.set(peerPath, true)
111+
}
112+
catch (e) {
113+
peerPaths.set(peerPath, false)
114+
}
12115
}
116+
117+
return peerPaths.get(peerPath) as boolean
118+
}
119+
120+
function getSideEffects(
121+
name: string,
122+
{
123+
alias = VEUI_PACKAGE_NAME,
124+
modules = [],
125+
locale = 'zh-Hans',
126+
global = [],
127+
}: VeuiResolverOptions,
128+
): SideEffectsInfo {
129+
const localeModules = (locale
130+
? Array.isArray(locale)
131+
? locale
132+
: [locale]
133+
: []
134+
).map(locale => `${alias}/locale/${locale}/${name}.js`)
135+
136+
const peerModules = modules.map(
137+
({
138+
package: pack,
139+
path = 'components',
140+
fileName = '{module}.css',
141+
transform = 'kebab-case',
142+
}) => {
143+
const peer = transform ? formatters[transform](name) : name
144+
const file = fileName.replace(/\$?\{module\}/g, peer)
145+
return normalize(join(pack, path, file))
146+
},
147+
)
148+
149+
return [...localeModules, ...global, ...peerModules].filter(assertPeerPath)
13150
}

0 commit comments

Comments
 (0)