Skip to content

Conversation

@snomiao
Copy link
Member

@snomiao snomiao commented Sep 12, 2025

Summary

Fixes babel configuration issues in the Playwright i18n collection script that were causing failures when importing ComfyNodeDefImpl after Vue nodes were introduced to the codebase.

The Problem

The collect-i18n-node-defs.ts script was failing because of an import chain that brings Vue components into Node.js context:

The Import Chain

collect-i18n-node-defs.ts
  ↓ imports
ComfyNodeDefImpl (from src/stores/nodeDefStore.ts)
  ↓ imports at line 19
useSubgraphStore (from src/stores/subgraphStore.ts)
  ↓ imports at line 28
ComfyNodeDefImpl (circular, but also imports other stores)
  ↓ which transitively imports
executionStore.ts
  ↓ imports at line 4
ChatHistoryWidget.vue (Vue component!)

Critical Issue: When babel tries to transform .vue files in Node.js context, it crashes because Vue SFC files are not JavaScript - they're templates that need webpack/rollup loaders, not babel transpilation.

When This Started

This problem began ~3 weeks ago when Vue nodes were introduced in commit 006e6bd57 (PR #4263). Before Vue nodes existed, the import chain didn't include any .vue files, so the script worked fine.

The Solution

This PR implements a robust babel transformation pipeline that:

1. Enhanced Playwright Configuration

  • Configures a proper babel plugin chain with TypeScript transformation, module resolution, and automatic global injection
  • Uses the magic config['@playwright/test'] configuration to control babel transformations
  • Ensures plugins execute in the correct order (module resolver → TypeScript → globals injection)

2. Automatic Browser Globals Injection

  • Created babel-plugin-inject-globals.cjs that automatically injects browser environment setup for matching files
  • Eliminates manual import dependencies and order issues
  • Configurable via file pattern matching

3. Browser Context Evaluation

  • Refactored collect-i18n-node-defs.ts to evaluate imports within browser context using Playwright
  • This avoids Node.js trying to parse Vue components directly
  • Vue components are properly available in the browser environment

4. Cleanup

  • Removed unused babel-plugin-stub-vue-imports.cjs (no longer needed with proper babel configuration)
  • Improved error handling and ESM support in setup scripts

The Learning Journey

Three weeks ago, we decided to pause running 'update locales' on every PR and moved this process to the version-bump-* branches. Later, update-locales started failing.

Initial Attempts That Failed:

  1. First attempt: I thought it was simply due to the new declare syntax in litegraph, so I tried removing declare keywords (PR #5304). However, this immediately caused semantic changes after compiling to JS, causing vitest to fail in unexpected ways.

  2. Second attempt: I tried using regex to strip declare keywords before and after playwright.i18n startup (PR #5297). This worked initially and generated some 'Update locales [skip ci]' commits, but as we merged from origin/main (our team develops very fast!), completely different errors kept appearing, leaving me clueless.

  3. Type Import Investigation: Initially, I suspected the issue was related to type imports being incorrectly included at runtime, so I started working on verbatimModuleSyntax. During this process, I encountered extremely complex circular dependency issues (see PR #5533 comment for detailed analysis).

Circular Dependency Discovery

To investigate circular dependencies in the project, I created a simple import-map visualization tool using D3.js that highlights all circular paths and uses physics models for automatic clustering: snomiao/ComfyUI_frontend-import-map-analyze

This tool helped identify critical circular dependencies like:

  • EmptySubgraphInput → SubgraphInput → SubgraphInputNode → EmptySubgraphInput
  • SubgraphNode → LGraphNode → litegraph.ts → SubgraphNode
  • ....and 100+ more! see - ComfyUI Frontend Import Map

Special thanks to @DrJKL and @webfiltered for their help in completely resolving the type import (verbatimModuleSyntax) issues.

The Breakthrough:

After extensive research on how Playwright, Babel, and Vue work, and with Christian Byrne's suggestion to study Playwright's source code, I discovered the magic config['@playwright/test'] configuration option. This allowed me to finally understand how Playwright handles TypeScript and Vue.

The Key Realization:

After much research into Vue/JSX/Webpack/Rollup, I realized a fundamental difference:

  • React: Can be rendered in Node.js and then hydrated in the browser
  • Vue: .vue files are NOT JavaScript that can be compiled by Babel. They are templates (more like .html files) that should be loaded by webpack/rollup, not transpiled by Babel

The critical insight: We should NEVER import any .vue files in Playwright's Node environment. Instead, they should run entirely in the browser and use page.evaluate() to pass JSON data to the Node environment.

Changes

  • ✨ Added babel-plugin-inject-globals.cjs for automatic browser globals injection
  • 🔧 Enhanced playwright.i18n.config.ts with complete babel transformation pipeline
  • ♻️ Refactored collect-i18n-node-defs.ts to use browser context evaluation
  • 🔥 Removed unused babel-plugin-stub-vue-imports.cjs
  • 📝 Improved error handling and logging throughout

Test Plan

# The i18n collection now works correctly
pnpm collect-i18n

# Verify the collected definitions
cat src/locales/i18n-node-defs.json

Why This Fix Works

Previously, when ComfyNodeDefImpl imported Vue components through the chain shown above, babel would try to transform them in Node.js context and fail. Now:

  1. The babel pipeline properly handles TypeScript and module resolution
  2. Browser globals are automatically injected where needed
  3. Vue-dependent code runs in browser context via Playwright, where Vue is properly available
  4. No more manual stubbing or order-dependent imports

Related Issues

Fixes issues with pnpm collect-i18n failing after Vue nodes were introduced to the codebase.

🤖 Generated with Claude Code

┆Issue is synchronized with this Notion page by Unito

@github-actions
Copy link

github-actions bot commented Sep 12, 2025

🎭 Playwright Test Results

Some tests failed

⏰ Completed at: 09/25/2025, 10:37:33 PM UTC

📈 Summary

  • Total Tests: 461
  • Passed: 429 ✅
  • Failed: 1 ❌
  • Flaky: 2 ⚠️
  • Skipped: 29 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 422 / ❌ 1 / ⚠️ 2 / ⏭️ 29
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 4 / ❌ 0 / ⚠️ 0 / ⏭️ 0

🎉 Click on the links above to view detailed test results for each browser configuration.

@socket-security
Copy link

socket-security bot commented Sep 12, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​babel/​plugin-transform-typescript@​7.27.1 ⏵ 7.28.01001007793100
Addedbabel-plugin-module-resolver@​5.0.29910010080100
Addedes-toolkit@​1.39.91001008997100
Updatedeslint-plugin-vue@​10.4.0 ⏵ 10.5.09910091 +195 +5100
Updatedeslint-plugin-storybook@​9.1.6 ⏵ 9.1.8100 +1100100100 +3100

View full report

@socket-security
Copy link

socket-security bot commented Sep 12, 2025

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report

@github-actions
Copy link

🔧 Auto-fixes Applied

This PR has been automatically updated to fix linting and formatting issues.

⚠️ Important: Your local branch is now behind. Run git pull before making additional changes to avoid conflicts.

Changes made:

  • ESLint auto-fixes
  • Prettier formatting

@snomiao snomiao force-pushed the sno-fix-playwright-babel-config branch from 2f74da7 to 0ae6e26 Compare September 13, 2025 10:21
@github-actions
Copy link

🔧 Auto-fixes Applied

This PR has been automatically updated to fix linting and formatting issues.

⚠️ Important: Your local branch is now behind. Run git pull before making additional changes to avoid conflicts.

Changes made:

  • ESLint auto-fixes
  • Prettier formatting

@snomiao snomiao force-pushed the sno-fix-playwright-babel-config branch 5 times, most recently from e1c0f11 to 9dd7ada Compare September 22, 2025 22:13
snomiao and others added 6 commits September 24, 2025 04:35
- 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 <[email protected]>
- Convert id to string before localeCompare to handle keyof Settings type
- Ensure proper type casting for settings id field
@snomiao snomiao force-pushed the sno-fix-playwright-babel-config branch from c99e92e to 20e1cb0 Compare September 24, 2025 04:36
This was automatically added by linter but causes issues with TypeScript compilation
Keep only the required babel dependencies:
- @babel/plugin-transform-typescript
- babel-plugin-module-resolver

Revert all other unrelated version changes to minimize diff
Update lockfile after reverting unnecessary version changes
@snomiao snomiao marked this pull request as ready for review September 24, 2025 05:22
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Sep 24, 2025
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Sep 24, 2025
@dosubot dosubot bot added size:XXL This PR changes 1000+ lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Sep 24, 2025
update-locales:
# Branch detection: Only run for manual dispatch or version-bump-* branches from main repo
if: github.event_name == 'workflow_dispatch' || (github.event.pull_request.head.repo.full_name == github.repository && startsWith(github.head_ref, 'version-bump-'))
if: github.event_name == 'workflow_dispatch' || (github.event.pull_request.head.repo.full_name == github.repository && (startsWith(github.head_ref, 'version-bump-') || startsWith(github.head_ref, 'sno-fix-playwright-')))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is for testing, can be resotred after/before merge this pr

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably before right?

@snomiao
Copy link
Member Author

snomiao commented Sep 26, 2025

@snomiao snomiao closed this Sep 26, 2025
christian-byrne pushed a commit that referenced this pull request Sep 26, 2025
… browser context (#5775)

## The Problem

The `collect-i18n-node-defs.ts` script started failing ~3 weeks ago when
Vue nodes were introduced ([commit
006e6bd](006e6bd57),
[PR #4263](#4263)).
The issue stems from:

1. **Import chain bringing Vue components into Node.js context:**
   ```
   collect-i18n-node-defs.ts
     ↓ imports
   ComfyNodeDefImpl (from nodeDefStore.ts)
     ↓ imports
   useSubgraphStore (from subgraphStore.ts)
     ↓ transitively imports
   executionStore.ts
     ↓ imports
   ChatHistoryWidget.vue (Vue component!)
   ```

2. **TypeScript `declare` fields causing Babel errors:**
   ```
TypeScript 'declare' fields must first be transformed by
@babel/plugin-transform-typescript
   ```

## This Solution vs PR #5515

### PR #5515 Approach (Complex)
- Adds custom Babel plugins and configurations
- Implements automatic browser globals injection
- Requires **47,517 additions, 9,469 deletions**
- Modifies the entire Playwright babel transformation pipeline

### This PR's Approach (Simple)
- Uses dynamic imports to defer module loading until runtime
- Avoids Babel compilation of problematic TypeScript/Vue files
- **Only 40 lines changed** in a single file
- No configuration changes needed

## How This Fix Works

```typescript
// Instead of static import that Babel tries to compile:
// import { ComfyNodeDefImpl } from '../src/stores/nodeDefStore'

// We use:
// 1. Type-only import (erased at runtime)
import type { ComfyNodeDefImpl } from '../src/stores/nodeDefStore'

// 2. Dynamic import at runtime (bypasses Babel)
const { ComfyNodeDefImpl: ComfyNodeDefImplClass } = await import(
  '../src/stores/nodeDefStore'
)
```

---------

Co-authored-by: github-actions <[email protected]>
christian-byrne pushed a commit that referenced this pull request Sep 27, 2025
… browser context (#5775)

## The Problem

The `collect-i18n-node-defs.ts` script started failing ~3 weeks ago when
Vue nodes were introduced ([commit
006e6bd](006e6bd57),
[PR #4263](#4263)).
The issue stems from:

1. **Import chain bringing Vue components into Node.js context:**
   ```
   collect-i18n-node-defs.ts
     ↓ imports
   ComfyNodeDefImpl (from nodeDefStore.ts)
     ↓ imports
   useSubgraphStore (from subgraphStore.ts)
     ↓ transitively imports
   executionStore.ts
     ↓ imports
   ChatHistoryWidget.vue (Vue component!)
   ```

2. **TypeScript `declare` fields causing Babel errors:**
   ```
TypeScript 'declare' fields must first be transformed by
@babel/plugin-transform-typescript
   ```

## This Solution vs PR #5515

### PR #5515 Approach (Complex)
- Adds custom Babel plugins and configurations
- Implements automatic browser globals injection
- Requires **47,517 additions, 9,469 deletions**
- Modifies the entire Playwright babel transformation pipeline

### This PR's Approach (Simple)
- Uses dynamic imports to defer module loading until runtime
- Avoids Babel compilation of problematic TypeScript/Vue files
- **Only 40 lines changed** in a single file
- No configuration changes needed

## How This Fix Works

```typescript
// Instead of static import that Babel tries to compile:
// import { ComfyNodeDefImpl } from '../src/stores/nodeDefStore'

// We use:
// 1. Type-only import (erased at runtime)
import type { ComfyNodeDefImpl } from '../src/stores/nodeDefStore'

// 2. Dynamic import at runtime (bypasses Babel)
const { ComfyNodeDefImpl: ComfyNodeDefImplClass } = await import(
  '../src/stores/nodeDefStore'
)
```

---------

Co-authored-by: github-actions <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants