-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvite.dev.config.ts
More file actions
140 lines (124 loc) · 4.76 KB
/
Copy pathvite.dev.config.ts
File metadata and controls
140 lines (124 loc) · 4.76 KB
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
130
131
132
133
134
135
136
137
138
139
140
/**
* Dev server config for Wely consumer projects.
* Used when running `wely dev` in a project that has no vite.config.
*
* HTML shell is read from the published `index.html` (same markup as the Wely repo dev server).
* The virtual entry imports `welyjs/playground/app` so behavior matches `src/playground/main.ts`.
*/
import { readFileSync } from 'node:fs'
import { dirname, join, relative, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
import { defineConfig } from 'vite'
import tailwindcss from '@tailwindcss/vite'
import { welyConsumerResolve } from './src/build/wely-vite-resolve'
import { welyTailwindPlugin, WELY_TAILWIND_VIRTUAL } from './src/build/wely-tailwind-plugin'
const pkgDir = dirname(fileURLToPath(import.meta.url))
const root = process.cwd()
/** Absolute path to the folder that contains components `index.ts` (from env or default). */
const componentsDirAbs = process.env.WELY_COMPONENTS_DIR
? resolve(process.env.WELY_COMPONENTS_DIR)
: resolve(root, 'src/wely-components')
const componentsRelToRoot = relative(root, componentsDirAbs).replace(/\\/g, '/')
const configPathResolved = process.env.WELY_CONFIG_PATH
? resolve(process.env.WELY_CONFIG_PATH)
: join(root, 'wely.config.ts')
function readWelyPackageConfig() {
try {
return JSON.parse(readFileSync(join(root, 'package.json'), 'utf-8')).wely ?? {}
} catch {
return {}
}
}
function buildComponentExcludeGlobs(base: string) {
const normalized = '/' + base.replace(/^\/+/, '').replace(/\/+$/, '')
const defaults = [
'!' + normalized + '/**/index.ts',
'!' + normalized + '/**/*.test.ts',
'!' + normalized + '/**/*.spec.ts',
]
const custom = readWelyPackageConfig().componentExclude
if (!Array.isArray(custom)) return defaults
const extra = custom.map((p: unknown) => {
const s = String(p)
if (s.startsWith('!')) return s
return '!' + normalized + '/' + s.replace(/^\//, '')
})
return [...defaults, ...extra]
}
const useAutoComponents = process.env.WELY_AUTO_COMPONENTS !== '0'
&& (process.env.WELY_AUTO_COMPONENTS === '1' || readWelyPackageConfig().autoComponents === true)
/** Virtual module that discovers consumer components via glob imports. */
const WELY_COMPONENTS_VIRTUAL = 'virtual:wely-components'
function buildPlaygroundHtml(virtualEntry: string): string {
const raw = readFileSync(join(pkgDir, 'index.html'), 'utf-8')
return raw
.replace(/\s*<link rel="stylesheet" href="\/src\/styles\/tailwind\.css" \/>\s*\n?/g, '\n')
.replace(/<script type="module" src="[^"]*"><\/script>/, `<script type="module" src="/${virtualEntry}"></script>`)
}
function welyPlaygroundPlugin() {
const VIRTUAL_ENTRY = 'virtual:wely-playground'
const RESOLVED_ENTRY = '\0' + VIRTUAL_ENTRY
const RESOLVED_COMPONENTS = '\0' + WELY_COMPONENTS_VIRTUAL
const componentGlobBase = '/' + componentsRelToRoot.replace(/^\/+/, '').replace(/\/+$/, '')
const excludeGlobs = buildComponentExcludeGlobs(componentsRelToRoot)
const componentsLoaderJs = useAutoComponents
? `
const __welyComponents = import.meta.glob([
${JSON.stringify(componentGlobBase + '/**/*.ts')},
${excludeGlobs.map((g) => JSON.stringify(g)).join(',\n ')},
], { eager: true })
void __welyComponents
`
: `
import ${JSON.stringify(join(root, 'src/bundle.ts'))}
`
const playgroundJs = `
import ${JSON.stringify(configPathResolved)}
import ${JSON.stringify(WELY_TAILWIND_VIRTUAL)}
import { mountApp } from 'welyjs/playground/app'
await import(${JSON.stringify(WELY_COMPONENTS_VIRTUAL)})
mountApp()
`
const playgroundHtml = buildPlaygroundHtml(VIRTUAL_ENTRY)
return {
name: 'wely-playground',
resolveId(id) {
if (id === VIRTUAL_ENTRY || id === '/' + VIRTUAL_ENTRY) return RESOLVED_ENTRY
if (id === WELY_COMPONENTS_VIRTUAL) return RESOLVED_COMPONENTS
},
load(id) {
if (id === RESOLVED_ENTRY) return playgroundJs
if (id === RESOLVED_COMPONENTS) return componentsLoaderJs
},
configureServer(server) {
return () => {
server.middlewares.use(async (req, res, next) => {
const url = req.url?.split('?')[0]
if (url === '/' || url === '/index.html') {
const transformed = await server.transformIndexHtml('/', playgroundHtml)
res.statusCode = 200
res.setHeader('Content-Type', 'text/html')
res.end(transformed)
return
}
next()
})
}
},
}
}
export default defineConfig({
root,
resolve: {
alias: {
...welyConsumerResolve(root),
/** Vite 7 import-analysis expects an explicit export; point at package source inside welyjs. */
'welyjs/playground/app': join(pkgDir, 'src/playground/app.ts'),
},
},
plugins: [
welyPlaygroundPlugin(),
welyTailwindPlugin({ root, welyPkgDir: pkgDir }),
tailwindcss(),
],
})