Skip to content

fix: make frontend-vite Cloudflare peer optional - #731

Merged
kang-heewon merged 4 commits into
trunkfrom
fix/636-frontend-vite-cloudflare-contract
Jun 14, 2026
Merged

fix: make frontend-vite Cloudflare peer optional#731
kang-heewon merged 4 commits into
trunkfrom
fix/636-frontend-vite-cloudflare-contract

Conversation

@kang-heewon

@kang-heewon kang-heewon commented Jun 14, 2026

Copy link
Copy Markdown
Member

Summary

@croco/frontend-vite now treats @cloudflare/vite-plugin as an optional peer that is loaded only when Cloudflare integration is enabled, so consumers can import the root package and use crocoVitePlugin({ cloudflare: false }) without installing the Cloudflare plugin. The default Cloudflare path now emits a clear install diagnostic when the optional peer is absent.

Fixes #636

변경 사항

  • Removed the top-level @cloudflare/vite-plugin runtime import and lazy-load it only for the Cloudflare-enabled path.
  • Declared @cloudflare/vite-plugin as an optional peer dependency and documented the install contract.
  • Updated CrocoViteConfig / crocoVitePlugin() to use Vite PluginOption[], which supports the lazy async plugin path.
  • Extended regression coverage for the default Cloudflare path, cloudflare: false, nested Cloudflare plugin resolution errors, and the copied-dist package entrypoint smoke fixture.
  • Added a patch changeset for @croco/frontend-vite.

Verification

  • pnpm --filter @croco/frontend-vite test - 2 files, 9 tests passed.
  • pnpm --filter @croco/frontend-vite typecheck - passed.
  • pnpm --filter @croco/frontend-vite build - passed.
  • pnpm check - passed.
  • pnpm package-entrypoints:smoke - framework-context CJS/ESM, frontend-vite CJS/ESM, and nested-error smoke passed.
  • pnpm install --lockfile-only --frozen-lockfile - passed.
  • pnpm exec changeset status --since origin/trunk - patch bump reported for @croco/frontend-vite.
  • Pre-push auto-changeset, full test (195 tasks), and full typecheck (194 tasks) passed.

Self-review

  • Correctness/regression: PASS. [frontend-vite] Publish Cloudflare plugin dependency as an explicit consumer contract #636 acceptance is covered by unit tests and the publish-style smoke fixture: package import and cloudflare: false work without the Cloudflare plugin; the default path reports the missing optional peer; and installed Cloudflare plugin nested resolution failures are preserved instead of rewritten.
  • API/security/compatibility/release: PASS. The manifest now exposes the Cloudflare dependency contract as an optional peer, no lockfile update is required under --frozen-lockfile, and the return type is broadened to Vite's supported PluginOption[] for async plugin loading. A patch changeset covers the public package behavior change.
  • Maintainability/minimality: PASS. The implementation is limited to the plugin loader, public type, focused package tests, README contract, changeset, and the existing package-entrypoint smoke script. Independent review found one diagnostic-masking issue; the detector and tests now preserve nested Cloudflare plugin errors.

Risk

Low. Consumers with explicit Plugin[] annotations around crocoVitePlugin() may need to accept Vite's PluginOption[], matching Vite's config contract and enabling the optional lazy load.

Summary by CodeRabbit

릴리스 노트

  • 새로운 기능

    • Cloudflare 통합을 선택적으로 비활성화할 수 있습니다. crocoVitePlugin({ cloudflare: false }) 설정 시 관련 의존성 설치 없이 사용 가능합니다.
  • 버그 수정

    • Cloudflare Vite 플러그인 누락 시 원인 정보를 포함한 더 명확한 진단 메시지가 제공됩니다.
  • 문서/타입

    • crocoVitePlugin 및 설정의 플러그인 타입이 PluginOption 기준으로 정리되었습니다.
    • Cloudflare 누락 문제 타입이 공개 API로 노출됩니다.
  • 기타

    • 패키지 선언 및 스모크 검증이 개선되었습니다.

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kang-heewon, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 47 minutes and 3 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8dd31181-a694-4c67-9346-f087627d3d7f

📥 Commits

Reviewing files that changed from the base of the PR and between 3828434 and 79f8372.

📒 Files selected for processing (2)
  • packages/frontend-vite/src/libs/problems/MissingCloudflareVitePluginProblem.ts
  • packages/frontend-vite/src/tests/crocoVitePlugin.spec.ts
📝 Walkthrough

Walkthrough

@cloudflare/vite-plugin을 optional peer dependency로 재선언하고, crocoVitePlugin()의 Cloudflare 플러그인 import를 정적에서 동적으로 전환한다. 누락 시 명확한 오류를 던지며, cloudflare: false 시 빈 배열을 즉시 반환한다. 관련 타입, 오류 클래스, 테스트, smoke 스크립트, 문서가 함께 갱신된다.

Changes

Cloudflare 플러그인 선택적 peer dependency 전환

