Skip to content

Commit 9f1c323

Browse files
jtydhr88viva-jinyi
authored andcommitted
Vue expose (#4265)
1 parent 6a95948 commit 9f1c323

4 files changed

Lines changed: 117 additions & 101 deletions

File tree

build/plugins/addElementVnodeExportPlugin.ts

Lines changed: 0 additions & 59 deletions
This file was deleted.

build/plugins/generateImportMapPlugin.ts

Lines changed: 83 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
1-
import type { OutputOptions } from 'rollup'
2-
import { HtmlTagDescriptor, Plugin } from 'vite'
1+
import glob from 'fast-glob'
2+
import fs from 'fs-extra'
3+
import { dirname, join } from 'node:path'
4+
import { HtmlTagDescriptor, Plugin, normalizePath } from 'vite'
35

4-
interface VendorLibrary {
6+
interface ImportMapSource {
57
name: string
6-
pattern: RegExp
8+
pattern: string | RegExp
9+
entry: string
10+
recursiveDependence?: boolean
11+
override?: Record<string, Partial<ImportMapSource>>
12+
}
13+
14+
const parseDeps = (root: string, pkg: string) => {
15+
const pkgPath = join(root, 'node_modules', pkg, 'package.json')
16+
if (fs.existsSync(pkgPath)) {
17+
const content = fs.readFileSync(pkgPath, 'utf-8')
18+
const pkg = JSON.parse(content)
19+
return Object.keys(pkg.dependencies || {})
20+
}
21+
return []
722
}
823

924
/**
@@ -23,53 +38,89 @@ interface VendorLibrary {
2338
* @returns {Plugin} A Vite plugin that generates and injects an import map
2439
*/
2540
export function generateImportMapPlugin(
26-
vendorLibraries: VendorLibrary[]
41+
importMapSources: ImportMapSource[]
2742
): Plugin {
2843
const importMapEntries: Record<string, string> = {}
44+
const resolvedImportMapSources: Map<string, ImportMapSource> = new Map()
45+
const assetDir = 'assets/lib'
46+
let root: string
2947

3048
return {
3149
name: 'generate-import-map-plugin',
3250

3351
// Configure manual chunks during the build process
3452
configResolved(config) {
53+
root = config.root
54+
3555
if (config.build) {
3656
// Ensure rollupOptions exists
3757
if (!config.build.rollupOptions) {
3858
config.build.rollupOptions = {}
3959
}
4060

41-
const outputOptions: OutputOptions = {
42-
manualChunks: (id: string) => {
43-
for (const lib of vendorLibraries) {
44-
if (lib.pattern.test(id)) {
45-
return `vendor-${lib.name}`
46-
}
61+
for (const source of importMapSources) {
62+
resolvedImportMapSources.set(source.name, source)
63+
if (source.recursiveDependence) {
64+
const deps = parseDeps(root, source.name)
65+
66+
while (deps.length) {
67+
const dep = deps.shift()!
68+
const depSource = Object.assign({}, source, {
69+
name: dep,
70+
pattern: dep,
71+
...source.override?.[dep]
72+
})
73+
resolvedImportMapSources.set(depSource.name, depSource)
74+
75+
const _deps = parseDeps(root, depSource.name)
76+
deps.unshift(..._deps)
4777
}
48-
return null
49-
},
50-
// Disable minification of internal exports to preserve function names
51-
minifyInternalExports: false
78+
}
79+
}
80+
81+
const external: (string | RegExp)[] = []
82+
for (const [, source] of resolvedImportMapSources) {
83+
external.push(source.pattern)
5284
}
53-
config.build.rollupOptions.output = outputOptions
85+
config.build.rollupOptions.external = external
5486
}
5587
},
5688

57-
generateBundle(_options, bundle) {
58-
for (const fileName in bundle) {
59-
const chunk = bundle[fileName]
60-
if (chunk.type === 'chunk' && !chunk.isEntry) {
61-
// Find matching vendor library by chunk name
62-
const vendorLib = vendorLibraries.find(
63-
(lib) => chunk.name === `vendor-${lib.name}`
64-
)
65-
66-
if (vendorLib) {
67-
const relativePath = `./${chunk.fileName.replace(/\\/g, '/')}`
68-
importMapEntries[vendorLib.name] = relativePath
69-
70-
console.log(
71-
`[ImportMap Plugin] Found chunk: ${chunk.name} -> Mapped '${vendorLib.name}' to '${relativePath}'`
72-
)
89+
generateBundle(_options) {
90+
for (const [, source] of resolvedImportMapSources) {
91+
if (source.entry) {
92+
const moduleFile = join(source.name, source.entry)
93+
const sourceFile = join(root, 'node_modules', moduleFile)
94+
const targetFile = join(root, 'dist', assetDir, moduleFile)
95+
96+
importMapEntries[source.name] =
97+
'./' + normalizePath(join(assetDir, moduleFile))
98+
99+
const targetDir = dirname(targetFile)
100+
if (!fs.existsSync(targetDir)) {
101+
fs.mkdirSync(targetDir, { recursive: true })
102+
}
103+
fs.copyFileSync(sourceFile, targetFile)
104+
}
105+
106+
if (source.recursiveDependence) {
107+
const files = glob.sync(['**/*.{js,mjs}'], {
108+
cwd: join(root, 'node_modules', source.name)
109+
})
110+
111+
for (const file of files) {
112+
const moduleFile = join(source.name, file)
113+
const sourceFile = join(root, 'node_modules', moduleFile)
114+
const targetFile = join(root, 'dist', assetDir, moduleFile)
115+
116+
importMapEntries[normalizePath(join(source.name, dirname(file)))] =
117+
'./' + normalizePath(join(assetDir, moduleFile))
118+
119+
const targetDir = dirname(targetFile)
120+
if (!fs.existsSync(targetDir)) {
121+
fs.mkdirSync(targetDir, { recursive: true })
122+
}
123+
fs.copyFileSync(sourceFile, targetFile)
73124
}
74125
}
75126
}

build/plugins/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
export { addElementVnodeExportPlugin } from './addElementVnodeExportPlugin'
21
export { comfyAPIPlugin } from './comfyAPIPlugin'
32
export { generateImportMapPlugin } from './generateImportMapPlugin'

vite.config.mts

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@ import { type UserConfig, defineConfig } from 'vite'
77
import { createHtmlPlugin } from 'vite-plugin-html'
88
import vueDevTools from 'vite-plugin-vue-devtools'
99

10-
import {
11-
addElementVnodeExportPlugin,
12-
comfyAPIPlugin,
13-
generateImportMapPlugin
14-
} from './build/plugins'
10+
import { comfyAPIPlugin, generateImportMapPlugin } from './build/plugins'
1511

1612
dotenv.config()
1713

@@ -88,11 +84,40 @@ export default defineConfig({
8884
: [vue()]),
8985
comfyAPIPlugin(IS_DEV),
9086
generateImportMapPlugin([
91-
{ name: 'vue', pattern: /[\\/]node_modules[\\/]vue[\\/]/ },
92-
{ name: 'primevue', pattern: /[\\/]node_modules[\\/]primevue[\\/]/ },
93-
{ name: 'vue-i18n', pattern: /[\\/]node_modules[\\/]vue-i18n[\\/]/ }
87+
{
88+
name: 'vue',
89+
pattern: 'vue',
90+
entry: './dist/vue.esm-browser.prod.js'
91+
},
92+
{
93+
name: 'vue-i18n',
94+
pattern: 'vue-i18n',
95+
entry: './dist/vue-i18n.esm-browser.prod.js'
96+
},
97+
{
98+
name: 'primevue',
99+
pattern: /^primevue\/?.*/,
100+
entry: './index.mjs',
101+
recursiveDependence: true
102+
},
103+
{
104+
name: '@primevue/themes',
105+
pattern: /^@primevue\/themes\/?.*/,
106+
entry: './index.mjs',
107+
recursiveDependence: true
108+
},
109+
{
110+
name: '@primevue/forms',
111+
pattern: /^@primevue\/forms\/?.*/,
112+
entry: './index.mjs',
113+
recursiveDependence: true,
114+
override: {
115+
'@primeuix/forms': {
116+
entry: ''
117+
}
118+
}
119+
}
94120
]),
95-
addElementVnodeExportPlugin(),
96121

97122
Icons({
98123
compiler: 'vue3'

0 commit comments

Comments
 (0)