@vue/compiler-sfc remove `~/` when handling the assets in template.
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.
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?
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:
-
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 */
);
-
vite:import-analysis
import _imports_0 from "@/test.jpg";
was transformed to
import _imports_0 from "/src/test.jpg?import";
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.
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.