Layer / File(s) Summary
타입 및 패키지 매니페스트 변경
packages/frontend-vite/src/libs/types.ts, packages/frontend-vite/package.json
CrocoViteConfig.plugins 타입이 Plugin[]에서 PluginOption[]으로 변경되고, @cloudflare/vite-pluginvitepeerDependencies로 이동되며 peerDependenciesMetaoptional: true가 추가된다.
선택적 의존성 누락 오류 정의
packages/frontend-vite/src/libs/problems/MissingCloudflareVitePluginProblem.ts, packages/frontend-vite/src/index.ts
MissingCloudflareVitePluginProblem 클래스가 추가되어 설치 안내 및 cloudflare: false 옵션 안내를 포함한 명확한 오류 메시지를 정의하고, 패키지 공개 API로 재-export된다.
crocoVitePlugin 동적 import 및 오류 분류 구현
packages/frontend-vite/src/libs/crocoVitePlugin.ts
crocoVitePlugin()cloudflare 비활성 시 빈 배열을 즉시 반환하고, loadCloudflarePlugin()이 동적 import()로 플러그인을 로드하며, isMissingCloudflarePluginError()가 모듈 누락 오류를 분류해 설치 안내 오류로 재던진다.
단위 테스트 갱신 및 신규 테스트 추가
packages/frontend-vite/src/tests/crocoVitePlugin.spec.ts
비동기 resolvePluginOptions 헬퍼로 검증 방식이 변경되고, cloudflare: false 빈 배열 반환, ssr: false 플러그인 포함, 모듈 해석 실패 시 오류 속성 보존 테스트가 추가된다.
엔트리포인트 smoke 스크립트 확장
scripts/package-entrypoint-smoke.mts
runPackageSmoke에서 @croco/frontend-vite 패키지 대상으로 runFrontendViteOptionalPeerSmoke 호출이 추가되고, optionalDependencyNamespeerDependenciesMeta의 optional peer도 포함하도록 확장된다. 깨진 Cloudflare 플러그인 스텁으로 중첩 오류 메시지를 검증하는 시나리오가 추가된다.
문서 및 변경셋 업데이트
packages/frontend-vite/README.md, .changeset/frontend-vite-cloudflare-contract.md
README에 선택적 peer dependency 설치 안내와 PluginOption[] 반환 타입 설명이 추가되고, changeset에 patch 릴리스 항목이 등록되어 선택적 peer dependency 계약을 문서화한다.

Sequence Diagram(s)

sequenceDiagram
  participant Consumer as 소비자 코드
  participant Plugin as crocoVitePlugin()
  participant Loader as loadCloudflarePlugin()
  participant CFPlugin as `@cloudflare/vite-plugin`

  Consumer->>Plugin: crocoVitePlugin({ cloudflare: true, ssr })
  Plugin->>Loader: loadCloudflarePlugin({ ssr })
  Loader->>CFPlugin: dynamic import("`@cloudflare/vite-plugin`")
  alt 모듈 존재
    CFPlugin-->>Loader: { cloudflare } 반환
    Loader-->>Plugin: PluginOption[] 반환
    Plugin-->>Consumer: PluginOption[] 반환
  else 모듈 누락 (ERR_MODULE_NOT_FOUND)
    CFPlugin-->>Loader: ModuleNotFoundError 던지기
    Loader-->>Plugin: MissingCloudflareVitePluginProblem 던지기
    Plugin-->>Consumer: 설치 안내 오류 전파
  end

  Consumer->>Plugin: crocoVitePlugin({ cloudflare: false })
  Plugin-->>Consumer: [] 즉시 반환
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • croco-dev/framework#634: scripts/package-entrypoint-smoke.mts의 엔트리포인트 검증 게이트 추가 흐름이 본 PR의 smoke 스크립트 확장과 코드 수준에서 직접 연결된다.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목 'fix: make frontend-vite Cloudflare peer optional'은 변경의 핵심 목표를 명확하고 간결하게 요약합니다.
Linked Issues check ✅ Passed PR이 issue #636의 모든 요구사항을 충족합니다: package.json에 optional peer dependency 선언, 동적 import로 lazy loading 구현, 테스트 커버리지 확대, 스모크 테스트 추가, 문제 진단 구현.
Out of Scope Changes check ✅ Passed 모든 변경사항이 issue #636의 범위 내에 있으며, Cloudflare peer dependency 계약 정립과 직접 관련이 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/636-frontend-vite-cloudflare-contract

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown

📊 Benchmark Results

❌ Some benchmarks failed

Benchmark p75 Threshold Baseline vs Baseline Status
CrocoApp benchmarks 3.0μs - - - ⚠️
EventBusConfig.start (10 handlers) 1.3μs - 9.0μs -85.6%
EventPublisher.publishNow single event 1.5μs - - - ⚠️
DefaultHandlerResolver.resolve × 10 0.1μs - 0.2μs -64.5%
Container.get singleton (cold) 1.0μs - 0.5μs +90.4%
Container.register × 50 components 11.6μs - 8.0μs +44.8%
Container.validate (50 components) 29.2μs - 25.0μs +16.7%
Container.get singleton (warm) 0.4μs - 0.3μs +40.3%
TelemetryRuntime benchmarks 2.1μs - 2.0μs +4.7%

