Skip to content

Conversation

christian-byrne
Copy link
Contributor

@christian-byrne christian-byrne commented Oct 12, 2025

Summary

Establishes distribution-specific code pattern using compile-time constants and dead code elimination. Demonstrates with Help Center by hiding extension manager and update buttons in cloud distribution.

Below commentary makes assumption that minifcation and tree-shaking is enabled (which isn't true yet, but will be eventually).

Changes

  • What: Added src/platform/distribution/types.ts with distribution detection via __DISTRIBUTION__ variable
  • Build: Vite replaces __DISTRIBUTION__ at build time using environment variables
  • Tree-shaking: All code not relevant to target distribution is DCR'd and eliminated from bundle
  • Example: Help Center hides "Manager Extension" menu item and "Update" buttons in cloud builds

Pattern

This PR defines a __DISTRIBUTION__ variable which gets replaced at build time by Vite using environment variables. All code not relevant to the given distribution is then DCR'd and tree-shaken.

For simple cases (like this Help Center PR), import isCloud and use compile-time conditionals:

import { isCloud } from '@/platform/distribution/types'

if (!isCloud) {
  items.push({
    key: 'manager',
    action: async () => {
      await useManagerState().openManager({ ... })
    }
  })
}

The code is DCR'd at build time so there's zero runtime overhead - we don't even incur the if (isCloud) cost because Terser eliminates it.

For complex services later, we'll add interfaces and use an index.ts that exports different implementations under the same alias per distribution. It will resemble a DI container but simpler since we don't need runtime discovery like backend devs do. This guarantees types and makes testing easier.

Example for services:

// src/platform/storage/index.ts
import { isCloud } from '@/platform/distribution/types'

if (isCloud) {
  export { CloudStorage as StorageService } from './cloud'
} else {
  export { LocalStorage as StorageService } from './local'
}

Example for component variants:

// src/components/downloads/index.ts
import { isCloud } from '@/platform/distribution/types'

if (isCloud) {
  export { default as DownloadButton } from './DownloadButton.cloud.vue'
} else {
  export { default as DownloadButton } from './DownloadButton.desktop.vue'
}

Implementation Details

Distribution types (src/platform/distribution/types.ts):

type Distribution = 'desktop' | 'localhost' | 'cloud'

declare global {
  const __DISTRIBUTION__: Distribution
}

const DISTRIBUTION: Distribution = __DISTRIBUTION__
export const isCloud = DISTRIBUTION === 'cloud'

Vite configuration adds the define:

const DISTRIBUTION = (process.env.DISTRIBUTION || 'localhost') as
  | 'desktop'
  | 'localhost'
  | 'cloud'

export default defineConfig({
  define: {
    __DISTRIBUTION__: JSON.stringify(DISTRIBUTION)
  }
})

Build Commands

pnpm build                      # localhost (default)
DISTRIBUTION=cloud pnpm build   # cloud
DISTRIBUTION=desktop pnpm build # desktop

Future Applications

This pattern can be used with auth or telemetry services - which will guarantee all the telemetry code, for example, is not even in the code distributed in OSS Comfy whatsoever while still being able to develop off main.

┆Issue is synchronized with this Notion page by Unito

@dosubot dosubot bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Oct 12, 2025
Copy link

github-actions bot commented Oct 12, 2025

🎨 Storybook Build Status

Build completed successfully!

⏰ Completed at: 10/12/2025, 04:12:27 AM UTC

🔗 Links


🎉 Your Storybook is ready for review!

Copy link

github-actions bot commented Oct 12, 2025

🎭 Playwright Test Results

⚠️ Tests passed with flaky tests

⏰ Completed at: 10/12/2025, 04:27:10 AM UTC

📈 Summary

  • Total Tests: 497
  • Passed: 465 ✅
  • Failed: 0
  • Flaky: 2 ⚠️
  • Skipped: 30 ⏭️

📊 Test Reports by Browser

  • chromium: View Report • ✅ 456 / ❌ 0 / ⚠️ 2 / ⏭️ 30
  • chromium-2x: View Report • ✅ 2 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • chromium-0.5x: View Report • ✅ 1 / ❌ 0 / ⚠️ 0 / ⏭️ 0
  • mobile-chrome: View Report • ✅ 6 / ❌ 0 / ⚠️ 0 / ⏭️ 0

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

@christian-byrne
Copy link
Contributor Author

Merging now so others can use - please still leave any review if you have it and I'll address in followups.

@christian-byrne christian-byrne merged commit 9c245e9 into main Oct 12, 2025
38 of 39 checks passed
@christian-byrne christian-byrne deleted the platform-distribution-var branch October 12, 2025 06:10
@arjansingh arjansingh mentioned this pull request Oct 14, 2025
arjansingh added a commit that referenced this pull request Oct 14, 2025
## What's Changed

### 🚀 Features
- Add MediaAssetCard presentation components (#5878)
- Make Vue nodes' outputs/previews responsively sized and work with node
resizing (#5970)
- Allow connection to subgraphIOs in vue mode (#6016)
- Add distribution detection pattern (#6028)
- Make nodeData.widgets reactive (#6019)

### 🐛 Bug Fixes
- Fix FLOAT widget incrementing broken & disabled state styles on widget
number input (Vue) (#6036)
- Fix Vue node border styles in different states (executing, error,
selected) (#6018)
- Fix Vue node opacity conditions (user node opacity, bypass state,
muted state) (#6022)
- Fix: emit layout change for batch node bounds (#5939)
- Safer restoration of widgets_values on subgraph nodes (#6015)
- Fix(execution): reset progress state after runs to unfreeze tab
title/favicon (main) (#6026)
- Use type check instead of cast (#6041)

### 🎨 Style & Design
- [style] match widget border/outline styles with designs (#6021)
- [style] make Vue widget/slot/label width and spacing align with
designs (#6023)

### ♿ Accessibility
- Add aria labels on vue node widgets (#6032)

### 🔧 Maintenance
- [refactor] adjust Vue node fixtures to not be coupled to Litegraph
(#6033)
- [refactor] reorganize devtools test nodes into modules (#6020)

### 🧪 Testing
- [test] add browser test for control+a selection of Vue nodes (#6031)

### 🔄 CI/CD
- [ci] fix update locales workflow (#6017)

**Full Changelog**:
v1.29.1...v1.29.2

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6045-1-29-2-28c6d73d3650817a8c36fba944ce69a8)
by [Unito](https://www.unito.io)

---------

Co-authored-by: arjansingh <[email protected]>
Co-authored-by: github-actions <[email protected]>
arjansingh pushed a commit that referenced this pull request Oct 16, 2025
## Summary

Establishes distribution-specific code pattern using compile-time
constants and dead code elimination. Demonstrates with Help Center by
hiding extension manager and update buttons in cloud distribution.

Below commentary makes assumption that minifcation and tree-shaking is
enabled (which isn't true yet, but will be eventually).

## Changes

- **What**: Added `src/platform/distribution/types.ts` with distribution
detection via `__DISTRIBUTION__` variable
- **Build**: Vite replaces `__DISTRIBUTION__` at build time using
environment variables
- **Tree-shaking**: All code not relevant to target distribution is
DCR'd and eliminated from bundle
- **Example**: Help Center hides "Manager Extension" menu item and
"Update" buttons in cloud builds

## Pattern

This PR defines a `__DISTRIBUTION__` variable which gets replaced at
build time by Vite using environment variables. All code not relevant to
the given distribution is then DCR'd and tree-shaken.

For simple cases (like this Help Center PR), import `isCloud` and use
compile-time conditionals:

```typescript
import { isCloud } from '@/platform/distribution/types'

if (!isCloud) {
  items.push({
    key: 'manager',
    action: async () => {
      await useManagerState().openManager({ ... })
    }
  })
}
```

The code is DCR'd at build time so there's zero runtime overhead - we
don't even incur the `if (isCloud)` cost because Terser eliminates it.

For complex services later, we'll add interfaces and use an index.ts
that exports different implementations under the same alias per
distribution. It will resemble a DI container but simpler since we don't
need runtime discovery like backend devs do. This guarantees types and
makes testing easier.

Example for services:
```typescript
// src/platform/storage/index.ts
import { isCloud } from '@/platform/distribution/types'

if (isCloud) {
  export { CloudStorage as StorageService } from './cloud'
} else {
  export { LocalStorage as StorageService } from './local'
}
```

Example for component variants:
```typescript
// src/components/downloads/index.ts
import { isCloud } from '@/platform/distribution/types'

if (isCloud) {
  export { default as DownloadButton } from './DownloadButton.cloud.vue'
} else {
  export { default as DownloadButton } from './DownloadButton.desktop.vue'
}
```

## Implementation Details

Distribution types (`src/platform/distribution/types.ts`):
```typescript
type Distribution = 'desktop' | 'localhost' | 'cloud'

declare global {
  const __DISTRIBUTION__: Distribution
}

const DISTRIBUTION: Distribution = __DISTRIBUTION__
export const isCloud = DISTRIBUTION === 'cloud'
```

Vite configuration adds the define:
```typescript
const DISTRIBUTION = (process.env.DISTRIBUTION || 'localhost') as
  | 'desktop'
  | 'localhost'
  | 'cloud'

export default defineConfig({
  define: {
    __DISTRIBUTION__: JSON.stringify(DISTRIBUTION)
  }
})
```

## Build Commands

```bash
pnpm build                      # localhost (default)
DISTRIBUTION=cloud pnpm build   # cloud
DISTRIBUTION=desktop pnpm build # desktop
```

## Future Applications

This pattern can be used with auth or telemetry services - which will
guarantee all the telemetry code, for example, is not even in the code
distributed in OSS Comfy whatsoever while still being able to develop
off `main`.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6028-Add-distribution-detection-pattern-28a6d73d365081b08767d395472cd1bc)
by [Unito](https://www.unito.io)
arjansingh added a commit that referenced this pull request Oct 17, 2025
## Summary

Updates with cloud specific features merged into `main`.

Notable changes include the `DISTRIBUTION=cloud` changes. Will also be
changing cloud build workflow to build with that flag in
Comfy-Org/cloud#1043

## Changes

- bb61d98 feat: AssetCard tweaks (#6085)
- 05f7352 fix terminal style (#6056)
- d5fa221 Add distribution detection pattern (#6028)
- 6c36aaa feat: Improve MediaAssetCard video controls and add gallery
view (#6065)
- 6944ef0 fix Cloudbadge (#6063)
- 6764f8d Badge for cloud environment (#6048)

---------

Co-authored-by: Johnpaul Chiwetelu <[email protected]>
Co-authored-by: Jin Yi <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: Christian Byrne <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:CI/CD area:cloud area:desktop size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant