Compare commits

...

6 Commits

Author SHA1 Message Date
snomiao
9ed91c197f [test] Improve shimFiles.test.ts to work with standard dist folder
- Use standard `dist` folder instead of hardcoded `dist-treeshake-*` paths
- Add fallback logic to check multiple dist directory candidates
- Remove local-only comparison test between treeshake-enabled/disabled builds
- Add helper test to verify dist directory is found

This ensures tests work in CI/CD environments where only the standard
`dist` folder exists, while still supporting local debugging builds.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-17 00:55:15 +00:00
sno
c0b80dc750 Merge branch 'main' into sno-enable-treeshake 2025-10-17 09:49:24 +09:00
snomiao
5216c0da9f [test] Add comprehensive shim files export tests
Added unit tests to verify that treeshaking doesn't break the public API exposed through shim files in the dist folder. Tests check:
- All core shim files exist (api.js, app.js, changeTracker.js, etc.)
- Each shim file contains proper exports from window.comfyAPI
- UI subdirectory shim files are present and valid
- Metadata subdirectory shim files are present and valid
- Treeshake-enabled and treeshake-disabled builds have identical shim files

This ensures backward compatibility when treeshaking is enabled and prevents breaking changes to the extension API.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 15:34:11 +00:00
GitHub Action
fdee6a51f6 [automated] Apply ESLint and Prettier fixes 2025-10-15 19:46:38 +00:00
snomiao
4b2c29c320 [bugfix] Fix ESLint config conflict for vite.config.mts
Removed vite.config.mts from tsconfig.json include array to resolve ESLint parsing error. The file is already configured via eslint.config.ts allowDefaultProject, and being in both locations caused a conflict. This fixes the CI lint-and-format check failure.
2025-10-15 19:40:51 +00:00
snomiao
8debaf922b fix: enable treeshaking\n\nRemoved explicit disablement of treeshaking in vite.config.mts by deleting rollupOptions.treeshake: false. Treeshaking is now enabled by default, allowing the bundler to prune unused exports and potentially reduce bundle size. This aligns with Vite/Rollup defaults and does not introduce breaking changes. 2025-10-15 19:40:51 +00:00
4 changed files with 251 additions and 7 deletions

1
.gitignore vendored
View File

@@ -19,6 +19,7 @@ yarn.lock
node_modules
dist
/dist*/
dist-ssr
*.local
# Claude configuration

View File