Updated: 2026-06-14T19:07:42.354Z · Commit: 971a4d6

coderabbitai[bot]
coderabbitai Bot previously requested changes Jun 14, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/frontend-vite/src/libs/crocoVitePlugin.ts`:
- Around line 20-25: The crocoVitePlugin function is throwing a generic Error
instead of a Problem subclass, which violates the RFC 7807 Problem-based error
handling guidelines. Replace the thrown Error with an appropriate Problem
subclass (such as MissingDependencyProblem or a similar existing Problem class
that represents missing peer dependencies) to align with the coding standards
for error handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 03106def-6a05-4477-90f3-7e4ed36e2f20

📥 Commits

Reviewing files that changed from the base of the PR and between 2977874 and e126b60.

📒 Files selected for processing (7)
  • .changeset/frontend-vite-cloudflare-contract.md
  • packages/frontend-vite/README.md
  • packages/frontend-vite/package.json
  • packages/frontend-vite/src/libs/crocoVitePlugin.ts
  • packages/frontend-vite/src/libs/types.ts
  • packages/frontend-vite/src/tests/crocoVitePlugin.spec.ts
  • scripts/package-entrypoint-smoke.mts

Comment thread packages/frontend-vite/src/libs/crocoVitePlugin.ts Outdated
@kang-heewon
kang-heewon force-pushed the fix/636-frontend-vite-cloudflare-contract branch 2 times, most recently from f697ff5 to a239c5e Compare June 14, 2026 18:39
@kang-heewon
kang-heewon force-pushed the fix/636-frontend-vite-cloudflare-contract branch from a239c5e to 3828434 Compare June 14, 2026 18:50
coderabbitai[bot]
coderabbitai Bot previously requested changes Jun 14, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/frontend-vite/src/libs/problems/MissingCloudflareVitePluginProblem.ts`:
- Around line 8-17: The MissingCloudflareVitePluginProblem class constructor is
currently using ProblemCategory.InternalServerError, which represents runtime
server errors (500), but missing optional peer dependencies are
build/configuration-time issues rather than runtime errors. Replace
ProblemCategory.InternalServerError with a more semantically appropriate
category such as BadRequest (400 for build configuration errors),
ValidationError (422 for build setting validation failures), or NotImplemented
(501 for unavailable plugins), depending on which best reflects the nature of
the missing Cloudflare Vite plugin in your system's problem categorization
scheme.

In `@packages/frontend-vite/src/tests/crocoVitePlugin.spec.ts`:
- Around line 77-100: The collectPlugins function does not await Promises within
nested arrays, which could leave unresolved Promises if Vite's PluginOption
contains nested Promise structures. In the collectPlugins function, when
handling the array case (the for loop that iterates through pluginOption array
elements), modify the code to await each nestedPluginOption before passing it to
the recursive collectPlugins call, ensuring all Promise values are resolved
regardless of nesting depth. This will make the helper robust for handling any
combination of nested arrays and Promises that Vite's PluginOption type allows.
- Around line 57-74: The test "should preserve nested module resolution errors
from the cloudflare plugin" currently relies on a module reset happening in a
previous afterEach hook, making it fragile to test execution order or parallel
runs. Add an explicit vi.resetModules() call at the very beginning of this test
function, before the vi.doMock call, to ensure the test has a clean and
independent module state regardless of how tests are ordered or executed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: cd315ea5-dc22-47cd-b7cd-c8e12e4afc9c

📥 Commits

Reviewing files that changed from the base of the PR and between e126b60 and 3828434.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • .changeset/frontend-vite-cloudflare-contract.md
  • packages/frontend-vite/README.md
  • packages/frontend-vite/package.json
  • packages/frontend-vite/src/index.ts
  • packages/frontend-vite/src/libs/crocoVitePlugin.ts
  • packages/frontend-vite/src/libs/problems/MissingCloudflareVitePluginProblem.ts
  • packages/frontend-vite/src/libs/types.ts
  • packages/frontend-vite/src/tests/crocoVitePlugin.spec.ts
  • scripts/package-entrypoint-smoke.mts

Comment thread packages/frontend-vite/src/tests/crocoVitePlugin.spec.ts
Comment thread packages/frontend-vite/src/tests/crocoVitePlugin.spec.ts
@kang-heewon
kang-heewon dismissed stale reviews from coderabbitai[bot] and coderabbitai[bot] June 14, 2026 19:14

Addressed by follow-up commits; all automated review threads are resolved, and the latest review rerun is blocked by prepaid credits.

@kang-heewon
kang-heewon merged commit 8e15939 into trunk Jun 14, 2026
7 of 8 checks passed
@kang-heewon
kang-heewon deleted the fix/636-frontend-vite-cloudflare-contract branch June 14, 2026 19:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[frontend-vite] Publish Cloudflare plugin dependency as an explicit consumer contract

1 participant