Slide 1

Slide 1 text

Nozomu Ikuta 19th Oct 2024 Demystifying Vite Internals

Slide 2

Slide 2 text

@NozomuIkuta • Software Engineer • Vue.js-JP Core Sta ff • UnJS Member • Nuxt / Vite Contributor

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Introduction

Slide 5

Slide 5 text

How Vite dev server is bootstrapped How Vite config is resolved How Vite handles HTTP requests How Vite plugins are made available in dev mode How Vite manages caches How Vite manages HMR How Vite builds application etc. Introduction Topics

Slide 6

Slide 6 text

How Vite dev server is bootstrapped How Vite config is resolved How Vite handles HTTP requests How Vite plugins are made available in dev mode How Vite manages caches How Vite manages HMR How Vite builds application etc. Introduction Topics

Slide 7

Slide 7 text

• Contents are based on Vite 5 • Core concepts are same in Vite 6

Slide 8

Slide 8 text

Dev Server Bootstrap

Slide 9

Slide 9 text

Dev Server Bootstrap Overview • Initialization • Con fi g resolution • Connect server setup • Dependency pre-bundling • Starting connect server

Slide 10

Slide 10 text

await createServer(inlineCon fi g) • Run Vite CLI or call exported function directly • These options are called inline con fi g in terms of con fi g resolution Vite CLI JavaScript API Pass 
 CLI options Call with options Dev Server Bootstrap Initialization

Slide 11

Slide 11 text

loadCon fi gFromFile() Disk Dev Server Bootstrap Con fi g Resolution • Build user con fi g fi le by esbuild vite.con fi g.ts other.ts build() import .env

Slide 12

Slide 12 text

loadCon fi gFromFile() Disk Dev Server Bootstrap Con fi g Resolution • Build user con fi g fi le by esbuild • Write the code to disk vite.con fi other.ts build() writeFile() import temporal fi le .env

Slide 13

Slide 13 text

loadCon fi gFromFile() Disk Dev Server Bootstrap Con fi g Resolution • Build user con fi g fi le by esbuild • Write the code to disk and then import the fi le vite.con fi temporal fi le other.ts build() writeFile() import() import .env

Slide 14

Slide 14 text

loadCon fi gFromFile() Disk Dev Server Bootstrap Con fi g Resolution • Build user con fi g fi le by esbuild • Write the code to disk and then import the fi le and delete it vite.con fi temporal fi le other.ts build() writeFile() import() unlink() import .env

Slide 15

Slide 15 text

loadCon fi gFromFile() Disk Dev Server Bootstrap Con fi g Resolution • Build user con fi g fi le by esbuild • Write the code to disk and then import the fi le • Merge inline con fi g and user con fi g vite.con fi temporal fi other.ts build() writeFile() import() unlink() mergeCon fi g(userCon fi g, inlineCon fi g) import .env

Slide 16

Slide 16 text

loadCon fi Disk Dev Server Bootstrap Con fi g Resolution • Build user con fi g fi le by esbuild • Write the code to disk and then import the fi le • Merge inline con fi g and user con fi g • Resolve user plugins vite.con fi temporal fi other.ts build() writeFile() import() unlink() mergeCon fi import fl atten / sort user plugins .env

Slide 17

Slide 17 text

loadCon fi Disk Dev Server Bootstrap Con fi g Resolution • Build user con fi g fi le by esbuild • Write the code to disk and then import the fi le • Merge inline con fi g and user con fi g • Resolve user plugins • Load .env fi le vite.con fi temporal fi other.ts build() writeFile() import() unlink() mergeCon fi import fl loadEnv() .env

Slide 18

Slide 18 text

Dev Server Bootstrap Connect Server Setup • timeMiddleware • corsMiddleware • cachedTransformMiddleware • proxyMiddleware • baseMiddleware • launchEditorMiddleware • viteHMRPringMiddleware • servePublicMiddleware • transformMiddleware • serveRawFsMiddleware • serveStaticMiddleware • htmlFallbackMiddleware • indexHtmlMiddleware • notFoundMiddleware • errorMiddleware

Slide 19

Slide 19 text

Dev Server Bootstrap Connect Server Setup • timeMiddleware • corsMiddleware • cachedTransformMiddleware • proxyMiddleware • baseMiddleware • launchEditorMiddleware • viteHMRPringMiddleware • servePublicMiddleware • transformMiddleware • serveRawFsMiddleware • serveStaticMiddleware • htmlFallbackMiddleware • indexHtmlMiddleware • notFoundMiddleware • errorMiddleware

Slide 20

Slide 20 text

Dev Server Bootstrap Dependency Pre-Bundling • Dependencies in node_modules are transformed by esbuild as ESM • The results are cached • type=“module” is written in package.json for deps to be recognized as ESM Deps- Optimizer Disk node_modules dep A .vite/deps package.json dep B dep C _metadata.json dep A’ dep B’ dep C’

Slide 21

Slide 21 text

Server starts to listen

Slide 22

Slide 22 text

No application build

Slide 23

Slide 23 text

• Vite con fi g is built by esbuild • Dependencies are built by esbuild and stored as cache • No application build on dev server bootstrap

Slide 24

Slide 24 text

Requesting Files

Slide 25

Slide 25 text

indexHtml- Middleware GET /index.html Requesting index.html indexHtmlMiddleware • Replace environment variable placeholders with values • Transform other parts of index.html for performance (out of scope) Disk index.html Browser readFile() transform() send() index.html

Slide 26

Slide 26 text

Requesting JS Files Native ESM Module Resolution • JavaScript fi les are requested according to src attribute • What to be returned from the URL depends on the server • This is the starting point of partial application build Browser GET index.html Vite dev server

Slide 27

Slide 27 text

Browser Disk src index.ts a.ts GET /src/main.ts Vite Dev Server transformMiddleware import A from ‘./a’ type MyType = true function fn(): void { console.log(‘Hi’) }

Slide 28

Slide 28 text

Browser Disk src index.ts a.ts Vite Dev Server transformMiddleware import A from ‘./a’ type MyType = true function fn(): void { console.log(‘Hi’) } GET /src/main.ts

Slide 29

Slide 29 text

Browser Disk src index.ts a.ts Vite Dev Server transformMiddleware import A from ‘./a’ type MyType = true function fn(): void { console.log(‘Hi’) } import A from ‘/src/a.ts’ function fn() { console.log(‘Hi’) } GET /src/index.ts

Slide 30

Slide 30 text

Browser Disk src Vite Dev Server transformMiddleware import A from ‘/src/a.ts’ function fn() { console.log(‘Hi’) } import A from ‘/src/a.ts’ index.ts a.ts import A from ‘./a’ type MyType = true function fn(): void { console.log(‘Hi’) }

Slide 31

Slide 31 text

Browser Disk src Vite Dev Server transformMiddleware import A from ‘/src/a.ts’ function fn() { console.log(‘Hi’) } import A from ‘/src/a.ts’ GET /src/a.ts index.ts a.ts import A from ‘./a’ type MyType = true function fn(): void { console.log(‘Hi’) }

Slide 32

Slide 32 text

Browser Disk src Vite Dev Server transformMiddleware import A from ‘/src/a.ts’ function fn() { console.log(‘Hi’) } import A from ‘/src/a.ts’ GET /src/a.ts index.ts a.ts import A from ‘./a’ type MyType = true function fn(): void { console.log(‘Hi’) }

Slide 33

Slide 33 text

Browser Disk src Vite Dev Server transformMiddleware import A from ‘/src/a’ function fn() { console.log(‘Hi’) } import A from ‘/src/a’ GET /src/a.ts Runnable JavaScript Code index.ts a.ts import A from ‘./a’ type MyType = true function fn(): void { console.log(‘Hi’) }

Slide 34

Slide 34 text

• File contents are transformed by plugins • Vite does not build your application with Rollup

Slide 35

Slide 35 text

Plugin System

Slide 36

Slide 36 text

Plugin System Vite vs. Rollup • Vite plugins extends Rollup's plugin interface • Most Rollup plugin can be used as Vite plugins: • if It doesn’t use moduleParsed hook • if it doesn't have strong coupling between bundle- phase hooks and output-phase hooks Rollup Plugins Vite Plugins https://vite.dev/guide/api-plugin.html

Slide 37

Slide 37 text

Plugin System The Missing Piece ? Vite Rollup Build Dev Vite plugins Vite plugins

Slide 38

Slide 38 text

Plugin Container Plugin System The Missing Piece Vite Rollup Build Dev Vite plugins Vite plugins

Slide 39

Slide 39 text

Plugin Container

Slide 40

Slide 40 text

Plugin Container Rollup Emulator • Implements Rollup plugin driver interface • Emulates Rollup plugin hooks in dev mode

Slide 41

Slide 41 text

That’s it

Slide 42

Slide 42 text

Plugin C Plugin Container resolveId Hook • resolveId hook of plugins are called sequentially • First non-nullable result is used as module ID Plugin A resolveId() Plugin Container resolveId() Returns null Returns string Plugin B

Slide 43

Slide 43 text

Plugin Container load Hook • load hook of plugins are called sequentially • First non-nullable result is used as source code Plugin C Plugin A load() Plugin Container load() Returns null Returns string Plugin B

Slide 44

Slide 44 text

Plugin Container transform Hook • transform hook of plugins are called sequentially • Final result is used as actual code Plugin C Plugin A transform() Plugin Container Returns A Plugin B transform() Returns B

Slide 45

Slide 45 text

• Vite makes up JavaScript code runnable in browser through 3 plugin hooks • Vite provides some built-in plugins • TypeScript is transpiled by esbuild

Slide 46

Slide 46 text

Summary

Slide 47

Slide 47 text

• Vite con fi g is built by esbuild • Dependencies are built by esbuild and stored as cache on dev server bootstrap • Vite does not build your application on dev server bootstrap, which is why it starts fast • index.html is the starting point from which your application is built • Plugin container makes it possible to partially build your application on demand

Slide 48

Slide 48 text

Acknowledgements Vite Study Members • aki • Jabelic • Jumpei Yamada • keigo • shoma mano • taka • ubugeeei • Yuma • ͍ͪΉΒ Ώ͏· • ͓ʔ͍͐͡ • ͔Β͜Ζ • πϊ In alphabetical order

Slide 49

Slide 49 text

Coming soon chibivite

Slide 50

Slide 50 text

Thank you