vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
47.26k stars 8.26k forks source link

@vue/compiler-sfc remove `~/` when handling the assets in template. #11367

Open s3xysteak opened 3 months ago

s3xysteak commented 3 months ago

Vue version

3.4.31

Link to minimal reproduction

https://play.vuejs.org/#eNp9kUtLAzEUhf/KcNclg9RVGcUHXehCRV0GZJy5jal5kcc4UMbfbpKhtdCS3eV854ZzbnZwawwZAsIKGo/SiNbjNVVV1fR8yEMcuWSVs90VBVJvtCZGMQrVKb0pUxM+i4bfMj2z3tRzyqY+yg4L8K7TasMZ2TqtYrVdMlPotDRcoH02nmvlKKyqTBJrhdA/j1nzNuBir3df2H2f0bduTBqFF4sO7YAUDsy3lqGf8frtCcc4H6DUfRDRXYCv6LQIKeNsuwuqj7GPfDntgzTaeq7Yu1uPHpXbl0pBk3PKfgrxf+8L1f/jLsll3qNqilf8GNCmN+MBIyDLC5j+AF8xsX8=

Steps to reproduce

See the JS tab in the playground.

<img src="./foo.png" >
<img src="@/foo.png" >
<img src="@pub/foo.png" >
<img src="~/foo.png" >
<img src="~pub/foo.png" >

are transformed to:

import _imports_0 from './foo.png'
import _imports_1 from '@/foo.png'
import _imports_2 from '@pub/foo.png'
import _imports_3 from 'foo.png'
import _imports_4 from 'pub/foo.png'

What is expected?

import _imports_0 from './foo.png'
import _imports_1 from '@/foo.png'
import _imports_2 from '@pub/foo.png'
import _imports_3 from '~/foo.png'
import _imports_4 from '~pub/foo.png'

What is actually happening?

import _imports_0 from './foo.png'
import _imports_1 from '@/foo.png'
import _imports_2 from '@pub/foo.png'
import _imports_3 from 'foo.png' // ! Here!
import _imports_4 from 'pub/foo.png' // ! Here!

System Info

System:
    OS: Windows 10 10.0.19045
    CPU: (8) x64 Intel(R) Core(TM) i3-10100 CPU @ 3.60GHz
    Memory: 4.24 GB / 15.90 GB
  Binaries:
    Node: 20.10.0 - ~\AppData\Local\fnm_multishells\15272_1721110809439\node.EXE
    npm: 10.2.3 - ~\AppData\Local\fnm_multishells\15272_1721110809439\npm.CMD
    pnpm: 9.4.0 - ~\AppData\Local\pnpm\pnpm.CMD
  Browsers:
    Edge: Chromium (126.0.2592.102)
    Internet Explorer: 11.0.19041.4355

Any additional comments?

Refer to a vite issue Refer to code caused the issue

@vue/compiler-sfc handles assets in template. If a element links to a absolute url, just use it. If links to a relative url, will import it. The url starts with . and ~ and @ will be considered a relative path , for ~ and @ are common aliases.

However, code here removed ~ and ~/ at the beginning of the url, which caused compilation differences just due to different alias names. So I think that should be a bug.

Bayn-Web commented 5 days ago

As a newbee I think while you using '\~' means that you are using vite's alias feature.So vite will canvert '\~' before vue's compile.Then it's wrong if the link is start with '\~' or '\~/'.Vue is try to be compatible with it I think.If it's going like this,it will be better to throw a warning maybe?

s3xysteak commented 5 days ago

Sorry I forgot to mention that I am using alias feature of vite. 😖

So vite will canvert '~' before vue's compile

On the contrary, vite will transform alias after compiling vue files. You can see the process by the plugin vite-plugin-inspect:

In order:

  1. vite:vue

    <img src="@/test.jpg" >

    was transformed to

    import _imports_0 from "@/test.jpg";
    const _hoisted_1 = /* @__PURE__ */ _createElementVNode(
    "img",
    { src: _imports_0 },
    null,
    -1
    /* HOISTED */
    );
  2. vite:import-analysis

    import _imports_0 from "@/test.jpg";

    was transformed to

    import _imports_0 from "/src/test.jpg?import";
Bayn-Web commented 5 days ago

I'm misunderstood this issue by using \~ in import.It should only happend in img and other tags.Here is webpack vue loader doc.Maybe compiler-sfc try to do the some.

s3xysteak commented 3 days ago

I'm misunderstood this issue by using ~ in import.It should only happend in img and other tags.Here is webpack vue loader doc.Maybe compiler-sfc try to do the some.

That sounds like it make sense. Since you have referred a PR so I do not close the issue by myself.