Skip to content

Fix linkWorkspaceSource vite plugin on Windows - #4325

Merged
JayaShakthi97 merged 1 commit into
thunder-id:mainfrom
JayaShakthi97:worktree-fix-link-workspace-source-windows
Jul 24, 2026
Merged

Fix linkWorkspaceSource vite plugin on Windows#4325
JayaShakthi97 merged 1 commit into
thunder-id:mainfrom
JayaShakthi97:worktree-fix-link-workspace-source-windows

Conversation

@JayaShakthi97

@JayaShakthi97 JayaShakthi97 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Purpose

linkWorkspaceSource (the Vite plugin that redirects @thunderid/* workspace imports to package source during vite serve) compared resolveId's source/importer paths against appSrcRoot using path.sep-joined prefixes. On Windows, path.sep is \, but Vite always resolves ids to POSIX-style paths (/), so the startsWith checks never matched and the app's @-alias re-rooting for linked packages silently failed on Windows.

While fixing this, also split the two Vite plugins (prismjsInjectCore and linkWorkspaceSource) out of the shared src/vite/index.ts into their own files, following the "one file per plugin" convention already documented in the @thunderid/build-plugins README.

Approach

  • Normalize appSrcRoot, source, importer, packageSrcRoots, and the result of resolveExistingFile with Vite's normalizePath before comparing, so path prefix checks work the same on Windows as on POSIX systems.
  • normalizePath doesn't normalize Windows drive-letter casing (C: vs c:), which can still differ between appRoot and packageDir since they come from different APIs. Add a case-insensitive comparison for the resolveId prefix checks on Windows only, so real workspace source imports aren't skipped due to a casing mismatch.
  • Guard the linked package's package.json read in buildWorkspaceLinks with the same try/catch used around realpathSync, so a malformed or missing manifest in one linked package is skipped instead of throwing synchronously inside configResolved and aborting dev-server startup for the whole app.
  • Move prismjsInjectCore into src/vite/prismjs-inject-core.ts and linkWorkspaceSource (plus its private helpers) into src/vite/link-workspace-source.ts. src/vite/index.ts is now a thin barrel re-exporting both plugins and the LinkWorkspaceSourceOptions type.
  • Document linkWorkspaceSource in the package README, which previously only covered prismjsInjectCore.
  • No change to the public @thunderid/build-plugins/vite API; both consumers (apps/console, apps/gate) are unaffected.
  • Add a "Cross-OS Path Handling" section to frontend/AGENTS.md capturing this normalize-before-comparing rule, so future build tooling and Node scripts don't reintroduce the same Windows-only breakage.
  • Add a vitest setup for the package and unit tests for both plugins, covering export/dist-to-source mapping, specifier redirection, the alias mis-substitution correction, the new casing and error-handling guards, and the prismjs transform hook's regex matching.

Related Issues

Related PRs

  • N/A

Checklist

  • Followed the contribution guidelines.
  • Manual test round performed and verified.
  • Documentation provided. (Add links if there are any)
    • Ran Vale and fixed all errors and warnings
  • Tests provided. (Add links if there are any)
    • Unit Tests
    • Integration Tests
  • Breaking changes. (Fill if applicable)
    • Breaking changes section filled.
    • breaking change label added.

Security checks

  • Followed secure coding standards in WSO2 Secure Coding Guidelines
  • Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets.

Summary by CodeRabbit

  • New Features
    • Added a Vite plugin that redirects @thunderid/* workspace imports to the linked packages’ TypeScript src during vite serve.
    • Added a Vite option to control the resolution root for workspace linking.
    • Added a Vite plugin that injects Prism core into Prism language component modules.
  • Documentation
    • Documented the workspace-source linking plugin and cross-OS path handling guidance.
  • Tests
    • Added Vitest coverage for both workspace linking and Prism core injection.
  • Chores
    • Added Vitest scripts/config and introduced a dedicated spec TypeScript configuration.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

The build-plugins package now exports dedicated Vite plugins for workspace source linking and PrismJS core injection. Vitest tooling and tests cover both plugins, while documentation adds usage and cross-platform path guidance.

Vite build plugins

Layer / File(s) Summary
Vite plugin implementations
frontend/packages/build-plugins/src/vite/link-workspace-source.ts, frontend/packages/build-plugins/src/vite/prismjs-inject-core.ts
Adds development-time workspace source resolution and PrismJS core import injection for language components.
Plugin exports and usage documentation
frontend/packages/build-plugins/src/vite/index.ts, frontend/packages/build-plugins/README.md, frontend/AGENTS.md
Re-exports the plugins, documents linkWorkspaceSource, and adds cross-OS path handling guidance.
Plugin behavior validation
frontend/packages/build-plugins/src/vite/__tests__/*
Tests serve-mode gating, workspace export mapping, source-file fallbacks, alias re-rooting, root overrides, invalid packages, and PrismJS path matching.
Vitest package tooling
frontend/packages/build-plugins/package.json, frontend/packages/build-plugins/tsconfig*.json, frontend/packages/build-plugins/vitest.config.ts
Adds Vitest scripts, dependency, project references, test type configuration, and global test settings.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

Possibly related PRs

  • thunder-id/thunderid#4208: Directly overlaps with linkWorkspaceSource rewriting workspace imports from dist to src during Vite development.

Suggested reviewers: jeradrutnam, brionmario, donomalvindula

Sequence Diagram(s)

sequenceDiagram
  participant ViteDevServer
  participant linkWorkspaceSource
  participant AppPackageJson
  participant WorkspacePackage

  ViteDevServer->>linkWorkspaceSource: Resolve workspace import during vite serve
  linkWorkspaceSource->>AppPackageJson: Read workspace dependencies
  linkWorkspaceSource->>WorkspacePackage: Inspect exports and source files
  WorkspacePackage-->>linkWorkspaceSource: Return dist export targets
  linkWorkspaceSource-->>ViteDevServer: Resolve corresponding src module
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.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
Title check ✅ Passed The title is concise and accurately names the main change: fixing the linkWorkspaceSource Vite plugin on Windows.
Description check ✅ Passed The description covers Purpose, Approach, related issues, checklist, and security items, with only non-critical boxes left unchecked.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

frontend/packages/build-plugins/package.json

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

frontend/packages/build-plugins/src/vite/__tests__/link-workspace-source.test.ts

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

frontend/packages/build-plugins/src/vite/__tests__/prismjs-inject-core.test.ts

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

  • 4 others

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.

@JayaShakthi97
JayaShakthi97 force-pushed the worktree-fix-link-workspace-source-windows branch from b781513 to 910de1e Compare July 24, 2026 07:11
@JayaShakthi97 JayaShakthi97 added Type/Bug skip-changelog Skip generating changelog for a particular PR labels Jul 24, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 `@frontend/packages/build-plugins/src/vite/link-workspace-source.ts`:
- Around line 55-154: Add unit tests for
frontend/packages/build-plugins/src/vite/link-workspace-source.ts:55-154
covering buildWorkspaceLinks export dist-to-src mapping,
linkWorkspaceSource.resolveId specifier redirection, and alias mis-substitution
correction; also add tests for
frontend/packages/build-plugins/src/vite/prismjs-inject-core.ts:23-34 covering
transform regex matches, exclusion of prism-core.js, and injected import output,
targeting at least 80% coverage.
- Around line 117-128: Guard the packageJson read in the linked-package
processing flow with the same error handling used for realpathSync, so failures
from readJson(join(packageDir, 'package.json')) are caught and that package is
skipped. Keep processing other workspace packages and preserve the existing
export-linking logic for successfully read manifests.
- Around line 62-93: Update resolveId’s workspace path comparisons to normalize
Windows drive-letter casing before the appSrcRoot, packageSrcRoots, and importer
prefix checks. Use the casing-normalized paths for startsWith and for
calculating the source suffix passed to join, while retaining the original
normalized paths where needed for resolving the existing file.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8a35b048-6a4c-4cfc-98c4-60adff0f1e03

📥 Commits

Reviewing files that changed from the base of the PR and between 189e635 and b781513.

📒 Files selected for processing (4)
  • frontend/packages/build-plugins/README.md
  • frontend/packages/build-plugins/src/vite/index.ts
  • frontend/packages/build-plugins/src/vite/link-workspace-source.ts
  • frontend/packages/build-plugins/src/vite/prismjs-inject-core.ts

Comment thread frontend/packages/build-plugins/src/vite/link-workspace-source.ts
Comment thread frontend/packages/build-plugins/src/vite/link-workspace-source.ts
Comment thread frontend/packages/build-plugins/src/vite/link-workspace-source.ts Outdated
@JayaShakthi97
JayaShakthi97 force-pushed the worktree-fix-link-workspace-source-windows branch from 910de1e to 2e9f049 Compare July 24, 2026 08:58
@JayaShakthi97 JayaShakthi97 added the trigger-pr-builder Add when the PR is ready for CI; starts the PR Builder for this and all later pushes label Jul 24, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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
`@frontend/packages/build-plugins/src/vite/__tests__/link-workspace-source.test.ts`:
- Around line 109-110: Normalize all expected path values in the
linkWorkspaceSource() tests before comparing them with POSIX-normalized Vite
IDs. In
frontend/packages/build-plugins/src/vite/__tests__/link-workspace-source.test.ts,
update lines 109-110, 125, 185-187, and 213 to wrap each specified join(...)
expected path with normalizePath(...).
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 65383053-485b-467d-a5ee-1914d1340ed1

📥 Commits

Reviewing files that changed from the base of the PR and between b781513 and 2e9f049.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (11)
  • frontend/AGENTS.md
  • frontend/packages/build-plugins/README.md
  • frontend/packages/build-plugins/package.json
  • frontend/packages/build-plugins/src/vite/__tests__/link-workspace-source.test.ts
  • frontend/packages/build-plugins/src/vite/__tests__/prismjs-inject-core.test.ts
  • frontend/packages/build-plugins/src/vite/index.ts
  • frontend/packages/build-plugins/src/vite/link-workspace-source.ts
  • frontend/packages/build-plugins/src/vite/prismjs-inject-core.ts
  • frontend/packages/build-plugins/tsconfig.json
  • frontend/packages/build-plugins/tsconfig.spec.json
  • frontend/packages/build-plugins/vitest.config.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/packages/build-plugins/README.md
  • frontend/packages/build-plugins/src/vite/index.ts

Comment thread frontend/packages/build-plugins/src/vite/__tests__/link-workspace-source.test.ts Outdated
… into per-file modules

`linkWorkspaceSource` compared `resolveId`'s `source`/`importer` paths
against `appSrcRoot` using `path.sep`-joined prefixes. On Windows,
`path.sep` is `\`, but Vite always resolves ids to POSIX-style paths
(`/`), so the `startsWith` checks never matched and the app's `@`-alias
re-rooting for linked packages silently failed. Normalize all of
`appSrcRoot`, `source`, `importer`, `packageSrcRoots`, and the result
of `resolveExistingFile` with Vite's `normalizePath` before comparing,
so the plugin works the same on Windows as on POSIX systems.

`normalizePath` only converts `\` to `/`; it doesn't normalize Windows
drive-letter casing (`C:` vs `c:`), which can still differ between
`appRoot` and `packageDir` since they come from different APIs (Vite's
resolved config root vs `realpathSync`). Add a case-insensitive
comparison on Windows only for the `resolveId` prefix checks, so real
workspace source imports aren't skipped due to a casing mismatch.

Guard the linked package's `package.json` read in `buildWorkspaceLinks`
with the same try/catch used around `realpathSync`, so a malformed or
missing manifest in one linked workspace package is skipped instead of
throwing synchronously inside `configResolved` and aborting dev-server
startup for the whole app.

While in this file, also move `prismjsInjectCore` and
`linkWorkspaceSource` out of the shared `src/vite/index.ts` into their
own files (`prismjs-inject-core.ts` and `link-workspace-source.ts`),
following the "one file per plugin" convention already documented in
the package README. `index.ts` is now a thin barrel re-exporting both
plugins and the `LinkWorkspaceSourceOptions` type.

Also document `linkWorkspaceSource` in the README, which previously
only covered `prismjsInjectCore`.

Add a "Cross-OS Path Handling" section to frontend/AGENTS.md capturing
this normalize-before-comparing rule, so future build tooling and Node
scripts don't reintroduce the same Windows-only breakage.

Add a vitest setup for the package and unit tests for both plugins:
export/dist-to-source mapping, specifier redirection, the alias
mis-substitution correction, the new casing and error-handling guards,
and the prismjs transform hook's regex matching. Assert against
`normalizePath`-wrapped expectations, since the plugin always returns
POSIX-style ids even where the test scaffolding uses `path.join`.
@JayaShakthi97
JayaShakthi97 force-pushed the worktree-fix-link-workspace-source-windows branch from 2e9f049 to 82598d3 Compare July 24, 2026 09:15
@JayaShakthi97 JayaShakthi97 changed the title Fix linkWorkspaceSource on Windows and split build-plugins Vite tools into per-file modules Fix linkWorkspaceSource vite plugin on Windows Jul 24, 2026
@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@rajithacharith

Copy link
Copy Markdown
Contributor

@coderabbitai help

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

CodeRabbit commands

These commands are invoked using PR/Issue comments.

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai rate limit to show your current review rate limit status.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai evaluate custom pre-merge check --instructions <custom-checks-instructions> --name <custom-checks-title> [--mode <error|warning>] to validate the custom pre-merge checks instructions. Defaults to error when --mode is omitted.
  • @coderabbitai ignore pre-merge checks to override pre-merge checks and get an approval on PR.
  • @coderabbitai run pre-merge checks to run pre-merge checks on the pull request.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai emit path instructions to emit generated path-specific review instructions for this repository.
  • @coderabbitai resolve merge conflict to automatically resolve merge conflicts.
  • @coderabbitai autofix to automatically fix issues identified in unresolved review comments.
  • @coderabbitai fix-ci to automatically fix failing CI checks by creating a stacked PR with fixes.
  • @coderabbitai resolve to resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai generate configuration to create a PR that adds the current resolved configuration as .coderabbit.yaml (or show it if already present).
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, support, documentation and community

  • Visit our status page to check the current availability of CodeRabbit.
  • Create a ticket on our support page for assistance with any issues or questions.
  • Visit our documentation site for detailed information on how to use CodeRabbit.
  • Join our Discord community to connect with other users and get help from the community.
  • Follow us on X/Twitter for updates and announcements.

@rajithacharith

Copy link
Copy Markdown
Contributor

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 `@frontend/packages/build-plugins/src/vite/link-workspace-source.ts`:
- Around line 48-50: Update WorkspacePackageJson and the package export mapping
logic in frontend/packages/build-plugins/src/vite/link-workspace-source.ts:48-50
and :137-144 to handle string exports and root condition objects, mapping "." or
root conditions to the package name while normalizing valid "./..." subpaths
without treating targets as export keys. Extend
frontend/packages/build-plugins/src/vite/__tests__/link-workspace-source.test.ts:95-128
with coverage for string root exports, conditional root exports, and normalized
subpath mappings.

In `@frontend/packages/build-plugins/src/vite/prismjs-inject-core.ts`:
- Around line 28-29: Update the comment immediately above the return in the
Prism injection transform to accurately state that map: null is explicitly
returned, removing the claim that it is omitted. Keep the implementation
unchanged.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 14ad3076-7cd0-4dff-908e-d7045afb41e7

📥 Commits

Reviewing files that changed from the base of the PR and between 00091d3 and 82598d3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (11)
  • frontend/AGENTS.md
  • frontend/packages/build-plugins/README.md
  • frontend/packages/build-plugins/package.json
  • frontend/packages/build-plugins/src/vite/__tests__/link-workspace-source.test.ts
  • frontend/packages/build-plugins/src/vite/__tests__/prismjs-inject-core.test.ts
  • frontend/packages/build-plugins/src/vite/index.ts
  • frontend/packages/build-plugins/src/vite/link-workspace-source.ts
  • frontend/packages/build-plugins/src/vite/prismjs-inject-core.ts
  • frontend/packages/build-plugins/tsconfig.json
  • frontend/packages/build-plugins/tsconfig.spec.json
  • frontend/packages/build-plugins/vitest.config.ts

Comment thread frontend/packages/build-plugins/src/vite/link-workspace-source.ts
Comment thread frontend/packages/build-plugins/src/vite/prismjs-inject-core.ts
@JayaShakthi97
JayaShakthi97 added this pull request to the merge queue Jul 24, 2026
Merged via the queue into thunder-id:main with commit 699a963 Jul 24, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-changelog Skip generating changelog for a particular PR trigger-pr-builder Add when the PR is ready for CI; starts the PR Builder for this and all later pushes Type/Bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants