Skip to content

Fix defineProps type resolution in production builds#5

Merged
amery merged 1 commit into
mainfrom
pr-amery-types
Apr 3, 2026
Merged

Fix defineProps type resolution in production builds#5
amery merged 1 commit into
mainfrom
pr-amery-types

Conversation

@amery

@amery amery commented Apr 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fix production build failure@vue/compiler-sfc cannot
    resolve Nuxt auto-imported types in defineProps<T>(). Each
    component now explicitly resolves its props type in a
    <script> block.
  • GoPkgProps stays in app/utils/go-pkg.ts (shared with
    resolveGoPkg). The component imports it explicitly.
  • ProseHeadingProps moves from app/utils/index.ts to
    prose-heading.vue (no utility consumer). Sibling
    components import from it directly.
  • Document the constraint and placement strategies in
    AGENTS.md under Components.

Test plan

  • pnpm clean && pnpm install && pnpm precommit passes
  • pnpm clean && pnpm install && pnpm build passes
  • Verified removal of explicit imports causes build failure

Summary by CodeRabbit

  • Documentation

    • Added component type declaration guidelines to developer documentation.
  • Refactor

    • Reorganized internal type definitions for improved code maintainability and consistency across components.

@amery amery added bug Something isn't working component labels Apr 3, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Apr 3, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
awesome-apptly aadebab Commit Preview URL

Branch Preview URL
Apr 03 2026, 07:45 PM

@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Move component prop interfaces to SFC script blocks

🐞 Bug fix ✨ Enhancement

Grey Divider

Walkthroughs

Description
• Move component prop interfaces to SFC <script> blocks
  - GoPkgProps moved to go-pkg.vue
  - ProseHeadingProps moved to prose-heading.vue
• Fixes production build failure with @vue/compiler-sfc type resolution
• Update prose-h2.vue and prose-h3.vue to import types locally
• Document constraint in AGENTS.md for component type definitions
Diagram
flowchart LR
  A["app/utils/go-pkg.ts<br/>app/utils/index.ts"] -->|"Move types"| B["go-pkg.vue<br/>prose-heading.vue"]
  B -->|"Import types"| C["prose-h2.vue<br/>prose-h3.vue"]
  D["AGENTS.md"] -->|"Document constraint"| E["Type resolution guide"]
Loading

Grey Divider

File Changes

1. app/utils/go-pkg.ts 🐞 Bug fix +2/-16

Remove GoPkgProps, import from component

• Remove GoPkgProps interface definition
• Add import of GoPkgProps from go-pkg.vue
• Keep GoPkgLink interface as return type of resolveGoPkg

app/utils/go-pkg.ts


2. app/utils/index.ts 🐞 Bug fix +0/-8

Remove ProseHeadingProps interface

• Remove ProseHeadingProps interface definition
• Keep OTHER_SLUG constant and utility functions

app/utils/index.ts


3. app/components/go-pkg.vue 🐞 Bug fix +18/-0

Define GoPkgProps in component script

• Add <script lang="ts"> block with GoPkgProps interface definition
• Define all prop types with documentation comments
• Maintain existing <script setup> functionality

app/components/go-pkg.vue


View more (4)
4. app/components/content/prose-heading.vue 🐞 Bug fix +11/-0

Define ProseHeadingProps in component script

• Add <script lang="ts"> block with ProseHeadingProps interface definition
• Add id: undefined to default props
• Keep existing glyph default and component logic

app/components/content/prose-heading.vue


5. app/components/content/prose-h2.vue 🐞 Bug fix +4/-0

Import ProseHeadingProps locally

• Add <script lang="ts"> block importing ProseHeadingProps from prose-heading.vue
• Maintain existing <script setup> with defineProps<ProseHeadingProps>()

app/components/content/prose-h2.vue


6. app/components/content/prose-h3.vue 🐞 Bug fix +4/-0

Import ProseHeadingProps locally

• Add <script lang="ts"> block importing ProseHeadingProps from prose-heading.vue
• Maintain existing <script setup> with defineProps<ProseHeadingProps>()

app/components/content/prose-h3.vue


7. AGENTS.md 📝 Documentation +4/-0

Document component type resolution constraint

• Add documentation section under Components
• Explain constraint that types in defineProps<T>() must be defined or imported in component's
 <script> block
• Note that auto-imports are not resolved during production builds

AGENTS.md


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Apr 3, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX Issues (0)

Grey Divider


Remediation recommended

1. Ambiguous script-block guidance 🐞 Bug ⚙ Maintainability ⭐ New
Description
AGENTS.md says types for defineProps<T>() must be in the component’s <script> block, but in Vue
SFCs <script> can mean either the module <script> or <script setup>, which can lead readers to
place imports in the wrong block and reintroduce the production resolution failure this PR is
addressing.
Code

AGENTS.md[R120-122]

+Types used in `defineProps<T>()` must be defined or imported
+in the component's `<script>` block — auto-imports are not
+resolved during production builds.
Evidence
AGENTS.md uses the ambiguous term “component's <script> block”, while the actual pattern
implemented in this PR is specifically to add a separate *non-setup* <script lang="ts"> block to
host the type imports used by defineProps<T>(). Clarifying this prevents future contributors from
misapplying the guidance.

AGENTS.md[118-127]
app/components/go-pkg.vue[1-8]
app/components/content/prose-h2.vue[1-8]
app/components/content/prose-h3.vue[1-8]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`AGENTS.md` says types used in `defineProps<T>()` must be defined/imported in the component’s `<script>` block, but Vue SFCs have both `<script>` and `<script setup>`. The guidance should explicitly say **non-setup** (module) `<script lang="ts">` to match the pattern used in this PR.

### Issue Context
This PR adds separate `<script lang="ts">` blocks in components solely to host type imports used by `defineProps<T>()`.

### Fix Focus Areas
- AGENTS.md[120-127]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Utility imports SFC type 🐞 Bug ⚙ Maintainability
Description
app/utils/go-pkg.ts now imports GoPkgProps from ~/components/go-pkg.vue, coupling a shared
utility’s public API to a component file and reversing the typical dependency direction (utils →
components). This makes the utility harder to reuse independently and creates fragile cross-layer
coupling when the component contract evolves.
Code

app/utils/go-pkg.ts[1]

+import type { GoPkgProps } from '~/components/go-pkg.vue';
Evidence
The utility’s exported function resolveGoPkg is typed using GoPkgProps, and that type is now
sourced from the component SFC itself. The component is also the only current consumer of
resolveGoPkg, so this change introduces a component-layer dependency into the utility layer
without clear benefit beyond colocating props types in the SFC.

app/utils/go-pkg.ts[1-2]
app/utils/go-pkg.ts[35-37]
app/components/go-pkg.vue[1-23]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`app/utils/go-pkg.ts` imports the `GoPkgProps` type from a Vue SFC (`~/components/go-pkg.vue`). This inverts layering (utils depend on components) and ties a generally reusable utility function signature to a specific component file.
### Issue Context
The original motivation is valid: types used in `defineProps<T>()` must be explicitly resolvable during production builds. You can still achieve this while keeping utilities independent by placing the shared type in a dedicated TypeScript module.
### Fix Focus Areas
- app/utils/go-pkg.ts[1-2]
- app/components/go-pkg.vue[1-23]
### Suggested approach
1. Create a dedicated type module (e.g. `app/utils/go-pkg.types.ts` or `app/types/go-pkg.ts`) exporting `GoPkgProps`.
2. In `app/components/go-pkg.vue`, import `GoPkgProps` from that new `.ts` module (explicitly, within the SFC).
3. In `app/utils/go-pkg.ts`, import `GoPkgProps` from the same `.ts` module.
4. Ensure the component’s `defineProps<GoPkgProps>()` still resolves in production builds with the explicit import.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Grey Divider

Previous review results

Review updated until commit aadebab

Results up to commit fe667bf


🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX Issues (0)

Grey Divider
Remediation recommended
1. Utility imports SFC type 🐞 Bug ⚙ Maintainability
Description
app/utils/go-pkg.ts now imports GoPkgProps from ~/components/go-pkg.vue, coupling a shared
utility’s public API to a component file and reversing the typical dependency direction (utils →
components). This makes the utility harder to reuse independently and creates fragile cross-layer
coupling when the component contract evolves.
Code

app/utils/go-pkg.ts[1]

+import type { GoPkgProps } from '~/components/go-pkg.vue';
Evidence
The utility’s exported function resolveGoPkg is typed using GoPkgProps, and that type is now
sourced from the component SFC itself. The component is also the only current consumer of
resolveGoPkg, so this change introduces a component-layer dependency into the utility layer
without clear benefit beyond colocating props types in the SFC.

app/utils/go-pkg.ts[1-2]
app/utils/go-pkg.ts[35-37]
app/components/go-pkg.vue[1-23]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`app/utils/go-pkg.ts` imports the `GoPkgProps` type from a Vue SFC (`~/components/go-pkg.vue`). This inverts layering (utils depend on components) and ties a generally reusable utility function signature to a specific component file.

### Issue Context
The original motivation is valid: types used in `defineProps<T>()` must be explicitly resolvable during production builds. You can still achieve this while keeping utilities independent by placing the shared type in a dedicated TypeScript module.

### Fix Focus Areas
- app/utils/go-pkg.ts[1-2]
- app/components/go-pkg.vue[1-23]

### Suggested approach
1. Create a dedicated type module (e.g. `app/utils/go-pkg.types.ts` or `app/types/go-pkg.ts`) exporting `GoPkgProps`.
2. In `app/components/go-pkg.vue`, import `GoPkgProps` from that new `.ts` module (explicitly, within the SFC).
3. In `app/utils/go-pkg.ts`, import `GoPkgProps` from the same `.ts` module.
4. Ensure the component’s `defineProps<GoPkgProps>()` still resolves in production builds with the explicit import.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider Grey Divider

Qodo Logo

@coderabbitai

coderabbitai Bot commented Apr 3, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5d21b788-7235-48c1-b581-013caa70bf53

📥 Commits

Reviewing files that changed from the base of the PR and between fe667bf and aadebab.

📒 Files selected for processing (6)
  • AGENTS.md
  • app/components/content/prose-h2.vue
  • app/components/content/prose-h3.vue
  • app/components/content/prose-heading.vue
  • app/components/go-pkg.vue
  • app/utils/index.ts
💤 Files with no reviewable changes (1)
  • app/utils/index.ts
✅ Files skipped from review due to trivial changes (2)
  • app/components/content/prose-h2.vue
  • AGENTS.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/components/content/prose-h3.vue
  • app/components/go-pkg.vue
  • app/components/content/prose-heading.vue

📝 Walkthrough

Walkthrough

This PR reorganizes component prop type definitions by moving ProseHeadingProps from centralized utility exports into its owning component, while updating dependent components to import the type. Documentation is added to establish this pattern as a coding standard.

Changes

Cohort / File(s) Summary
Documentation Standards
AGENTS.md
Added guidance rule for Components that types referenced in defineProps<T>() must be declared or imported within the component's <script> block, noting auto-imports are not resolved in production builds.
Prose Heading Components
app/components/content/prose-heading.vue, app/components/content/prose-h2.vue, app/components/content/prose-h3.vue
Extracted ProseHeadingProps interface (with optional id and glyph fields) into prose-heading.vue as the owning component, and added separate <script> blocks in prose-h2.vue and prose-h3.vue to explicitly import the type before use in defineProps().
Go Package Component
app/components/go-pkg.vue
Added separate <script> block importing GoPkgProps type from ~/utils/go-pkg to maintain explicit type declarations before defineProps() usage.
Utilities Cleanup
app/utils/index.ts
Removed the ProseHeadingProps export, which is now defined in prose-heading.vue as the primary owner.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

🐰 Types now dwell where they belong,
In components singing their song,
No auto-imports in prod's light,
Explicit imports make all right!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing a production build issue by ensuring defineProps types are explicitly imported rather than relying on auto-imports.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pr-amery-types

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

@amery amery self-assigned this Apr 3, 2026
@vue/compiler-sfc cannot resolve Nuxt auto-imported types in
defineProps<T>() during production builds. Each component now
explicitly resolves its props type in a <script> block.

Where the type lives depends on its consumers:

- GoPkgProps stays in app/utils/go-pkg.ts (shared with
  resolveGoPkg). The component imports it explicitly.
- ProseHeadingProps moves from app/utils/index.ts to
  prose-heading.vue (no utility consumer). Sibling
  components import from it directly.

Signed-off-by: Alejandro Mery <amery@apptly.co>
@amery

amery commented Apr 3, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review feedback: GoPkgProps stays in
app/utils/go-pkg.ts (shared with resolveGoPkg) and the
component imports it explicitly, fixing the layering
inversion. Added placement strategy guidance to AGENTS.md.

@amery

amery commented Apr 3, 2026

Copy link
Copy Markdown
Contributor Author

/review
--pr_reviewer.inline_code_comments=true

@qodo-code-review

qodo-code-review Bot commented Apr 3, 2026

Copy link
Copy Markdown

Persistent review updated to latest commit aadebab

@amery amery merged commit 0bb06da into main Apr 3, 2026
4 checks passed
@amery amery deleted the pr-amery-types branch April 3, 2026 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working component

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant