Upgrade to Pro — share decks privately, control downloads, hide ads and more …

被 Vue 框架耽誤的建置工具

高見龍
August 19, 2023

被 Vue 框架耽誤的建置工具

許多現在的前端開發框架都有如 Webpack 或 Parcel 之類的 bundle 工具,而 Vue 卻選擇了另外開發自己的構建工具 - Vite,不只設定簡單,效能還驚人的好,甚至在 Vue 以外的框架也能使用。 官方網站已經介紹了不少它的功能及運作方式,但身為工程師應該要有的好奇心,我想不只靠文件,還希望藉由閱讀 Vite 原始程式碼,介紹 Vite 的內部的設計方式,以及它為什麼可以這麼快。

高見龍

August 19, 2023
Tweet

More Decks by 高見龍

Other Decks in Programming

Transcript

  1. 五倍學院 { "name": "vite", "version": "4.4.9", "type": "module", "license": "MIT",

    "author": "Evan You", "description": "Native-ESM powered web dev build tool", // ..略.. "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", "rollup": "^3.27.1" } } vite/package.json v4.4.9
  2. 五倍學院 try { fetchedModule = await import( /* @vite-ignore */

    base + acceptedPathWithoutQuery.slice(1) + `?${explicitImportRequired ? 'import&' : ''}t=${timestamp}${ query ? `&${query}` : '' }` ) } catch (e) { warnFailedFetch(e, acceptedPath) } node/client/client.ts
  3. 五倍學院 httpServer.listen = (async (port: number, ...args: any[]) => {

    try { // ensure ws server started ws.listen() await initServer() } catch (e) { httpServer.emit('error', e) return } return listen(port, ...args) }) as any node/server/index.ts
  4. 五倍學院 if (cachedMetadata && cachedMetadata.hash === getDepHash(config, ssr)) { log?.('Hash

    is consistent. Skipping. Use --force to override.') return cachedMetadata } node/optimizer/optimizer.ts
  5. 五倍學院 async ensureEntryFromUrl( rawUrl: string, ssr?: boolean, setIsSelfAccepting = true,

    ): Promise<ModuleNode> { return this._ensureEntryFromUrl(rawUrl, ssr, setIsSelfAccepting) } node/server/moduleGraph.ts
  6. 五倍學院 // for incoming urls, it is important to: //

    1. remove the HMR timestamp query (?t=xxxx) and the ?import query // 2. resolve its extension so that urls with or without extension all map to // the same module async resolveUrl(url: string, ssr?: boolean): Promise<ResolvedUrl> { url = removeImportQuery(removeTimestampQuery(url)) const mod = await this._getUnresolvedUrlToModule(url, ssr) if (mod?.id) { return [mod.url, mod.id, mod.meta] } return this._resolveUrl(url, ssr) } node/server/moduleGraph.ts