Skip to content

fix: resolve src imports using resolved SFC-relative paths#202

Open
pont1s wants to merge 1 commit into
unplugin:mainfrom
pont1s:fix/resolve-src-paths-relative-to-the-sfc
Open

fix: resolve src imports using resolved SFC-relative paths#202
pont1s wants to merge 1 commit into
unplugin:mainfrom
pont1s:fix/resolve-src-paths-relative-to-the-sfc

Conversation

@pont1s

@pont1s pont1s commented May 13, 2026

Copy link
Copy Markdown

Description

Fixed resolving relative path inside , <script src="./foo.ts">, <style src="./foo.css">, and custom blocks in the SFC files.

SFC block src attributes were resolved via pluginContext.resolve, but the resolved path was not used in generated imports. This could leave raw relative paths in emitted code and trigger ENOENT in raw Rollup/Rolldown when cwd did not match the SFC directory.

Use a single helper, resolveAndLinkSrcToDescriptor, to both:

  • resolve and normalize the src path,
  • link the resolved file to the owner SFC descriptor.

Linked Issues

#201

Additional context

Rollup parity tests were adjusted to skip sfc-src* comparison with @vitejs/plugin-vue, since upstream still has this latent issue under raw Rollup bundler

SFC block `src` attributes were resolved via `pluginContext.resolve`, but the
resolved path was not used in generated imports. This could leave raw relative
paths in emitted code and trigger ENOENT in raw Rollup/Rolldown when `cwd`
did not match the SFC directory.

Use a single helper, `resolveAndLinkSrcToDescriptor`, to both:
- resolve and normalize the `src` path (strip query),
- link the resolved file to the owner SFC descriptor.

Then use the returned resolved path in all block generators
(template/script/style/custom blocks), so emitted imports are stable and
correct across environments.

Tests were updated to exercise SFC-relative `src` fixture paths, and Rollup
parity with `@vitejs/plugin-vue` is skipped for `sfc-src` because upstream
still relies on Vite pre-resolution in this case.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 13, 2026 12:21
@bolt-new-by-stackblitz

Copy link
Copy Markdown

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

Copilot AI 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.

Pull request overview

This PR fixes incorrect handling of <template/src>, <script/src>, <style/src>, and custom block src attributes in Vue SFCs when running under raw Rollup/Rolldown, where leaving un-resolved relative paths in generated imports could lead to ENOENT when cwd differs from the SFC’s directory.

Changes:

  • Introduces resolveAndLinkSrcToDescriptor to resolve/clean src file paths and link them to the owning SFC descriptor in one step.
  • Updates generated import requests for SFC blocks to use the resolved (SFC-relative) file path instead of the raw src string.
  • Adjusts Rollup parity testing to skip sfc-src* fixtures vs @vitejs/plugin-vue, and updates the sfc-src.vue fixture to use SFC-relative src paths.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/core/main.ts Uses resolved src paths when generating imports for template/script/style/custom blocks and links resolved files to descriptor cache.
tests/rollup.test.ts Skips parity comparisons for sfc-src* fixtures where upstream still differs under raw Rollup.
tests/fixtures/sfc-src.vue Updates src attributes to be SFC-relative (./…) to validate correct resolution behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/core/main.ts
Comment on lines 433 to +451
async function genStyleCode(
descriptor: SFCDescriptor,
pluginContext: Context,
customElement: boolean,
attachedProps: [string, string][],
) {
let stylesCode = ``
let cssModulesMap: Record<string, string> | undefined
if (descriptor.styles.length > 0) {
for (let i = 0; i < descriptor.styles.length; i++) {
const style = descriptor.styles[i]
if (style.src) {
await linkSrcToDescriptor(
style.src,
descriptor,
pluginContext,
style.scoped,
)
}
const src = style.src || descriptor.filename
const src = style.src
? await resolveAndLinkSrcToDescriptor(
style.src,
descriptor,
pluginContext,
style.scoped,
)
: descriptor.filename
Comment thread src/core/main.ts
Comment on lines 519 to +533
async function genCustomBlockCode(
descriptor: SFCDescriptor,
pluginContext: Context,
) {
let code = ''
for (let index = 0; index < descriptor.customBlocks.length; index++) {
const block = descriptor.customBlocks[index]
if (block.src) {
await linkSrcToDescriptor(block.src, descriptor, pluginContext, false)
}
const src = block.src || descriptor.filename
const src = block.src
? await resolveAndLinkSrcToDescriptor(
block.src,
descriptor,
pluginContext,
false,
)
: descriptor.filename
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.

2 participants