javascript - Hur kan webbläsaren använda TypeScript-fil direkt i Vite index.html?


På senaste tiden har jag lekt med Vite. En sak som fascinerar mig är dess förmåga att använda TypeScript-filer direkt i index.html, till exempel.

<script type="module" src="/src/main.ts"></script>

Från dokumentationen förstår jag att Vite kommer att transpile den ursprungliga koden från Typescript till Javascript (jag har kontrollerat att innehållet i main.ts faktiskt omvandlas). Men hur kan webbläsaren köra Javascript-koden inuti en *.ts-fil?

Jag försökte återskapa det genom att skapa en enkel statisk server med en index.html som innehöll skript-taggen som ovan. Ändå kommer webbläsaren att visa ett fel:

Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "video/mp2t". Strict MIME type checking is enforced for module scripts per HTML spec.

Så hur är detta möjligt med Vite?

Svar #1

Men hur kan webbläsaren köra Javascript-koden inuti en *.ts-fil?

JavaScript är inte i en *.ts-fil.

Det är en resurs, med en Content-Type: text/javascript responsrubrik, hämtad med en URL. Sökvägen för den URL:en spelar bara roll eftersom den talar om för servern vad den ska leta efter. Webbläsaren bryr sig inte om vilka bokstäver som finns i den.

Svar #2

REDIGERA: Det accepterade svaret är faktiskt korrekt, eftersom OP inte undrade över vad Vite gör under produktions-byggen utan snarare under utvecklings-byggen, vilket är att utveckling serverar de transplierade resultaten från minnet (modifierar Content-Type-huvuden för att servera rätt filtyp, åsidosätter filändelser som antyds vid behov) medan produktion beständigt ändrar URL:er i genererade artefakter.

Mitt svar nedan förklarar vad som händer med Vite-inputs under slutliga transpileringar i produktions-läge, medan det accepterade svaret förklarar hur Vite klarar av att transpile filer i minnet och ändra innehållshuvuden för att leverera de minnes-transpilerade filerna under utvecklings-läge.


Om jag inte missförstår något, tycker jag att svaret som har godkänts inte faktiskt motsvarar vad som frågades. Jag tror att OP undrar hur man kan referera till en "TypeScript"-fil i en Vite-projekts HTML-rotfil (index.html) för att transpila och köra den refererade TypeScript-koden. Ett exempel är:

<script type="module" src="./index.ts"></script>

TL;DR är att webbläsaren aldrig kör TypeScript-kod -- Vite omvandlar URL:en ovan till något som liknar:

<script type="module" src="/index.[content_hash].js"></script>

...hur kan webbläsaren köra Javascript-koden inuti en *.ts-fil?

Det behöver (lyckligtvis) inte. Du svarade delvis på din egen fråga här:

...Vite kommer att transpile den ursprungliga koden från Typescript till Javascript.

Webbläsaren får inte rå TypeScript direkt. Vite transformera inte bara dina tillgångar, det transformera också länkarna i din index.html till andra externa resurser.

Försök att köra npm run build eller vite build, och besök sedan din utmatningskatalog och inspektera den genererade index.html-filen själv.


En "JavaScript-först" modulbuntare (som Webpack) skapar en "beroendegraf" av dina moduler. I princip tillhandahåller du en ingångspunkt, och buntaren går igenom alla importeringar (rekursivt) och gör avancerade saker (dvs. buntning, trädskakning och alla andra transformationer).

Vite, å andra sidan, är vad jag skulle kalla en "HTML-först" bundler. Där Webpack skulle välja att använda JavaScript-filer (och ibland andra filer) som ingångspunkter, tillåter Vite HTML-filer att vara en ingångspunkt. Samma sak händer här, med skillnaden att istället för JavaScript-importer, traverserar Vite istället saker som ett link-tags href-attribut, eller ett img-tags src-attribut.

I båda fallen, när sammanställning och transformation av tillgångar har skett, ser beroendegrafen vanligtvis annorlunda ut -- och filtyperna själva kan ha förändrats. Till exempel skulle flera sammanfogade filer inte längre kräva flera importeringar, och TypeScript-filer kan nu vara JavaScript-filer. Bundlers tar hänsyn till detta genom att dynamiskt ändra import-URL:er och strategi baserat på kontexten.

Hoppas det hjälper!

Relaterade artiklar