@@ -0,0 +1,249 @@
import fs from 'fs'
import path from 'path'
import { describe, expect, it } from 'vitest'
/**
* Test suite to verify that shim files exist in the dist folder and all exports are accessible.
* This ensures that treeshaking doesn't break the public API exposed through shim files.
*
* These are static file tests that don't require the browser or ComfyUI backend to be running.
*/
// Use standard dist folder (built by CI/CD and normal builds)
// Falls back to local debug builds if available
const findDistDir = (): string | null => {
const candidates = [
path.join(__dirname, '../../dist'),
path.join(__dirname, '../../dist-treeshake-enabled'),
path.join(__dirname, '../../dist-treeshake-disabled')
]
for (const dir of candidates) {
if (fs.existsSync(dir) && fs.existsSync(path.join(dir, 'scripts'))) {
return dir
}
}
return null
}
const DIST_DIR = findDistDir()
const SCRIPTS_DIR = DIST_DIR ? path.join(DIST_DIR, 'scripts') : ''
// Skip these tests if dist folder doesn't exist (e.g., during development before build)
const distExists = DIST_DIR !== null
describe.skipIf(!distExists)('Shim Files Exports', () => {
it('should find a valid dist directory', () => {
expect(DIST_DIR).toBeTruthy()
expect(fs.existsSync(SCRIPTS_DIR)).toBe(true)
})
describe('Core shim files should exist', () => {
const coreShimFiles = [
'api.js',
'app.js',
'changeTracker.js',
'defaultGraph.js',
'domWidget.js',
'pnginfo.js',
'ui.js',
'utils.js',
'widgets.js'
]
coreShimFiles.forEach((file) => {
it(`${file} should exist`, () => {
const filePath = path.join(SCRIPTS_DIR, file)
expect(fs.existsSync(filePath)).toBe(true)
})
})
})
describe('API shim file exports', () => {
it('should contain all required exports', () => {
const filePath = path.join(SCRIPTS_DIR, 'api.js')
const content = fs.readFileSync(filePath, 'utf-8')
expect(content).toContain('// Shim for scripts/api.ts')
expect(content).toContain('export const UnauthorizedError')
expect(content).toContain('export const PromptExecutionError')
expect(content).toContain('export const ComfyApi')
expect(content).toContain('export const api')
expect(content).toContain('window.comfyAPI.api')
})
})
describe('App shim file exports', () => {
it('should contain all required exports', () => {
const filePath = path.join(SCRIPTS_DIR, 'app.js')
const content = fs.readFileSync(filePath, 'utf-8')
expect(content).toContain('// Shim for scripts/app.ts')
expect(content).toContain('export const ANIM_PREVIEW_WIDGET')
expect(content).toContain('export const ComfyApp')
expect(content).toContain('export const app')
expect(content).toContain('window.comfyAPI.app')
})
})
describe('ChangeTracker shim file exports', () => {
it('should contain all required exports', () => {
const filePath = path.join(SCRIPTS_DIR, 'changeTracker.js')
const content = fs.readFileSync(filePath, 'utf-8')
expect(content).toContain('// Shim for scripts/changeTracker.ts')
expect(content).toContain('export const ChangeTracker')
expect(content).toContain('window.comfyAPI.changeTracker')
})
})
describe('DefaultGraph shim file exports', () => {
it('should contain all required exports', () => {
const filePath = path.join(SCRIPTS_DIR, 'defaultGraph.js')
const content = fs.readFileSync(filePath, 'utf-8')
expect(content).toContain('// Shim for scripts/defaultGraph.ts')
expect(content).toContain('export const defaultGraph')
expect(content).toContain('export const defaultGraphJSON')
expect(content).toContain('export const blankGraph')
expect(content).toContain('window.comfyAPI.defaultGraph')
})
})
describe('DomWidget shim file exports', () => {
it('should contain all required exports', () => {
const filePath = path.join(SCRIPTS_DIR, 'domWidget.js')
const content = fs.readFileSync(filePath, 'utf-8')
expect(content).toContain('// Shim for scripts/domWidget.ts')
expect(content).toContain('export const isDOMWidget')
expect(content).toContain('export const isComponentWidget')
expect(content).toContain('export const DOMWidgetImpl')
expect(content).toContain('export const ComponentWidgetImpl')
expect(content).toContain('export const addWidget')
expect(content).toContain('window.comfyAPI.domWidget')
})
})
describe('Pnginfo shim file exports', () => {
it('should contain all required exports', () => {
const filePath = path.join(SCRIPTS_DIR, 'pnginfo.js')
const content = fs.readFileSync(filePath, 'utf-8')
expect(content).toContain('// Shim for scripts/pnginfo.ts')
expect(content).toContain('export const getPngMetadata')
expect(content).toContain('export const getFlacMetadata')
expect(content).toContain('export const getAvifMetadata')
expect(content).toContain('export const getWebpMetadata')
expect(content).toContain('export const getLatentMetadata')
expect(content).toContain('export const importA1111')
expect(content).toContain('window.comfyAPI.pnginfo')
})
})
describe('UI shim file exports', () => {
it('should contain all required exports', () => {
const filePath = path.join(SCRIPTS_DIR, 'ui.js')
const content = fs.readFileSync(filePath, 'utf-8')
expect(content).toContain('// Shim for scripts/ui.ts')
expect(content).toContain('export const ComfyDialog')
expect(content).toContain('export const $el')
expect(content).toContain('export const ComfyUI')
expect(content).toContain('window.comfyAPI.ui')
})
})
describe('Utils shim file exports', () => {
it('should contain all required exports', () => {
const filePath = path.join(SCRIPTS_DIR, 'utils.js')
const content = fs.readFileSync(filePath, 'utf-8')
expect(content).toContain('// Shim for scripts/utils.ts')
expect(content).toContain('export const clone')
expect(content).toContain('export const applyTextReplacements')
expect(content).toContain('export const addStylesheet')
expect(content).toContain('export const downloadBlob')
expect(content).toContain('export const uploadFile')
expect(content).toContain('export const prop')
expect(content).toContain('export const getStorageValue')
expect(content).toContain('export const setStorageValue')
expect(content).toContain('window.comfyAPI.utils')
})
})
describe('Widgets shim file exports', () => {
it('should contain all required exports', () => {
const filePath = path.join(SCRIPTS_DIR, 'widgets.js')
const content = fs.readFileSync(filePath, 'utf-8')
expect(content).toContain('// Shim for scripts/widgets.ts')
expect(content).toContain('export const updateControlWidgetLabel')
expect(content).toContain('export const IS_CONTROL_WIDGET')
expect(content).toContain('export const addValueControlWidget')
expect(content).toContain('export const addValueControlWidgets')
expect(content).toContain('export const ComfyWidgets')
expect(content).toContain('window.comfyAPI.widgets')
})
})
describe('UI subdirectory shim files', () => {
const uiShimFiles = [
'ui/components/asyncDialog.js',
'ui/components/button.js',
'ui/components/buttonGroup.js',
'ui/components/popup.js',
'ui/components/splitButton.js',
'ui/dialog.js',
'ui/draggableList.js',
'ui/imagePreview.js',
'ui/menu/index.js',
'ui/settings.js',
'ui/toggleSwitch.js',
'ui/utils.js'
]
uiShimFiles.forEach((file) => {
it(`${file} should exist`, () => {
const filePath = path.join(SCRIPTS_DIR, file)
expect(fs.existsSync(filePath)).toBe(true)
})
it(`${file} should be a valid shim file`, () => {
const filePath = path.join(SCRIPTS_DIR, file)
const content = fs.readFileSync(filePath, 'utf-8')
expect(content).toContain('window.comfyAPI')
expect(content).toContain('export const')
})
})
})
describe('Metadata subdirectory shim files', () => {
const metadataShimFiles = [
'metadata/avif.js',
'metadata/ebml.js',
'metadata/flac.js',
'metadata/gltf.js',
'metadata/isobmff.js',
'metadata/mp3.js',
'metadata/ogg.js',
'metadata/png.js',
'metadata/svg.js'
]
metadataShimFiles.forEach((file) => {
it(`${file} should exist`, () => {
const filePath = path.join(SCRIPTS_DIR, file)
expect(fs.existsSync(filePath)).toBe(true)
})
it(`${file} should be a valid shim file`, () => {
const filePath = path.join(SCRIPTS_DIR, file)
const content = fs.readFileSync(filePath, 'utf-8')
expect(content).toContain('window.comfyAPI')
expect(content).toContain('export const')
})
})
})
})

View File

@@ -58,7 +58,6 @@
"src/types/**/*.d.ts",
"tailwind.config.ts",
"tests-ui/**/*",
"vite.config.mts",
"vitest.config.ts",
// "vitest.setup.ts",
]

View File

@@ -185,12 +185,7 @@ export default defineConfig({
build: {
minify: SHOULD_MINIFY ? 'esbuild' : false,
target: 'es2022',
sourcemap: true,
rollupOptions: {
// Disabling tree-shaking
// Prevent vite remove unused exports
treeshake: false
}
sourcemap: true
},
esbuild: {