Skip to content

Conversation

@edison1105
Copy link
Member

@edison1105 edison1105 commented Jun 11, 2025

close #13460
close vitejs/vite-plugin-vue#15

This PR introduces a new option, preserveLeadingTilde , for handling the ~ in asset URLs.

  • The default value is false, which keeps the existing behavior: leading ~ and ~/ are stripped - it's exactly the same as before.
  • If set to true, leading ~ and ~/ are preserved and resolution relies on the bundler (e.g., Vite).

Usage example:

  // vite.config.js
  plugins: [vue({
    template:{
      transformAssetUrls:{
        preserveLeadingTilde: true 
      }
    }
  })],

Summary by CodeRabbit

  • New Features
    • Added an option to preserve a leading tilde (~) in asset URLs and srcset entries; default behavior remains unchanged, enabling compatibility with tilde-based aliases when enabled.
  • Tests
    • Added tests verifying asset URL and srcset transformations with the preserve-leading-tilde option enabled, ensuring expected output when the option is used.

@coderabbitai
Copy link

coderabbitai bot commented Jun 11, 2025

Walkthrough

Added an optional preserveLeadingTilde flag to asset URL parsing and transformation; updated parseUrl, transformAssetUrl, and transformSrcset to accept/use the flag and added tests covering template/srcset compilation with preserveLeadingTilde: true.

Changes

Cohort / File(s) Change Summary
Tests
packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts, packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts
Added tests that compile templates and srcset attributes containing tilde-leading URLs with { preserveLeadingTilde: true } and assert output via snapshots.
Template utilities
packages/compiler-sfc/src/template/templateUtils.ts
Changed parseUrl signature to parseUrl(url: string, preserveLeadingTilde?: boolean) and made leading-tilde removal conditional on the new flag.
Asset URL transformer
packages/compiler-sfc/src/template/transformAssetUrl.ts
Added optional preserveLeadingTilde?: boolean to AssetURLOptions, set default preserveLeadingTilde: false, and pass the flag into parseUrl (including base parsing).
Srcset transformer
packages/compiler-sfc/src/template/transformSrcset.ts
Pass options.preserveLeadingTilde into parseUrl when parsing srcset entries.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Compiler as TemplateCompiler
    participant Asset as transformAssetUrl
    participant Src as transformSrcset
    participant Parse as parseUrl

    Note over Compiler,Asset: Asset URL transform (optionally preserve leading ~)
    Compiler->>Asset: compile(template, options)
    Asset->>Parse: parseUrl(attr.value.content, options.preserveLeadingTilde)
    Parse-->>Asset: parsed URL (leading ~ preserved if flag true)
    Asset-->>Compiler: transformed template

    Note over Compiler,Src: Srcset transform (optionally preserve leading ~)
    Compiler->>Src: compileSrcset(template, options)
    Src->>Parse: parseUrl(srcsetUrl, options.preserveLeadingTilde)
    Parse-->>Src: parsed srcset URL (leading ~ preserved if flag true)
    Src-->>Compiler: transformed srcset
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

ready to merge

Poem

I nibble at code with whiskers bright,
A tilde kept through moonlit night.
Small change, big hop — paths now true,
Images find their way anew.
🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title accurately and concisely describes the primary change: it adds a preserveLeadingTilde option to compiler-sfc to affect asset URL and srcset transformations, names the affected area (compiler-sfc) and the feature, and matches the changes in the diff and PR objectives.
Linked Issues Check ✅ Passed The changes implement the linked issues' intent by introducing transformAssetUrls.preserveLeadingTilde (default false), updating parseUrl to accept and honor the option, and passing it through in both transformAssetUrl and transformSrcset, with tests added to verify preserved-tilde behavior; this directly addresses preserving leading ~/~/ for bundler alias resolution as requested in [#13460] and the related [#15] while keeping existing behaviour when the option is false.
Out of Scope Changes Check ✅ Passed All modifications are narrowly scoped to template asset handling in compiler-sfc (templateUtils.parseUrl signature, AssetURLOptions, transformAssetUrl, transformSrcset, and corresponding tests); there are no unrelated file changes or extraneous logic shifts, and public API changes are minimal and backward-compatible (optional param/property) to support the stated objective.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch edison/fix/13460

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 466e890 and 4d3917a.

