mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-09 07:00:06 +00:00
fix: resolve collect-i18n babel transformation issues
- Created configurable babel-plugin-inject-globals to inject browser setup - Added setup-browser-globals.mjs for browser environment mocking - Moved babel plugin files to scripts directory for better organization - Removed dependency on import order by using babel transformation - Made plugin options configurable (filenamePattern, setupFile) - Updated tsconfig.json to include playwright config and scripts This fixes the ReferenceError: location is not defined issue that occurred when running pnpm collect-i18n, ensuring the command works reliably regardless of import auto-sorting. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
30
scripts/babel-plugin-inject-globals.cjs
Normal file
30
scripts/babel-plugin-inject-globals.cjs
Normal file
@@ -0,0 +1,30 @@
|
||||
module.exports = function(babel) {
|
||||
const { types: t } = babel;
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
Program(path, state) {
|
||||
// Get options from plugin configuration
|
||||
const opts = state.opts || {};
|
||||
const filenamePattern = opts.filenamePattern || DIE('filenamePattern option is required');
|
||||
const setupFile = opts.setupFile || DIE('setupFile option is required');
|
||||
|
||||
// Only inject the setup for matching test files
|
||||
if (state.filename?.match(filenamePattern)) {
|
||||
// Create an import statement for the setup file
|
||||
const importDeclaration = t.importDeclaration(
|
||||
[],
|
||||
t.stringLiteral(setupFile)
|
||||
);
|
||||
|
||||
// Insert the import at the beginning of the file
|
||||
path.node.body.unshift(importDeclaration);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
function DIE(msg) {
|
||||
throw new Error(msg);
|
||||
}
|
||||
32
scripts/babel-plugin-stub-vue-imports.cjs
Normal file
32
scripts/babel-plugin-stub-vue-imports.cjs
Normal file
@@ -0,0 +1,32 @@
|
||||
module.exports = function(babel) {
|
||||
const { types: t } = babel;
|
||||
|
||||
return {
|
||||
visitor: {
|
||||
ImportDeclaration(path) {
|
||||
const source = path.node.source.value;
|
||||
|
||||
// Handle Vue files
|
||||
if (source.endsWith('.vue')) {
|
||||
const specifiers = path.node.specifiers;
|
||||
if (specifiers.length > 0 && specifiers[0].type === 'ImportDefaultSpecifier') {
|
||||
const name = specifiers[0].local.name;
|
||||
// Replace with a variable declaration
|
||||
path.replaceWith(
|
||||
t.variableDeclaration('const', [
|
||||
t.variableDeclarator(
|
||||
t.identifier(name),
|
||||
t.objectExpression([])
|
||||
)
|
||||
])
|
||||
);
|
||||
}
|
||||
}
|
||||
// Handle CSS files - just remove the import
|
||||
else if (source.endsWith('.css') || source.endsWith('.scss') || source.endsWith('.less')) {
|
||||
path.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -7,7 +7,6 @@ import { SERVER_CONFIG_ITEMS } from '../src/constants/serverConfig'
|
||||
import type { ComfyCommandImpl } from '../src/stores/commandStore'
|
||||
import type { FormItem, SettingParams } from '../src/platform/settings/types'
|
||||
import { formatCamelCase, normalizeI18nKey } from '../src/utils/formatUtil'
|
||||
import './setup-browser-globals.js'
|
||||
|
||||
const localePath = './src/locales/en/main.json'
|
||||
const commandsPath = './src/locales/en/commands.json'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// Setup browser globals before any other imports that might use them
|
||||
import * as fs from 'fs'
|
||||
|
||||
import { comfyPageFixture as test } from '../browser_tests/fixtures/ComfyPage'
|
||||
@@ -6,7 +5,6 @@ import type { ComfyNodeDef } from '../src/schemas/nodeDefSchema'
|
||||
import type { ComfyApi } from '../src/scripts/api'
|
||||
import { ComfyNodeDefImpl } from '../src/stores/nodeDefStore'
|
||||
import { normalizeI18nKey } from '../src/utils/formatUtil'
|
||||
import './setup-browser-globals.js'
|
||||
|
||||
const localePath = './src/locales/en/main.json'
|
||||
const nodeDefsPath = './src/locales/en/nodeDefs.json'
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
// Setup browser-like globals for Node.js environment
|
||||
import { Window } from 'happy-dom'
|
||||
import { createRequire } from 'module';
|
||||
const require = createRequire(import.meta.url);
|
||||
const { Window } = require('happy-dom');
|
||||
|
||||
// Set build-time constants
|
||||
global.__USE_PROD_CONFIG__ = false
|
||||
global.__USE_LOCAL_SERVER__ = true
|
||||
global.__RUN_TESTS__ = true
|
||||
global.__USE_PROD_CONFIG__ = false;
|
||||
global.__USE_LOCAL_SERVER__ = true;
|
||||
global.__RUN_TESTS__ = true;
|
||||
|
||||
const window = new Window({
|
||||
url: 'http://localhost:5173',
|
||||
width: 1024,
|
||||
height: 768
|
||||
})
|
||||
});
|
||||
|
||||
global.window = window
|
||||
global.document = window.document
|
||||
global.location = window.location
|
||||
global.window = window;
|
||||
global.document = window.document;
|
||||
global.location = window.location;
|
||||
// Don't set navigator if it's read-only
|
||||
if (!global.navigator || Object.getOwnPropertyDescriptor(global, 'navigator')?.set) {
|
||||
global.navigator = window.navigator
|
||||
global.navigator = window.navigator;
|
||||
}
|
||||
global.HTMLElement = window.HTMLElement
|
||||
global.Element = window.Element
|
||||
global.CustomEvent = window.CustomEvent
|
||||
global.requestAnimationFrame = window.requestAnimationFrame
|
||||
global.HTMLElement = window.HTMLElement;
|
||||
global.Element = window.Element;
|
||||
global.CustomEvent = window.CustomEvent;
|
||||
global.requestAnimationFrame = window.requestAnimationFrame;
|
||||
|
||||
// Use happy-dom's storage implementations
|
||||
global.localStorage = window.localStorage
|
||||
global.sessionStorage = window.sessionStorage
|
||||
global.localStorage = window.localStorage;
|
||||
global.sessionStorage = window.sessionStorage;
|
||||
|
||||
// Mock fetch if not available
|
||||
if (!global.fetch) {
|
||||
@@ -37,7 +39,7 @@ if (!global.fetch) {
|
||||
blob: () => Promise.resolve(new Blob()),
|
||||
arrayBuffer: () => Promise.resolve(new ArrayBuffer(0)),
|
||||
headers: new Map()
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Mock ResizeObserver
|
||||
@@ -45,7 +47,7 @@ global.ResizeObserver = class ResizeObserver {
|
||||
observe() {}
|
||||
unobserve() {}
|
||||
disconnect() {}
|
||||
}
|
||||
};
|
||||
|
||||
// Mock IntersectionObserver
|
||||
global.IntersectionObserver = class IntersectionObserver {
|
||||
@@ -53,10 +55,10 @@ global.IntersectionObserver = class IntersectionObserver {
|
||||
observe() {}
|
||||
unobserve() {}
|
||||
disconnect() {}
|
||||
}
|
||||
};
|
||||
|
||||
// Mock getComputedStyle
|
||||
global.getComputedStyle = window.getComputedStyle
|
||||
global.getComputedStyle = window.getComputedStyle;
|
||||
|
||||
// Mock createRange
|
||||
global.document.createRange = () => ({
|
||||
@@ -71,4 +73,4 @@ global.document.createRange = () => ({
|
||||
height: 0
|
||||
}),
|
||||
getClientRects: () => []
|
||||
})
|
||||
});
|
||||
Reference in New Issue
Block a user