feat: add renderer web component build config#53
Conversation
…nto cgm/build-web-component
…/build-web-component
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds a Vue custom element for SchemaCardRenderer: a no-shadow wrapper that parses string attributes into typed props, registration utilities and re-exports, parsing helpers, a dedicated Vite build, npm scripts, and a post-build CSS-variable rename script. ChangesWeb Component for SchemaCardRenderer
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (5)
packages/frameworks/vue/vite.config.web-component.ts (2)
11-17: 💤 Low valueConsider adding a comment to clarify
isCustomElementconfiguration.The
isCustomElement: () => falseconfiguration is correct for this use case (Vue compiles everything as Vue components beforedefineCustomElementwraps them), but it's counter-intuitive for a web component build. A comment would help future maintainers understand the intent.📝 Proposed clarification
vue({ template: { compilerOptions: { + // During compilation, treat all elements as Vue components. + // defineCustomElement will wrap the compiled output as a custom element at runtime. isCustomElement: () => false, }, }, }),🤖 Prompt for 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. In `@packages/frameworks/vue/vite.config.web-component.ts` around lines 11 - 17, Add a brief inline comment above the vue template.compilerOptions isCustomElement configuration explaining why it returns false for the web-component build (Vue compiles everything as Vue components before defineCustomElement wraps them), so future maintainers understand the counter‑intuitive choice; update the block around vue({ template: { compilerOptions: { isCustomElement: () => false } } }) to include that comment referencing isCustomElement and defineCustomElement semantics.
10-10: ⚡ Quick winMake bundle visualizer opt-in for CI/CD compatibility.
visualizer({ open: true })automatically opens the bundle analysis in a browser, which will fail or cause issues in CI/CD environments. Consider making it conditional on the environment or removingopen: true.♻️ Proposed fix
- visualizer({ open: true }), + visualizer({ open: process.env.CI !== 'true' }),Or simply:
- visualizer({ open: true }), + visualizer(),🤖 Prompt for 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. In `@packages/frameworks/vue/vite.config.web-component.ts` at line 10, The visualizer plugin is currently opening a browser unconditionally via visualizer({ open: true }), which breaks CI; change it to be opt-in by guarding either the plugin inclusion or the open flag with an environment check (e.g., use process.env.VISUALIZE or process.env.CI/NODE_ENV) so visualizer is only enabled or open when that env flag is set; update the visualizer invocation (the visualizer(...) call) to remove or conditionally set open: true and/or conditionally include the visualizer plugin in the exported Vite plugins array.packages/frameworks/vue/src/renderer/SchemaCardRenderer.ce.vue (2)
19-54: ⚡ Quick winConsider logging parse errors and extracting the parser logic.
The four computed properties share identical parsing logic. Parse errors are silently ignored, which may make debugging difficult for consumers passing malformed JSON.
Consider:
- Logging warnings when JSON parsing fails (use
console.warnto preserve fallback behavior)- Extracting a shared helper function to reduce duplication
♻️ Proposed refactor with logging and DRY
+// 解析字符串属性为对象,适配 Web Component 的属性传递 +function parseJsonProp(value: string | undefined, propName: string): any { + if (!value) return undefined; + try { + return JSON.parse(value); + } catch (error) { + console.warn(`[SchemaCardRenderer] Failed to parse ${propName}:`, error); + return undefined; + } +} + -// 解析字符串属性为对象,适配 Web Component 的属性传递 const parsedCustomComponents = computed(() => { - if (!props.customComponents) return undefined; - try { - return JSON.parse(props.customComponents); - } catch { - return undefined; - } + return parseJsonProp(props.customComponents, 'customComponents'); }); const parsedCustomActions = computed(() => { - if (!props.customActions) return undefined; - try { - return JSON.parse(props.customActions); - } catch { - return undefined; - } + return parseJsonProp(props.customActions, 'customActions'); }); const parsedRequiredCompleteFieldSelectors = computed(() => { - if (!props.requiredCompleteFieldSelectors) return undefined; - try { - return JSON.parse(props.requiredCompleteFieldSelectors); - } catch { - return undefined; - } + return parseJsonProp(props.requiredCompleteFieldSelectors, 'requiredCompleteFieldSelectors'); }); const parsedState = computed(() => { - if (!props.state) return undefined; - try { - return JSON.parse(props.state); - } catch { - return undefined; - } + return parseJsonProp(props.state, 'state'); });🤖 Prompt for 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. In `@packages/frameworks/vue/src/renderer/SchemaCardRenderer.ce.vue` around lines 19 - 54, The four computed props parsedCustomComponents, parsedCustomActions, parsedRequiredCompleteFieldSelectors, and parsedState all duplicate JSON.parse logic and silently swallow errors; extract a shared helper (e.g., parseJsonProp(value, propName)) and use it inside each computed to remove duplication, and on parse failure call console.warn with the propName and the caught error while still returning undefined to preserve fallback behavior.
56-61: ⚡ Quick winClarify string-to-boolean conversion behavior.
The current logic treats only the string
"true"as booleantrue; all other string values (including"false","1","yes") becomefalse. While this may be intentional for HTML attribute behavior, it could surprise consumers who pass string"false"expecting it to be truthy.Consider adding a comment documenting this behavior, or explicitly handle string
"false":📝 Proposed clarification
+// Convert string attributes to boolean: only "true" string becomes true, all others become false const isGenerating = computed(() => { if (typeof props.generating === 'string') { return props.generating === 'true'; } return props.generating || false; });Or, if you want to be more explicit:
const isGenerating = computed(() => { if (typeof props.generating === 'string') { - return props.generating === 'true'; + // HTML attributes: "true" → true, "false" or any other string → false + return props.generating.toLowerCase() === 'true'; } return props.generating || false; });🤖 Prompt for 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. In `@packages/frameworks/vue/src/renderer/SchemaCardRenderer.ce.vue` around lines 56 - 61, The computed isGenerating currently treats only the literal string "true" as true, which can surprise callers passing "false" or other values; update the isGenerating logic to explicitly handle both "true" and "false" string values (e.g., map "true" => true, "false" => false, otherwise fall back to Boolean(props.generating)) and add a short inline comment above the isGenerating computed property explaining this string-to-boolean conversion and why it's implemented that way; reference the isGenerating computed and props.generating identifiers when making the change.packages/frameworks/vue/src/web-component/index.ts (1)
12-14: 💤 Low valueConsider making auto-registration opt-in rather than automatic.
The current implementation registers the custom element as a side effect when the module is imported. While the
typeof windowcheck prevents SSR crashes, automatic registration can cause issues in testing environments or when multiple package versions are loaded.Consider documenting that consumers should explicitly call
registerSchemaCardRenderer()rather than relying on auto-registration, or provide a build-time flag to disable it.📝 Alternative: Document the behavior
+/** + * Registers the SchemaCardRenderer custom element. + * Auto-registers with default tag name 'genui-renderer' when imported in browser environments. + * `@param` tagName - Custom element tag name (must contain a hyphen) + */ export function registerSchemaCardRenderer(tagName: string = 'genui-renderer') { if (!customElements.get(tagName)) { customElements.define(tagName, SchemaCardRendererElement); } } +// Auto-register in browser environments if (typeof window !== 'undefined') { registerSchemaCardRenderer(); }🤖 Prompt for 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. In `@packages/frameworks/vue/src/web-component/index.ts` around lines 12 - 14, Currently the module side-effects by calling registerSchemaCardRenderer() on import; remove that automatic invocation so consumers opt-in. Delete the if (typeof window !== 'undefined') { registerSchemaCardRenderer(); } block (or change it to a guarded global toggle) and ensure registerSchemaCardRenderer remains exported; optionally implement a single, explicit opt-in mechanism if you want to preserve convenience (e.g. check window.__AUTO_REGISTER_SCHEMA_CARD_RENDERER__ === true before calling) and add a short note in docs explaining consumers must call registerSchemaCardRenderer() themselves.
🤖 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/frameworks/vue/scripts/transform-style.ts`:
- Around line 8-11: The script currently reads and writes outputPath using
readFileSync/writeFileSync and does a blind replaceAll('--ti','--tio'); wrap the
file operations in a try/catch (and optionally check existsSync(outputPath)
before reading) to avoid crashing on missing/unreadable files, and replace
replaceAll with a regex-based replace that only targets CSS variable prefixes
(e.g. use a pattern like /--ti-([A-Za-z0-9-_]+)/g and replace with '--tio-$1')
so only variables of the form --ti-... are changed; keep references to
outputPath, content, readFileSync, writeFileSync, and the replace logic when
applying the fix.
In `@packages/frameworks/vue/src/web-component/index.ts`:
- Around line 6-10: registerSchemaCardRenderer currently calls
customElements.define(tagName, SchemaCardRendererElement) without handling
DOMExceptions; wrap the define call in a try-catch and handle registration
errors (e.g., invalid tag names or already-defined names) so consumer apps won't
crash. In the catch, log a clear error including tagName and the caught error
(e.g., via console.error or your project logger) and ensure the function exits
gracefully — optionally change the function to return a boolean success flag
(true on successful define, false on error) so callers can react.
---
Nitpick comments:
In `@packages/frameworks/vue/src/renderer/SchemaCardRenderer.ce.vue`:
- Around line 19-54: The four computed props parsedCustomComponents,
parsedCustomActions, parsedRequiredCompleteFieldSelectors, and parsedState all
duplicate JSON.parse logic and silently swallow errors; extract a shared helper
(e.g., parseJsonProp(value, propName)) and use it inside each computed to remove
duplication, and on parse failure call console.warn with the propName and the
caught error while still returning undefined to preserve fallback behavior.
- Around line 56-61: The computed isGenerating currently treats only the literal
string "true" as true, which can surprise callers passing "false" or other
values; update the isGenerating logic to explicitly handle both "true" and
"false" string values (e.g., map "true" => true, "false" => false, otherwise
fall back to Boolean(props.generating)) and add a short inline comment above the
isGenerating computed property explaining this string-to-boolean conversion and
why it's implemented that way; reference the isGenerating computed and
props.generating identifiers when making the change.
In `@packages/frameworks/vue/src/web-component/index.ts`:
- Around line 12-14: Currently the module side-effects by calling
registerSchemaCardRenderer() on import; remove that automatic invocation so
consumers opt-in. Delete the if (typeof window !== 'undefined') {
registerSchemaCardRenderer(); } block (or change it to a guarded global toggle)
and ensure registerSchemaCardRenderer remains exported; optionally implement a
single, explicit opt-in mechanism if you want to preserve convenience (e.g.
check window.__AUTO_REGISTER_SCHEMA_CARD_RENDERER__ === true before calling) and
add a short note in docs explaining consumers must call
registerSchemaCardRenderer() themselves.
In `@packages/frameworks/vue/vite.config.web-component.ts`:
- Around line 11-17: Add a brief inline comment above the vue
template.compilerOptions isCustomElement configuration explaining why it returns
false for the web-component build (Vue compiles everything as Vue components
before defineCustomElement wraps them), so future maintainers understand the
counter‑intuitive choice; update the block around vue({ template: {
compilerOptions: { isCustomElement: () => false } } }) to include that comment
referencing isCustomElement and defineCustomElement semantics.
- Line 10: The visualizer plugin is currently opening a browser unconditionally
via visualizer({ open: true }), which breaks CI; change it to be opt-in by
guarding either the plugin inclusion or the open flag with an environment check
(e.g., use process.env.VISUALIZE or process.env.CI/NODE_ENV) so visualizer is
only enabled or open when that env flag is set; update the visualizer invocation
(the visualizer(...) call) to remove or conditionally set open: true and/or
conditionally include the visualizer plugin in the exported Vite plugins array.
🪄 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: CHILL
Plan: Pro
Run ID: c427509d-d032-404c-b865-2865786c894d
📒 Files selected for processing (5)
packages/frameworks/vue/package.jsonpackages/frameworks/vue/scripts/transform-style.tspackages/frameworks/vue/src/renderer/SchemaCardRenderer.ce.vuepackages/frameworks/vue/src/web-component/index.tspackages/frameworks/vue/vite.config.web-component.ts
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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/frameworks/vue/src/renderer/SchemaCardRenderer.ce.vue`:
- Line 42: The current binding in SchemaCardRenderer.ce.vue forwards an empty
string because "content ?? '{}'" treats "" as defined; change the expression to
treat empty/whitespace strings as missing—e.g., replace the binding on the
content prop with a conditional that checks for a non-empty trimmed string (use
content && content.trim() or content?.trim()) and fall back to '{}' when it's
falsy; update the :content binding so the component (SchemaCardRenderer) always
receives either a non-empty payload or the '{}' default.
In `@packages/frameworks/vue/src/web-component/index.ts`:
- Around line 8-10: The exported function registerSchemaCardRenderer currently
calls customElements directly which will throw in non-browser runtimes
(SSR/tests); update registerSchemaCardRenderer to first check for a browser
environment and the existence of customElements (e.g., typeof window !==
'undefined' && typeof customElements !== 'undefined') before calling
customElements.get/define for SchemaCardRendererElement and use tagName as
before so callers in SSR won't error.
🪄 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: CHILL
Plan: Pro
Run ID: c6f00d50-2b60-442a-8b92-9fe35145f284
📒 Files selected for processing (4)
packages/frameworks/vue/scripts/transform-style.tspackages/frameworks/vue/src/renderer/SchemaCardRenderer.ce.vuepackages/frameworks/vue/src/web-component/index.tspackages/frameworks/vue/src/web-component/parse-attribute.ts
There was a problem hiding this comment.
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/frameworks/vue/src/web-component/parse-attribute.ts`:
- Line 3: parseJsonAttribute currently fast-paths any typeof value === 'object',
which also accepts null, arrays, and non-plain objects; update the guard in
parseJsonAttribute to only accept plain non-null objects (e.g., value !== null
&& !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype)
before returning value as T so arrays/null/class instances fall through to the
string/json parse logic and avoid type mismatches for props like
customComponents/customActions/requiredCompleteFieldSelectors/state.
🪄 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: CHILL
Plan: Pro
Run ID: bf62dd73-eb2e-4e7d-b0d3-4d127ee0dd90
📒 Files selected for processing (1)
packages/frameworks/vue/src/web-component/parse-attribute.ts
There was a problem hiding this comment.
♻️ Duplicate comments (1)
packages/frameworks/vue/src/web-component/index.ts (1)
8-13:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winAdd error handling for custom element registration.
The open past review comment remains valid:
customElements.define()on line 11 can throwDOMExceptionfor invalid tag names (e.g., missing hyphen, reserved names) or other registration issues. While line 10 prevents duplicate registration, it doesn't guard against invalid input.🛡️ Recommended fix
export function registerSchemaCardRenderer(tagName = 'genui-renderer') { if (typeof customElements === 'undefined') return; if (!customElements.get(tagName)) { - customElements.define(tagName, SchemaCardRendererElement); + try { + customElements.define(tagName, SchemaCardRendererElement); + } catch (error) { + console.error(`[genui-renderer] Failed to register custom element "${tagName}":`, error); + } } }🤖 Prompt for 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. In `@packages/frameworks/vue/src/web-component/index.ts` around lines 8 - 13, The registerSchemaCardRenderer function should guard against invalid tag names and registration exceptions by validating tagName (ensure it contains a hyphen and meets custom element naming rules) and wrapping the customElements.define(tagName, SchemaCardRendererElement) call in a try/catch; on failure catch DOMException (or any Error) and log a clear error (e.g., via console.error) including the tagName and exception message, and then either return false or rethrow as appropriate so callers can detect the failure.
🤖 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.
Duplicate comments:
In `@packages/frameworks/vue/src/web-component/index.ts`:
- Around line 8-13: The registerSchemaCardRenderer function should guard against
invalid tag names and registration exceptions by validating tagName (ensure it
contains a hyphen and meets custom element naming rules) and wrapping the
customElements.define(tagName, SchemaCardRendererElement) call in a try/catch;
on failure catch DOMException (or any Error) and log a clear error (e.g., via
console.error) including the tagName and exception message, and then either
return false or rethrow as appropriate so callers can detect the failure.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: b9f7c542-7f4b-4485-84a4-4490bb4c6f22
📒 Files selected for processing (2)
packages/frameworks/vue/scripts/transform-style.tspackages/frameworks/vue/src/web-component/index.ts
新增renderer构建成web component的配置
Summary by CodeRabbit
New Features
Build
Utilities
Bug Fixes