@live-change/frontend-base 0.9.59 → 0.9.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +21 -19
- package/tailwindcss-vite.ts +349 -0
- package/vite-config.js +37 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@live-change/frontend-base",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.61",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"memDev": "node server/start.js memDev --enableSessions --initScript ./init.js --templatePath ../../base-frontend/index.html",
|
|
6
6
|
"localDevInit": "rm tmp.db; lcli localDev --enableSessions --initScript ./init.js",
|
|
@@ -35,22 +35,23 @@
|
|
|
35
35
|
"@lezer/rust": "=1.0.1",
|
|
36
36
|
"@lezer/sass": "=1.0.3",
|
|
37
37
|
"@lezer/xml": "=1.0.2",
|
|
38
|
-
"@live-change/cli": "^0.9.
|
|
39
|
-
"@live-change/dao": "^0.9.
|
|
40
|
-
"@live-change/dao-message": "^0.9.
|
|
41
|
-
"@live-change/dao-sockjs": "^0.9.
|
|
42
|
-
"@live-change/dao-vue3": "^0.9.
|
|
43
|
-
"@live-change/dao-websocket": "^0.9.
|
|
44
|
-
"@live-change/email-service": "^0.9.
|
|
45
|
-
"@live-change/password-authentication-service": "^0.9.
|
|
46
|
-
"@live-change/secret-code-service": "^0.9.
|
|
47
|
-
"@live-change/secret-link-service": "^0.9.
|
|
48
|
-
"@live-change/security-frontend": "^0.9.
|
|
49
|
-
"@live-change/session-service": "^0.9.
|
|
50
|
-
"@live-change/user-service": "^0.9.
|
|
51
|
-
"@live-change/vue3-components": "^0.9.
|
|
52
|
-
"@live-change/vue3-ssr": "^0.9.
|
|
53
|
-
"@primevue/themes": "^4.
|
|
38
|
+
"@live-change/cli": "^0.9.61",
|
|
39
|
+
"@live-change/dao": "^0.9.61",
|
|
40
|
+
"@live-change/dao-message": "^0.9.61",
|
|
41
|
+
"@live-change/dao-sockjs": "^0.9.61",
|
|
42
|
+
"@live-change/dao-vue3": "^0.9.61",
|
|
43
|
+
"@live-change/dao-websocket": "^0.9.61",
|
|
44
|
+
"@live-change/email-service": "^0.9.61",
|
|
45
|
+
"@live-change/password-authentication-service": "^0.9.61",
|
|
46
|
+
"@live-change/secret-code-service": "^0.9.61",
|
|
47
|
+
"@live-change/secret-link-service": "^0.9.61",
|
|
48
|
+
"@live-change/security-frontend": "^0.9.61",
|
|
49
|
+
"@live-change/session-service": "^0.9.61",
|
|
50
|
+
"@live-change/user-service": "^0.9.61",
|
|
51
|
+
"@live-change/vue3-components": "^0.9.61",
|
|
52
|
+
"@live-change/vue3-ssr": "^0.9.61",
|
|
53
|
+
"@primevue/themes": "^4.3.3",
|
|
54
|
+
"@tailwindcss/node": "4.1.0",
|
|
54
55
|
"@tailwindcss/vite": "4.1.0",
|
|
55
56
|
"@unhead/ssr": "^1.6.2",
|
|
56
57
|
"@vitejs/plugin-vue": "^5.0.5",
|
|
@@ -87,6 +88,7 @@
|
|
|
87
88
|
"serve-static": "^1.16.2",
|
|
88
89
|
"tailwindcss": "4.1.0",
|
|
89
90
|
"tailwindcss-primeui": "^0.4.0",
|
|
91
|
+
"tsx": "4.19.2",
|
|
90
92
|
"typescript": "5.4.5",
|
|
91
93
|
"unhead": "^1.9.13",
|
|
92
94
|
"unplugin-vue-components": "^0.27.0",
|
|
@@ -105,7 +107,7 @@
|
|
|
105
107
|
"vue3-scroll-border": "0.1.6"
|
|
106
108
|
},
|
|
107
109
|
"devDependencies": {
|
|
108
|
-
"@live-change/codeceptjs-helper": "^0.9.
|
|
110
|
+
"@live-change/codeceptjs-helper": "^0.9.61",
|
|
109
111
|
"codeceptjs": "^3.6.10",
|
|
110
112
|
"generate-password": "1.7.1",
|
|
111
113
|
"playwright": "1.49.1",
|
|
@@ -119,5 +121,5 @@
|
|
|
119
121
|
"author": "Michał Łaszczewski <michal@laszczewski.pl>",
|
|
120
122
|
"license": "BSD-3-Clause",
|
|
121
123
|
"description": "",
|
|
122
|
-
"gitHead": "
|
|
124
|
+
"gitHead": "f750f29f912b9a76b5ffa2bdf5c46954cc7e7a67"
|
|
123
125
|
}
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import { compile, env, Features, Instrumentation, normalizePath, optimize } from '@tailwindcss/node'
|
|
2
|
+
import { clearRequireCache } from '@tailwindcss/node/require-cache'
|
|
3
|
+
import { Scanner, SourceEntry } from '@tailwindcss/oxide'
|
|
4
|
+
import fs from 'node:fs/promises'
|
|
5
|
+
import path from 'node:path'
|
|
6
|
+
import type { Plugin, ResolvedConfig, ViteDevServer } from 'vite'
|
|
7
|
+
|
|
8
|
+
const DEBUG = env.DEBUG
|
|
9
|
+
const SPECIAL_QUERY_RE = /[?&](?:worker|sharedworker|raw|url)\b/
|
|
10
|
+
const COMMON_JS_PROXY_RE = /\?commonjs-proxy/
|
|
11
|
+
const INLINE_STYLE_ID_RE = /[?&]index\=\d+\.css$/
|
|
12
|
+
|
|
13
|
+
interface TailwindViteConfig {
|
|
14
|
+
sources: SourceEntry[]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default function tailwindcss(pluginConfig: TailwindViteConfig): Plugin[] {
|
|
18
|
+
let servers: ViteDevServer[] = []
|
|
19
|
+
let config: ResolvedConfig | null = null
|
|
20
|
+
|
|
21
|
+
let isSSR = false
|
|
22
|
+
let minify = false
|
|
23
|
+
|
|
24
|
+
let roots: DefaultMap<string, Root> = new DefaultMap((id) => {
|
|
25
|
+
let cssResolver = config!.createResolver({
|
|
26
|
+
...config!.resolve,
|
|
27
|
+
extensions: ['.css'],
|
|
28
|
+
mainFields: ['style'],
|
|
29
|
+
conditions: ['style', 'development|production'],
|
|
30
|
+
tryIndex: false,
|
|
31
|
+
preferRelative: true,
|
|
32
|
+
})
|
|
33
|
+
function customCssResolver(id: string, base: string) {
|
|
34
|
+
return cssResolver(id, base, true, isSSR)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
let jsResolver = config!.createResolver(config!.resolve)
|
|
38
|
+
function customJsResolver(id: string, base: string) {
|
|
39
|
+
return jsResolver(id, base, true, isSSR)
|
|
40
|
+
}
|
|
41
|
+
return new Root(id, config!.root, customCssResolver, customJsResolver)
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
return [
|
|
45
|
+
{
|
|
46
|
+
// Step 1: Scan source files for candidates
|
|
47
|
+
name: '@tailwindcss/vite:scan',
|
|
48
|
+
enforce: 'pre',
|
|
49
|
+
|
|
50
|
+
configureServer(server) {
|
|
51
|
+
servers.push(server)
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
async configResolved(_config) {
|
|
55
|
+
config = _config
|
|
56
|
+
minify = config.build.cssMinify !== false
|
|
57
|
+
isSSR = config.build.ssr !== false && config.build.ssr !== undefined
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
{
|
|
62
|
+
// Step 2 (serve mode): Generate CSS
|
|
63
|
+
name: '@tailwindcss/vite:generate:serve',
|
|
64
|
+
apply: 'serve',
|
|
65
|
+
enforce: 'pre',
|
|
66
|
+
|
|
67
|
+
async transform(src, id, options) {
|
|
68
|
+
if (!isPotentialCssRootFile(id)) return
|
|
69
|
+
|
|
70
|
+
using I = new Instrumentation()
|
|
71
|
+
DEBUG && I.start('[@tailwindcss/vite] Generate CSS (serve)')
|
|
72
|
+
|
|
73
|
+
let root = roots.get(id)
|
|
74
|
+
|
|
75
|
+
let generated = await root.generate(src, (file) => this.addWatchFile(file), I, pluginConfig)
|
|
76
|
+
if (!generated) {
|
|
77
|
+
roots.delete(id)
|
|
78
|
+
return src
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
DEBUG && I.end('[@tailwindcss/vite] Generate CSS (serve)')
|
|
82
|
+
return { code: generated }
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
{
|
|
87
|
+
// Step 2 (full build): Generate CSS
|
|
88
|
+
name: '@tailwindcss/vite:generate:build',
|
|
89
|
+
apply: 'build',
|
|
90
|
+
enforce: 'pre',
|
|
91
|
+
|
|
92
|
+
async transform(src, id) {
|
|
93
|
+
if (!isPotentialCssRootFile(id)) return
|
|
94
|
+
|
|
95
|
+
using I = new Instrumentation()
|
|
96
|
+
DEBUG && I.start('[@tailwindcss/vite] Generate CSS (build)')
|
|
97
|
+
|
|
98
|
+
let root = roots.get(id)
|
|
99
|
+
|
|
100
|
+
let generated = await root.generate(src, (file) => this.addWatchFile(file), I, pluginConfig)
|
|
101
|
+
if (!generated) {
|
|
102
|
+
roots.delete(id)
|
|
103
|
+
return src
|
|
104
|
+
}
|
|
105
|
+
DEBUG && I.end('[@tailwindcss/vite] Generate CSS (build)')
|
|
106
|
+
|
|
107
|
+
DEBUG && I.start('[@tailwindcss/vite] Optimize CSS')
|
|
108
|
+
generated = optimize(generated, { minify })
|
|
109
|
+
DEBUG && I.end('[@tailwindcss/vite] Optimize CSS')
|
|
110
|
+
|
|
111
|
+
return { code: generated }
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
] satisfies Plugin[]
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function getExtension(id: string) {
|
|
118
|
+
let [filename] = id.split('?', 2)
|
|
119
|
+
return path.extname(filename).slice(1)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function isPotentialCssRootFile(id: string) {
|
|
123
|
+
if (id.includes('/.vite/')) return
|
|
124
|
+
let extension = getExtension(id)
|
|
125
|
+
let isCssFile =
|
|
126
|
+
(extension === 'css' || id.includes('&lang.css') || id.match(INLINE_STYLE_ID_RE)) &&
|
|
127
|
+
// Don't intercept special static asset resources
|
|
128
|
+
!SPECIAL_QUERY_RE.test(id) &&
|
|
129
|
+
!COMMON_JS_PROXY_RE.test(id)
|
|
130
|
+
return isCssFile
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function idToPath(id: string) {
|
|
134
|
+
return path.resolve(id.replace(/\?.*$/, ''))
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* A Map that can generate default values for keys that don't exist.
|
|
139
|
+
* Generated default values are added to the map to avoid recomputation.
|
|
140
|
+
*/
|
|
141
|
+
class DefaultMap<K, V> extends Map<K, V> {
|
|
142
|
+
constructor(private factory: (key: K, self: DefaultMap<K, V>) => V) {
|
|
143
|
+
super()
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
get(key: K): V {
|
|
147
|
+
let value = super.get(key)
|
|
148
|
+
|
|
149
|
+
if (value === undefined) {
|
|
150
|
+
value = this.factory(key, this)
|
|
151
|
+
this.set(key, value)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return value
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
class Root {
|
|
159
|
+
// The lazily-initialized Tailwind compiler components. These are persisted
|
|
160
|
+
// throughout rebuilds but will be re-initialized if the rebuild strategy is
|
|
161
|
+
// set to `full`.
|
|
162
|
+
private compiler?: Awaited<ReturnType<typeof compile>>
|
|
163
|
+
|
|
164
|
+
// The lazily-initialized Tailwind scanner.
|
|
165
|
+
private scanner?: Scanner
|
|
166
|
+
|
|
167
|
+
// List of all candidates that were being returned by the root scanner during
|
|
168
|
+
// the lifetime of the root.
|
|
169
|
+
private candidates: Set<string> = new Set<string>()
|
|
170
|
+
|
|
171
|
+
// List of all build dependencies (e.g. imported stylesheets or plugins) and
|
|
172
|
+
// their last modification timestamp. If no mtime can be found, we need to
|
|
173
|
+
// assume the file has always changed.
|
|
174
|
+
private buildDependencies = new Map<string, number | null>()
|
|
175
|
+
|
|
176
|
+
constructor(
|
|
177
|
+
private id: string,
|
|
178
|
+
private base: string,
|
|
179
|
+
|
|
180
|
+
private customCssResolver: (id: string, base: string) => Promise<string | false | undefined>,
|
|
181
|
+
private customJsResolver: (id: string, base: string) => Promise<string | false | undefined>,
|
|
182
|
+
) {}
|
|
183
|
+
|
|
184
|
+
// Generate the CSS for the root file. This can return false if the file is
|
|
185
|
+
// not considered a Tailwind root. When this happened, the root can be GCed.
|
|
186
|
+
public async generate(
|
|
187
|
+
content: string,
|
|
188
|
+
_addWatchFile: (file: string) => void,
|
|
189
|
+
I: Instrumentation,
|
|
190
|
+
pluginConfig: TailwindViteConfig
|
|
191
|
+
): Promise<string | false> {
|
|
192
|
+
let inputPath = idToPath(this.id)
|
|
193
|
+
|
|
194
|
+
function addWatchFile(file: string) {
|
|
195
|
+
// Don't watch the input file since it's already a dependency anc causes
|
|
196
|
+
// issues with some setups (e.g. Qwik).
|
|
197
|
+
if (file === inputPath) {
|
|
198
|
+
return
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Scanning `.svg` file containing a `#` or `?` in the path will
|
|
202
|
+
// crash Vite. We work around this for now by ignoring updates to them.
|
|
203
|
+
//
|
|
204
|
+
// https://github.com/tailwindlabs/tailwindcss/issues/16877
|
|
205
|
+
if (/[\#\?].*\.svg$/.test(file)) {
|
|
206
|
+
return
|
|
207
|
+
}
|
|
208
|
+
_addWatchFile(file)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
let requiresBuildPromise = this.requiresBuild()
|
|
212
|
+
let inputBase = path.dirname(path.resolve(inputPath))
|
|
213
|
+
|
|
214
|
+
if (!this.compiler || !this.scanner || (await requiresBuildPromise)) {
|
|
215
|
+
clearRequireCache(Array.from(this.buildDependencies.keys()))
|
|
216
|
+
this.buildDependencies.clear()
|
|
217
|
+
|
|
218
|
+
this.addBuildDependency(idToPath(inputPath))
|
|
219
|
+
|
|
220
|
+
DEBUG && I.start('Setup compiler')
|
|
221
|
+
let addBuildDependenciesPromises: Promise<void>[] = []
|
|
222
|
+
this.compiler = await compile(content, {
|
|
223
|
+
base: inputBase,
|
|
224
|
+
shouldRewriteUrls: true,
|
|
225
|
+
onDependency: (path) => {
|
|
226
|
+
addWatchFile(path)
|
|
227
|
+
addBuildDependenciesPromises.push(this.addBuildDependency(path))
|
|
228
|
+
},
|
|
229
|
+
|
|
230
|
+
customCssResolver: this.customCssResolver,
|
|
231
|
+
customJsResolver: this.customJsResolver,
|
|
232
|
+
})
|
|
233
|
+
await Promise.all(addBuildDependenciesPromises)
|
|
234
|
+
DEBUG && I.end('Setup compiler')
|
|
235
|
+
|
|
236
|
+
DEBUG && I.start('Setup scanner')
|
|
237
|
+
|
|
238
|
+
let sources = (() => {
|
|
239
|
+
// Disable auto source detection
|
|
240
|
+
if (this.compiler.root === 'none') {
|
|
241
|
+
return []
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// No root specified, auto-detect based on the `**/*` pattern
|
|
245
|
+
if (this.compiler.root === null) {
|
|
246
|
+
return [{ base: this.base, pattern: '**/*', negated: false }]
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Use the specified root
|
|
250
|
+
return [{ ...this.compiler.root, negated: false }]
|
|
251
|
+
})().concat(this.compiler.sources).concat(pluginConfig.sources)
|
|
252
|
+
|
|
253
|
+
this.scanner = new Scanner({ sources })
|
|
254
|
+
DEBUG && I.end('Setup scanner')
|
|
255
|
+
} else {
|
|
256
|
+
for (let buildDependency of this.buildDependencies.keys()) {
|
|
257
|
+
addWatchFile(buildDependency)
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (
|
|
262
|
+
!(
|
|
263
|
+
this.compiler.features &
|
|
264
|
+
(Features.AtApply | Features.JsPluginCompat | Features.ThemeFunction | Features.Utilities)
|
|
265
|
+
)
|
|
266
|
+
) {
|
|
267
|
+
return false
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (this.compiler.features & Features.Utilities) {
|
|
271
|
+
// This should not be here, but right now the Vite plugin is setup where we
|
|
272
|
+
// setup a new scanner and compiler every time we request the CSS file
|
|
273
|
+
// (regardless whether it actually changed or not).
|
|
274
|
+
DEBUG && I.start('Scan for candidates')
|
|
275
|
+
for (let candidate of this.scanner.scan()) {
|
|
276
|
+
this.candidates.add(candidate)
|
|
277
|
+
}
|
|
278
|
+
DEBUG && I.end('Scan for candidates')
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (this.compiler.features & Features.Utilities) {
|
|
282
|
+
// Watch individual files found via custom `@source` paths
|
|
283
|
+
for (let file of this.scanner.files) {
|
|
284
|
+
addWatchFile(file)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Watch globs found via custom `@source` paths
|
|
288
|
+
for (let glob of this.scanner.globs) {
|
|
289
|
+
if (glob.pattern[0] === '!') continue
|
|
290
|
+
|
|
291
|
+
let relative = path.relative(this.base, glob.base)
|
|
292
|
+
if (relative[0] !== '.') {
|
|
293
|
+
relative = './' + relative
|
|
294
|
+
}
|
|
295
|
+
// Ensure relative is a posix style path since we will merge it with the
|
|
296
|
+
// glob.
|
|
297
|
+
relative = normalizePath(relative)
|
|
298
|
+
|
|
299
|
+
addWatchFile(path.posix.join(relative, glob.pattern))
|
|
300
|
+
|
|
301
|
+
let root = this.compiler.root
|
|
302
|
+
|
|
303
|
+
if (root !== 'none' && root !== null) {
|
|
304
|
+
let basePath = normalizePath(path.resolve(root.base, root.pattern))
|
|
305
|
+
|
|
306
|
+
let isDir = await fs.stat(basePath).then(
|
|
307
|
+
(stats) => stats.isDirectory(),
|
|
308
|
+
() => false,
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
if (!isDir) {
|
|
312
|
+
throw new Error(
|
|
313
|
+
`The path given to \`source(…)\` must be a directory but got \`source(${basePath})\` instead.`,
|
|
314
|
+
)
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
DEBUG && I.start('Build CSS')
|
|
321
|
+
let result = this.compiler.build([...this.candidates])
|
|
322
|
+
DEBUG && I.end('Build CSS')
|
|
323
|
+
|
|
324
|
+
return result
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
private async addBuildDependency(path: string) {
|
|
328
|
+
let mtime: number | null = null
|
|
329
|
+
try {
|
|
330
|
+
mtime = (await fs.stat(path)).mtimeMs
|
|
331
|
+
} catch {}
|
|
332
|
+
this.buildDependencies.set(path, mtime)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
private async requiresBuild(): Promise<boolean> {
|
|
336
|
+
for (let [path, mtime] of this.buildDependencies) {
|
|
337
|
+
if (mtime === null) return true
|
|
338
|
+
try {
|
|
339
|
+
let stat = await fs.stat(path)
|
|
340
|
+
if (stat.mtimeMs > mtime) {
|
|
341
|
+
return true
|
|
342
|
+
}
|
|
343
|
+
} catch {
|
|
344
|
+
return true
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return false
|
|
348
|
+
}
|
|
349
|
+
}
|
package/vite-config.js
CHANGED
|
@@ -5,7 +5,9 @@ import { findFreePorts } from 'find-free-ports'
|
|
|
5
5
|
import path from 'path'
|
|
6
6
|
import vuePlugin from '@vitejs/plugin-vue'
|
|
7
7
|
|
|
8
|
-
import tailwindcss from '@tailwindcss/vite'
|
|
8
|
+
//import tailwindcss from '@tailwindcss/vite'
|
|
9
|
+
import { tsImport } from 'tsx/esm/api'
|
|
10
|
+
const tailwindcss = (await tsImport('./tailwindcss-vite.ts', import.meta.url)).default
|
|
9
11
|
|
|
10
12
|
import Markdown from 'unplugin-vue-markdown/vite'
|
|
11
13
|
import MarkdownItAnchor from 'markdown-it-anchor'
|
|
@@ -83,7 +85,40 @@ export default async ({ command, mode, version }, options = {
|
|
|
83
85
|
}
|
|
84
86
|
},
|
|
85
87
|
}),
|
|
86
|
-
tailwindcss(
|
|
88
|
+
tailwindcss({
|
|
89
|
+
sources: [
|
|
90
|
+
'@live-change/frontend-base/src',
|
|
91
|
+
'@live-change/access-control-frontend/src',
|
|
92
|
+
'@live-change/content-frontend/src',
|
|
93
|
+
'@live-change/blog-frontend/src',
|
|
94
|
+
'@live-change/image-frontend/src',
|
|
95
|
+
'@live-change/security-frontend/src',
|
|
96
|
+
'@live-change/upload-frontend/src',
|
|
97
|
+
'@live-change/url-frontend/src',
|
|
98
|
+
'@live-change/user-frontend/src',
|
|
99
|
+
'@live-change/wysiwyg-frontend/src',
|
|
100
|
+
'@live-change/flow-frontend/src',
|
|
101
|
+
'@live-change/task-frontend/src',
|
|
102
|
+
'@live-change/balance-frontend/src',
|
|
103
|
+
'@live-change/billing-frontend/src',
|
|
104
|
+
'@live-change/survey-frontend/src',
|
|
105
|
+
'@live-change/peer-connection-frontend/src',
|
|
106
|
+
'@live-change/video-call-frontend/src',
|
|
107
|
+
'@live-change/frontend-auto-form/src',
|
|
108
|
+
'@live-change/db-web/src',
|
|
109
|
+
].map(p => {
|
|
110
|
+
try {
|
|
111
|
+
return {
|
|
112
|
+
base: path.dirname(fileURLToPath(import.meta.resolve(p))),
|
|
113
|
+
pattern: '**/*.{vue,css,scss,sass,less,styl,md}',
|
|
114
|
+
negated: false
|
|
115
|
+
}
|
|
116
|
+
} catch (e) {
|
|
117
|
+
// ignore import errors
|
|
118
|
+
return null
|
|
119
|
+
}
|
|
120
|
+
}).filter(Boolean)
|
|
121
|
+
}),
|
|
87
122
|
Markdown({
|
|
88
123
|
headEnabled: true,
|
|
89
124
|
markdownItOptions: {
|