Open sschneider-ihre-pvs opened 2 years ago
Is this a bug in Vite or in @vue/compiler-sfc
?
It seems a bug in Vite. When this condition is met, it is transpiled here. https://github.com/vitejs/vite/blob/f3d15f106f378c3850b62fbebd69fc8f7c7f944b/packages/plugin-vue/src/main.ts#L229 https://github.com/vitejs/vite/blob/f3d15f106f378c3850b62fbebd69fc8f7c7f944b/packages/plugin-vue/src/main.ts#L193-L208
But if it does not meet, it is not transpiled. https://github.com/vitejs/vite/blob/f3d15f106f378c3850b62fbebd69fc8f7c7f944b/packages/plugin-vue/src/main.ts#L238-L250
So in theory, this does not work. (I did not test)
<template src="foo.html"></template> <!-- foo.html includes typescript syntax -->
<script lang="ts" setup>
export const foo = 'foo'
</script>
Oh, so you would like to remove types from template
s using src
? I'm not sure if this is possible right now. Also that would not be a bug but a feature request, would it? 🤔
Feel free to open a PR and try to enhance this behavior.
Well, currently it is assumed that every piece of js code in the template is vanilla js. I think that if you have script lang="ts" the probability is high that you have ts syntax in the template. It seems that the possibility is currently not checked, and the statements get copied to js code. Another way could be to indicate that you can only use vanilla js in html templates.
Well, currently it is assumed that every piece of js code in the template is vanilla js. I think that if you have script lang="ts" the probability is high that you have ts syntax in the template. It seems that the possibility is currently not checked, and the statements get copied to js code. Another way could be to indicate that you can only use vanilla js in html templates.
I specifically talk about template
with using src
I assume TypeScript types get removed if you use SFC with <script lang="ts">
together with <template lang="pug">
but without src
for template
I'm not the issuer (just in case).
When a <template>
is written in html and is not using external src
, it gets directly in the main module.
Typescript support inside <template>
is supported with intention.
https://github.com/vitejs/vite/blob/f3d15f106f378c3850b62fbebd69fc8f7c7f944b/packages/plugin-vue/src/template.ts#L156-L162
Typescript support for <template>
written in html and not using external src
relies on this part.
https://github.com/vitejs/vite/blob/f3d15f106f378c3850b62fbebd69fc8f7c7f944b/packages/plugin-vue/src/main.ts#L193-L208
But when this condition is not met, the code above does not run.
https://github.com/vitejs/vite/blob/f3d15f106f378c3850b62fbebd69fc8f7c7f944b/packages/plugin-vue/src/main.ts#L229
So if a <template>
uses external src
or it is not written in html, it does not work with typescript.
Just wanted to say, it also does not work.
Ah ok, then I misunderstood. And in my case I didn't use src and it didn't get removed.
That would match my pug case.
So if a uses external src or it is not written in html, it does not work with typescript.
This is the repro with pug and without external src
.
https://stackblitz.com/edit/vitejs-vite-ustutd?file=src%2Fcomponents%2FHelloWorld.vue
This is the repro with pug and without external
src
. https://stackblitz.com/edit/vitejs-vite-ustutd?file=src%2Fcomponents%2FHelloWorld.vue
thanks for the repo, I added that to the report.
can confirm I'm experiencing the same bug without src
Same issue, typescript got not removed in pug template
In my project, when I use the combination of API options, Pug, and Vite for building, I encounter an unexpected token error due to TypeScript type assertion in the Pug template. However, when I switch to the Composition API, the error disappears.
For someone in need, I've created a Vite plugin to remove type assertions. This may help some Pug users. I'm uncertain if there are other TypeScript syntax will break Vite, but removing type assertions will solve my problem.
vite-plugin-remove-pug-type-assertion.ts
import fs from "fs"
import type { Plugin } from "vite"
const vitePluginPugBuild = (): Plugin => {
return {
name: "vite-plugin-remove-pug-type-assertion",
enforce: "pre",
apply: "build",
load(id: string) {
if (!id.endsWith(".vue")) return
let content = fs.readFileSync(id, "utf-8")
// Remove type assertion in pug block for vue files.
content = content.replace(/(?<==".+)( as [\w<>|', ]+)/g, '')
return content
},
}
}
export default function() {
return vitePluginPugBuild()
}
Config your vite.config.ts
:
import vue from '@vitejs/plugin-vue'
import removePugAssertion from '[some path]/vite-plugin-remove-pug-type-assertion'
export default defineConfig({
plugins: [
removePugAssertion(),
vue(),
],
...
This is only for building Vue, not for dev server. It loads all Vue SFCs and replaces assertions only in the template block by checking if ="
appears before the assertion. I don't check if the user is using Pug or HTML, but I believe it will not break HTML. Please avoid to use double quotes in your assertion, like v as "apple" | "banana"
. Instead, use single quotes. There may be some bugs in this plugin, and some assertions may not be detected. I hope this helps you.
In my project, when I use the combination of API options, Pug, and Vite for building, I encounter an unexpected token error due to TypeScript type assertion in the Pug template. However, when I switch to the Composition API, the error disappears.
For someone in need, I've created a Vite plugin to remove type assertions. This may help some Pug users. I'm uncertain if there are other TypeScript syntax will break Vite, but removing type assertions will solve my problem.
vite-plugin-remove-pug-type-assertion.ts
import fs from "fs" import type { Plugin } from "vite" const vitePluginPugBuild = (): Plugin => { return { name: "vite-plugin-remove-pug-type-assertion", enforce: "pre", apply: "build", load(id: string) { if (!id.endsWith(".vue")) return let content = fs.readFileSync(id, "utf-8") // Remove type assertion in pug block for vue files. content = content.replace(/(?<==".+)( as [\w<>|', ]+)/g, '') return content }, } } export default function() { return vitePluginPugBuild() }
Config your
vite.config.ts
:import vue from '@vitejs/plugin-vue' import removePugAssertion from '[some path]/vite-plugin-remove-pug-type-assertion' export default defineConfig({ plugins: [ removePugAssertion(), vue(), ], ...
This is only for building Vue, not for dev server. It loads all Vue SFCs and replaces assertions only in the template block by checking if
="
appears before the assertion. I don't check if the user is using Pug or HTML, but I believe it will not break HTML. Please avoid to use double quotes in your assertion, likev as "apple" | "banana"
. Instead, use single quotes. There may be some bugs in this plugin, and some assertions may not be detected. I hope this helps you.
Would it be possible to extend this for optional brackets?
:something="v as someType | someOtherType"
:something="(v as someType | someOtherType)"
In my project, when I use the combination of API options, Pug, and Vite for building, I encounter an unexpected token error due to TypeScript type assertion in the Pug template. However, when I switch to the Composition API, the error disappears.
For someone in need, I've created a Vite plugin to remove type assertions. This may help some Pug users. I'm uncertain if there are other TypeScript syntax will break Vite, but removing type assertions will solve my problem.
vite-plugin-remove-pug-type-assertion.ts
import fs from "fs" import type { Plugin } from "vite" const vitePluginPugBuild = (): Plugin => { return { name: "vite-plugin-remove-pug-type-assertion", enforce: "pre", apply: "build", load(id: string) { if (!id.endsWith(".vue")) return let content = fs.readFileSync(id, "utf-8") // Remove type assertion in pug block for vue files. content = content.replace(/(?<==".+)( as [\w<>|', ]+)/g, '') return content }, } } export default function() { return vitePluginPugBuild() }
Config your
vite.config.ts
:import vue from '@vitejs/plugin-vue' import removePugAssertion from '[some path]/vite-plugin-remove-pug-type-assertion' export default defineConfig({ plugins: [ removePugAssertion(), vue(), ], ...
This is only for building Vue, not for dev server. It loads all Vue SFCs and replaces assertions only in the template block by checking if
="
appears before the assertion. I don't check if the user is using Pug or HTML, but I believe it will not break HTML. Please avoid to use double quotes in your assertion, likev as "apple" | "banana"
. Instead, use single quotes. There may be some bugs in this plugin, and some assertions may not be detected. I hope this helps you.
import { readFileSync } from 'node:fs';
export default function () {
return {
name: 'vite-plugin-remove-pug-type-assertion',
enforce: 'pre',
load(id: string) {
if (!id.endsWith('.vue')) return;
let content = readFileSync(id, 'utf-8');
const regex = new RegExp(/(?<==")(.+)( as [\w<>|', ]+)/, 'g');
while (regex.test(content)) {
content = content.replace(regex, '$1');
}
return content;
},
};
}
I just worked on the former suggestion for a vite solution with regard to build/serve and multiple assertions in a line
Describe the bug
Having something like
in a pug template is fine with volar, but vite doesn't seem to expect that kind of thing and compiles it to js as is
which leads to some cryptic error messages like
Reproduction
Hello World
System Info
Used Package Manager
npm
Logs
No response
Validations