Repository navigation
fix: resolve svelte/vue compilers from the project directory - #798
Merged
Merged
Conversation
The svelte and vue language plugins loaded their compilers with a bare
`import('svelte/compiler')` / `import('vue/compiler-sfc')`, which resolves
against jsrepo's own install location rather than the user's project. When
jsrepo lives in a different node_modules than the framework (global/npx
installs, hoisted monorepos, package managers that don't hoist peer deps),
that lookup fails and the build reports "svelte is required for Svelte
language support to work" even though the user installed svelte in their
project.
Resolve the compiler from the consumer's `cwd` first (already threaded into
`resolveDependencies`), falling back to jsrepo's own resolution. Auto-detection
in `DEFAULT_LANGS` now checks the project directory as well.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UwUar3KD5KEWVRN4GWgBu5
🦋 Changeset detectedLatest commit: 3ead72e The changes in this PR will be included in the next version bump. This PR includes changesets to release 11 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
jsrepo
@jsrepo/mcp
@jsrepo/migrate
@jsrepo/transform-biome
@jsrepo/transform-filecasing
@jsrepo/transform-javascript
@jsrepo/transform-oxfmt
@jsrepo/transform-prettier
commit: |
svelte/compiler and vue/compiler-sfc ship as CommonJS. Importing them by an explicit file URL (as loadPeerCompiler does after resolving from cwd) exposes their exports under the namespace's `default` key rather than as top-level named exports, so `compiler.preprocess` was undefined and the build failed with "n.preprocess is not a function". Unwrap the CJS default when the imported namespace only carries `default`. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UwUar3KD5KEWVRN4GWgBu5
Importing the resolved svelte/compiler (CJS) file by URL puts its exports under `default`, and whether the exports lexer surfaces named exports varies by Node version (worked under Node 22 locally, failed under Node 24 in CI), so `compiler.preprocess` was undefined and the build threw "n.preprocess is not a function". Load these CommonJS compilers with require() instead, which returns module.exports directly with the real API, matching the condition require.resolve already selects. ESM-only modules fall back to a dynamic import with default interop. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UwUar3KD5KEWVRN4GWgBu5
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Investigated discussion #797, where a user building a Svelte registry hit:
…even though they had
svelte@^5.56.1installed in their project. The error being reported didn't add up.Root cause
The Svelte and Vue language plugins loaded their compilers with a bare dynamic import:
A bare
import('svelte/compiler')resolves the module relative to jsrepo's own location on disk, not the user's project.resolveDependenciesis already handedopts.cwd(the consumer's project root), but the loader ignored it.So whenever jsrepo lives in a different
node_modulesthan the framework — a global/npx/bunxinstall, a hoisted monorepo, or a package manager that doesn't hoist optional peer deps — the lookup fails and jsrepo throwsMissingPeerDependencyErrortelling the user to install a package they already installed. This also lines up with the reporter's own resolution (abun.lockconflict that was movingsvelteout of the location jsrepo could see).The
DEFAULT_LANGSauto-detection insrc/langs/index.tshad the same blind spot (createRequire(import.meta.url)), so the maintainer's suggested workaround — "removelanguagesfrom your config" — was equally unreliable.Changes
src/langs/load-peer-compiler.ts(new): shared helper that resolves a peer compiler from the consumer'scwdfirst (viacreateRequirepointed at the project), then falls back to jsrepo's own resolution, and only throwsMissingPeerDependencyErrorif both fail.src/langs/svelte.ts/src/langs/vue.ts: threadopts.cwdinto the compiler loader and use the shared helper.src/langs/index.ts:isModuleAvailablenow checks the project directory (process.cwd()) before jsrepo's own location, so auto-detection finds project-installed frameworks too.tests/langs/load-peer-compiler.test.tscovers project-cwd resolution and the missing-dependency failure path.patchbump forjsrepo.Verification
pnpm check(tsc) — cleanpnpm vitest run— 200/200 tests pass, including the new helper testsbiome check— clean on all touched files🤖 Generated with Claude Code
https://claude.ai/code/session_01UwUar3KD5KEWVRN4GWgBu5
Generated by Claude Code