mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-29 02:32:18 +00:00
Devex: Remove Importmap plugin (#6899)
## Summary See [this page](https://www.notion.so/comfy-org/Remove-importmap-and-replace-with-better-solution-if-it-exists-2ab6d73d3650801d83afe006fa0d9929?source=copy_link). ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6899-Devex-Remove-Importmap-plugin-2b66d73d365081b28167c9ae70100092) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -64,7 +64,6 @@ const config: StorybookConfig = {
|
|||||||
deep: true,
|
deep: true,
|
||||||
extensions: ['vue']
|
extensions: ['vue']
|
||||||
})
|
})
|
||||||
// Note: Explicitly NOT including generateImportMapPlugin to avoid externalization
|
|
||||||
],
|
],
|
||||||
server: {
|
server: {
|
||||||
allowedHosts: true
|
allowedHosts: true
|
||||||
|
|||||||
@@ -1,154 +0,0 @@
|
|||||||
import glob from 'fast-glob'
|
|
||||||
import fs from 'fs-extra'
|
|
||||||
import { dirname, join } from 'node:path'
|
|
||||||
import { type HtmlTagDescriptor, type Plugin, normalizePath } from 'vite'
|
|
||||||
|
|
||||||
interface ImportMapSource {
|
|
||||||
name: string
|
|
||||||
pattern: string | RegExp
|
|
||||||
entry: string
|
|
||||||
recursiveDependence?: boolean
|
|
||||||
override?: Record<string, Partial<ImportMapSource>>
|
|
||||||
}
|
|
||||||
|
|
||||||
const parseDeps = (root: string, pkg: string) => {
|
|
||||||
const pkgPath = join(root, 'node_modules', pkg, 'package.json')
|
|
||||||
if (fs.existsSync(pkgPath)) {
|
|
||||||
const content = fs.readFileSync(pkgPath, 'utf-8')
|
|
||||||
const pkg = JSON.parse(content)
|
|
||||||
return Object.keys(pkg.dependencies || {})
|
|
||||||
}
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vite plugin that generates an import map for vendor chunks.
|
|
||||||
*
|
|
||||||
* This plugin creates a browser-compatible import map that maps module specifiers
|
|
||||||
* (like 'vue' or 'primevue') to their actual file locations in the build output.
|
|
||||||
* This improves module loading in modern browsers and enables better caching.
|
|
||||||
*
|
|
||||||
* The plugin:
|
|
||||||
* 1. Tracks vendor chunks during bundle generation
|
|
||||||
* 2. Creates mappings between module names and their file paths
|
|
||||||
* 3. Injects an import map script tag into the HTML head
|
|
||||||
* 4. Configures manual chunk splitting for vendor libraries
|
|
||||||
*
|
|
||||||
* @param vendorLibraries - An array of vendor libraries to split into separate chunks
|
|
||||||
* @returns {Plugin} A Vite plugin that generates and injects an import map
|
|
||||||
*/
|
|
||||||
export function generateImportMapPlugin(
|
|
||||||
importMapSources: ImportMapSource[]
|
|
||||||
): Plugin {
|
|
||||||
const importMapEntries: Record<string, string> = {}
|
|
||||||
const resolvedImportMapSources: Map<string, ImportMapSource> = new Map()
|
|
||||||
const assetDir = 'assets/lib'
|
|
||||||
let root: string
|
|
||||||
|
|
||||||
return {
|
|
||||||
name: 'generate-import-map-plugin',
|
|
||||||
|
|
||||||
// Configure manual chunks during the build process
|
|
||||||
configResolved(config) {
|
|
||||||
root = config.root
|
|
||||||
|
|
||||||
if (config.build) {
|
|
||||||
// Ensure rollupOptions exists
|
|
||||||
if (!config.build.rollupOptions) {
|
|
||||||
config.build.rollupOptions = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const source of importMapSources) {
|
|
||||||
resolvedImportMapSources.set(source.name, source)
|
|
||||||
if (source.recursiveDependence) {
|
|
||||||
const deps = parseDeps(root, source.name)
|
|
||||||
|
|
||||||
while (deps.length) {
|
|
||||||
const dep = deps.shift()!
|
|
||||||
const depSource = Object.assign({}, source, {
|
|
||||||
name: dep,
|
|
||||||
pattern: dep,
|
|
||||||
...source.override?.[dep]
|
|
||||||
})
|
|
||||||
resolvedImportMapSources.set(depSource.name, depSource)
|
|
||||||
|
|
||||||
const _deps = parseDeps(root, depSource.name)
|
|
||||||
deps.unshift(..._deps)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const external: (string | RegExp)[] = []
|
|
||||||
for (const [, source] of resolvedImportMapSources) {
|
|
||||||
external.push(source.pattern)
|
|
||||||
}
|
|
||||||
config.build.rollupOptions.external = external
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
generateBundle(_options) {
|
|
||||||
for (const [, source] of resolvedImportMapSources) {
|
|
||||||
if (source.entry) {
|
|
||||||
const moduleFile = join(source.name, source.entry)
|
|
||||||
const sourceFile = join(root, 'node_modules', moduleFile)
|
|
||||||
const targetFile = join(root, 'dist', assetDir, moduleFile)
|
|
||||||
|
|
||||||
importMapEntries[source.name] =
|
|
||||||
'./' + normalizePath(join(assetDir, moduleFile))
|
|
||||||
|
|
||||||
const targetDir = dirname(targetFile)
|
|
||||||
if (!fs.existsSync(targetDir)) {
|
|
||||||
fs.mkdirSync(targetDir, { recursive: true })
|
|
||||||
}
|
|
||||||
fs.copyFileSync(sourceFile, targetFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (source.recursiveDependence) {
|
|
||||||
const files = glob.sync(['**/*.{js,mjs}'], {
|
|
||||||
cwd: join(root, 'node_modules', source.name)
|
|
||||||
})
|
|
||||||
|
|
||||||
for (const file of files) {
|
|
||||||
const moduleFile = join(source.name, file)
|
|
||||||
const sourceFile = join(root, 'node_modules', moduleFile)
|
|
||||||
const targetFile = join(root, 'dist', assetDir, moduleFile)
|
|
||||||
|
|
||||||
importMapEntries[normalizePath(join(source.name, dirname(file)))] =
|
|
||||||
'./' + normalizePath(join(assetDir, moduleFile))
|
|
||||||
|
|
||||||
const targetDir = dirname(targetFile)
|
|
||||||
if (!fs.existsSync(targetDir)) {
|
|
||||||
fs.mkdirSync(targetDir, { recursive: true })
|
|
||||||
}
|
|
||||||
fs.copyFileSync(sourceFile, targetFile)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
transformIndexHtml(html) {
|
|
||||||
if (Object.keys(importMapEntries).length === 0) {
|
|
||||||
console.warn(
|
|
||||||
'[ImportMap Plugin] No vendor chunks found to create import map.'
|
|
||||||
)
|
|
||||||
return html
|
|
||||||
}
|
|
||||||
|
|
||||||
const importMap = {
|
|
||||||
imports: importMapEntries
|
|
||||||
}
|
|
||||||
|
|
||||||
const importMapTag: HtmlTagDescriptor = {
|
|
||||||
tag: 'script',
|
|
||||||
attrs: { type: 'importmap' },
|
|
||||||
children: JSON.stringify(importMap, null, 2),
|
|
||||||
injectTo: 'head'
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
html,
|
|
||||||
tags: [importMapTag]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,2 +1 @@
|
|||||||
export { comfyAPIPlugin } from './comfyAPIPlugin'
|
export { comfyAPIPlugin } from './comfyAPIPlugin'
|
||||||
export { generateImportMapPlugin } from './generateImportMapPlugin'
|
|
||||||
|
|||||||
@@ -164,7 +164,6 @@
|
|||||||
"es-toolkit": "^1.39.9",
|
"es-toolkit": "^1.39.9",
|
||||||
"extendable-media-recorder": "^9.2.27",
|
"extendable-media-recorder": "^9.2.27",
|
||||||
"extendable-media-recorder-wav-encoder": "^7.0.129",
|
"extendable-media-recorder-wav-encoder": "^7.0.129",
|
||||||
"fast-glob": "^3.3.3",
|
|
||||||
"firebase": "catalog:",
|
"firebase": "catalog:",
|
||||||
"fuse.js": "^7.0.0",
|
"fuse.js": "^7.0.0",
|
||||||
"glob": "^11.0.3",
|
"glob": "^11.0.3",
|
||||||
|
|||||||
17
pnpm-lock.yaml
generated
17
pnpm-lock.yaml
generated
@@ -15,15 +15,9 @@ catalogs:
|
|||||||
'@eslint/js':
|
'@eslint/js':
|
||||||
specifier: ^9.35.0
|
specifier: ^9.35.0
|
||||||
version: 9.35.0
|
version: 9.35.0
|
||||||
'@iconify-json/lucide':
|
|
||||||
specifier: ^1.1.178
|
|
||||||
version: 1.2.66
|
|
||||||
'@iconify/json':
|
'@iconify/json':
|
||||||
specifier: ^2.2.380
|
specifier: ^2.2.380
|
||||||
version: 2.2.380
|
version: 2.2.380
|
||||||
'@iconify/tailwind':
|
|
||||||
specifier: ^1.1.3
|
|
||||||
version: 1.2.0
|
|
||||||
'@intlify/eslint-plugin-vue-i18n':
|
'@intlify/eslint-plugin-vue-i18n':
|
||||||
specifier: ^4.1.0
|
specifier: ^4.1.0
|
||||||
version: 4.1.0
|
version: 4.1.0
|
||||||
@@ -431,9 +425,6 @@ importers:
|
|||||||
extendable-media-recorder-wav-encoder:
|
extendable-media-recorder-wav-encoder:
|
||||||
specifier: ^7.0.129
|
specifier: ^7.0.129
|
||||||
version: 7.0.129
|
version: 7.0.129
|
||||||
fast-glob:
|
|
||||||
specifier: ^3.3.3
|
|
||||||
version: 3.3.3
|
|
||||||
firebase:
|
firebase:
|
||||||
specifier: 'catalog:'
|
specifier: 'catalog:'
|
||||||
version: 11.6.0
|
version: 11.6.0
|
||||||
@@ -7877,8 +7868,8 @@ packages:
|
|||||||
vue-component-type-helpers@3.1.1:
|
vue-component-type-helpers@3.1.1:
|
||||||
resolution: {integrity: sha512-B0kHv7qX6E7+kdc5nsaqjdGZ1KwNKSUQDWGy7XkTYT7wFsOpkEyaJ1Vq79TjwrrtuLRgizrTV7PPuC4rRQo+vw==}
|
resolution: {integrity: sha512-B0kHv7qX6E7+kdc5nsaqjdGZ1KwNKSUQDWGy7XkTYT7wFsOpkEyaJ1Vq79TjwrrtuLRgizrTV7PPuC4rRQo+vw==}
|
||||||
|
|
||||||
vue-component-type-helpers@3.1.4:
|
vue-component-type-helpers@3.1.5:
|
||||||
resolution: {integrity: sha512-Uws7Ew1OzTTqHW8ZVl/qLl/HB+jf08M0NdFONbVWAx0N4gMLK8yfZDgeB77hDnBmaigWWEn5qP8T9BG59jIeyQ==}
|
resolution: {integrity: sha512-7V3yJuNWW7/1jxCcI1CswnpDsvs02Qcx/N43LkV+ZqhLj2PKj50slUflHAroNkN4UWiYfzMUUUXiNuv9khmSpQ==}
|
||||||
|
|
||||||
vue-demi@0.14.10:
|
vue-demi@0.14.10:
|
||||||
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
|
resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
|
||||||
@@ -10681,7 +10672,7 @@ snapshots:
|
|||||||
storybook: 9.1.6(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@5.4.19(@types/node@20.14.10)(lightningcss@1.30.1)(terser@5.39.2))
|
storybook: 9.1.6(@testing-library/dom@10.4.1)(prettier@3.6.2)(vite@5.4.19(@types/node@20.14.10)(lightningcss@1.30.1)(terser@5.39.2))
|
||||||
type-fest: 2.19.0
|
type-fest: 2.19.0
|
||||||
vue: 3.5.13(typescript@5.9.2)
|
vue: 3.5.13(typescript@5.9.2)
|
||||||
vue-component-type-helpers: 3.1.4
|
vue-component-type-helpers: 3.1.5
|
||||||
|
|
||||||
'@swc/helpers@0.5.17':
|
'@swc/helpers@0.5.17':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -16448,7 +16439,7 @@ snapshots:
|
|||||||
|
|
||||||
vue-component-type-helpers@3.1.1: {}
|
vue-component-type-helpers@3.1.1: {}
|
||||||
|
|
||||||
vue-component-type-helpers@3.1.4: {}
|
vue-component-type-helpers@3.1.5: {}
|
||||||
|
|
||||||
vue-demi@0.14.10(vue@3.5.13(typescript@5.9.2)):
|
vue-demi@0.14.10(vue@3.5.13(typescript@5.9.2)):
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import type { ProxyOptions, UserConfig } from 'vite'
|
|||||||
import { createHtmlPlugin } from 'vite-plugin-html'
|
import { createHtmlPlugin } from 'vite-plugin-html'
|
||||||
import vueDevTools from 'vite-plugin-vue-devtools'
|
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||||
|
|
||||||
import { comfyAPIPlugin, generateImportMapPlugin } from './build/plugins'
|
import { comfyAPIPlugin } from './build/plugins'
|
||||||
|
|
||||||
dotenvConfig()
|
dotenvConfig()
|
||||||
|
|
||||||
@@ -318,47 +318,6 @@ export default defineConfig({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Skip import-map generation for cloud builds to keep bundle small
|
|
||||||
...(DISTRIBUTION !== 'cloud'
|
|
||||||
? [
|
|
||||||
generateImportMapPlugin([
|
|
||||||
{
|
|
||||||
name: 'vue',
|
|
||||||
pattern: 'vue',
|
|
||||||
entry: './dist/vue.esm-browser.prod.js'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'vue-i18n',
|
|
||||||
pattern: 'vue-i18n',
|
|
||||||
entry: './dist/vue-i18n.esm-browser.prod.js'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'primevue',
|
|
||||||
pattern: /^primevue\/?.*/,
|
|
||||||
entry: './index.mjs',
|
|
||||||
recursiveDependence: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '@primevue/themes',
|
|
||||||
pattern: /^@primevue\/themes\/?.*/,
|
|
||||||
entry: './index.mjs',
|
|
||||||
recursiveDependence: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '@primevue/forms',
|
|
||||||
pattern: /^@primevue\/forms\/?.*/,
|
|
||||||
entry: './index.mjs',
|
|
||||||
recursiveDependence: true,
|
|
||||||
override: {
|
|
||||||
'@primeuix/forms': {
|
|
||||||
entry: ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
])
|
|
||||||
]
|
|
||||||
: []),
|
|
||||||
|
|
||||||
Icons({
|
Icons({
|
||||||
compiler: 'vue3',
|
compiler: 'vue3',
|
||||||
customCollections: {
|
customCollections: {
|
||||||
|
|||||||
Reference in New Issue
Block a user