⛔ Files ignored due to path filters (2)
  • packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap is excluded by !**/*.snap
  • packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (4)
  • packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts (1 hunks)
  • packages/compiler-sfc/src/template/templateUtils.ts (1 hunks)
  • packages/compiler-sfc/src/template/transformAssetUrl.ts (2 hunks)
  • packages/compiler-sfc/src/template/transformSrcset.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • packages/compiler-sfc/src/template/transformAssetUrl.ts
  • packages/compiler-sfc/src/template/transformSrcset.ts
  • packages/compiler-sfc/tests/templateTransformSrcset.spec.ts
  • packages/compiler-sfc/src/template/templateUtils.ts

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

@github-actions
Copy link

github-actions bot commented Jun 11, 2025

Size Report

Bundles

File Size Gzip Brotli
runtime-dom.global.prod.js 101 kB 38.5 kB 34.6 kB
vue.global.prod.js 159 kB 58.6 kB 52.1 kB

Usages

Name Size Gzip Brotli
createApp (CAPI only) 46.6 kB 18.2 kB 16.7 kB
createApp 54.6 kB 21.3 kB 19.4 kB
createSSRApp 58.9 kB 23 kB 21 kB
defineCustomElement 59.6 kB 22.8 kB 20.9 kB
overall 68.8 kB 26.4 kB 24.2 kB

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jun 11, 2025

Open in StackBlitz

@vue/compiler-core

npm i https://pkg.pr.new/@vue/compiler-core@13462

@vue/compiler-dom

npm i https://pkg.pr.new/@vue/compiler-dom@13462

@vue/compiler-sfc

npm i https://pkg.pr.new/@vue/compiler-sfc@13462

@vue/compiler-ssr

npm i https://pkg.pr.new/@vue/compiler-ssr@13462

@vue/reactivity

npm i https://pkg.pr.new/@vue/reactivity@13462

@vue/runtime-core

npm i https://pkg.pr.new/@vue/runtime-core@13462

@vue/runtime-dom

npm i https://pkg.pr.new/@vue/runtime-dom@13462

@vue/server-renderer

npm i https://pkg.pr.new/@vue/server-renderer@13462

@vue/shared

npm i https://pkg.pr.new/@vue/shared@13462

vue

npm i https://pkg.pr.new/vue@13462

@vue/compat

npm i https://pkg.pr.new/@vue/compat@13462

commit: 4d3917a

@edison1105 edison1105 changed the base branch from main to minor June 11, 2025 01:04
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
packages/compiler-sfc/src/template/templateUtils.ts (1)

22-31: preserveTilde flag integrates cleanly – consider future-proofing with WHATWG URL

The early-return logic is solid and preserves existing behaviour when the flag is falsy ✅.
However, url.parse (the legacy API behind uriParse) is deprecated in recent Node versions; the WHATWG URL constructor is now the recommended API. Migrating at some point would avoid deprecation warnings and give stricter parsing.

No action required for this PR, but adding a tech-debt ticket now will save churn later.

packages/compiler-sfc/src/template/transformAssetUrl.ts (1)

123-129: Redundant parse on options.base

parseUrl is executed twice in the same branch – once for attr.value.content and again for options.base. The second invocation is unavoidable, but you could memoise it locally to avoid reparsing base for every attribute.

-const base = parseUrl(options.base, options.preserveTilde)
+const baseUrl = parseUrl(options.base, options.preserveTilde)

Minor perf win, feel free to ignore.

packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts (1)

103-111: 👍 Test covers both ~/ and ~ alias forms

Snapshot ensures both syntaxes compile. Consider asserting the generated import path explicitly (e.g. contains import _imports_0 from '~/app/bar.png') to make the test more intention-revealing.

packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts (1)

102-111: Good parity with asset-url tests

Mirrors the asset-url testcase; same note about being explicit applies here.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cdffaf6 and b896fd4.

⛔ Files ignored due to path filters (2)
  • packages/compiler-sfc/__tests__/__snapshots__/templateTransformAssetUrl.spec.ts.snap is excluded by !**/*.snap
  • packages/compiler-sfc/__tests__/__snapshots__/templateTransformSrcset.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (5)
  • packages/compiler-sfc/__tests__/templateTransformAssetUrl.spec.ts (1 hunks)
  • packages/compiler-sfc/__tests__/templateTransformSrcset.spec.ts (1 hunks)
  • packages/compiler-sfc/src/template/templateUtils.ts (1 hunks)
  • packages/compiler-sfc/src/template/transformAssetUrl.ts (2 hunks)
  • packages/compiler-sfc/src/template/transformSrcset.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
packages/compiler-sfc/src/template/transformSrcset.ts (1)
packages/compiler-sfc/src/template/templateUtils.ts (1)
  • parseUrl (22-32)
packages/compiler-sfc/src/template/transformAssetUrl.ts (1)
packages/compiler-sfc/src/template/templateUtils.ts (1)
  • parseUrl (22-32)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Redirect rules
  • GitHub Check: Header rules
  • GitHub Check: Pages changed
  • GitHub Check: test / unit-test-windows
🔇 Additional comments (3)
packages/compiler-sfc/src/template/transformAssetUrl.ts (2)

35-41: Option contract extended correctly – please bubble the docs

preserveTilde is added with a clear JSDoc and default. Looks good.
Remember to surface the new option in user-facing docs / typings packages (@vue/compiler-sfc).


46-47: Default updated – snapshot tests already cover it

No issues spotted.

packages/compiler-sfc/src/template/transformSrcset.ts (1)

111-112: preserveTilde correctly forwarded

Passing options.preserveTilde keeps behaviour consistent with transformAssetUrl. Good catch.

@edison1105 edison1105 changed the base branch from minor to main June 11, 2025 01:20
@danielroe
Copy link
Member

this looks great! thank you ❤️

is it still possible to import from modules, ie some-npm-package/file.png?

(I would imagine that would just be up to the bundler to resolve, and would therefore work with vite.)

@edison1105
Copy link
Member Author

You're absolutely right!
This PR only affects handling for ~ prefixes:

With preserveTilde set to false, everything works as before.
With preserveTilde set to true, the ~ is preserved and resolution is handled by the bundler (like Vite).

@edison1105 edison1105 changed the title feat(compiler-sfc): add preserveTilde option for asset URL and srcset transformations feat(compiler-sfc): add preserveLeadingTilde option for asset URL and srcset transformations Sep 18, 2025
Copy link
Contributor

@alex-snezhko alex-snezhko left a comment

Choose a reason for hiding this comment

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

LGTM!

@edison1105 edison1105 moved this from Todo to Ready To Merge in Next Minor Dec 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Ready To Merge

Development

Successfully merging this pull request may close these issues.

Allow ~/path as <img src="~/..."> with ~ alias tilde alias not working in img.src

4 participants