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. 五倍學院
    被 Vue 框架耽誤的建置工具

    View Slide

  2. 五倍學院
    Vite /vit/

    View Slide

  3. 五倍學院
    關公面前耍小刀

    View Slide

  4. 五倍學院
    今天內容:新手以上,資深未滿

    View Slide

  5. 五倍學院
    npm run dev 之後發生什麼事?

    View Slide

  6. 五倍學院
    自我介紹

    View Slide

  7. 五倍學院
    愛玩、愛現,喜歡冷門的玩具


    網站開發者、講師、作家


    技術推廣、企業訓練、技術諮詢


    部落格:kaochenlong.com
    高見龍
    @eddiekao

    View Slide

  8. 五倍學院
    第26刷 發售中 發售中
    發售中

    View Slide

  9. 五倍學院
    已絕版

    View Slide

  10. 五倍學院
    歡迎加
    好友

    View Slide

  11. 五倍學院
    被 Vue 框架耽誤的建置工具

    View Slide

  12. 五倍學院
    我是個 Rails Developer

    View Slide

  13. 五倍學院
    Rails 4: assets pipeline


    Rails 5 ~ 6: webpack


    Rails 7: importmap

    View Slide

  14. 五倍學院
    vite_rails

    View Slide

  15. 五倍學院
    不只可以用在 Vue 專案上!

    View Slide

  16. 五倍學院
    一般的香草 JS 專案可以用

    View Slide

  17. 五倍學院
    連 React 也能用 Vite!


    身在曹營心在漢
    真香

    View Slide

  18. 五倍學院
    模組化

    View Slide

  19. 五倍學院
    no module
    石器時代

    View Slide

  20. 五倍學院
    CommonJS、AMD、ESM


    大亂鬥!
    戰國時代

    View Slide

  21. 五倍學院
    ESM 原生支援
    美好時代

    View Slide

  22. 五倍學院
    打包工具 vs 建置工具
    Bundler vs Building Tool

    View Slide

  23. 五倍學院
    打包工具
    將多個原始檔(例如 .js、.css 或圖片)合併成較
    少數量的文件。


    通常可透過壓縮程式碼、圖片或是檔案名雜湊等方
    式,提高性能和快取利用率。


    例:Webpack, Parcel, Rollup

    View Slide

  24. 五倍學院
    建置工具
    在不同階段或環境執行的各種任務,例如跑測試、
    原始碼轉譯、CSS 樣式預處理、圖片最佳化等。


    或是讓開發者可以在開時階段使用較新的語法,但
    最後再將其轉換成瀏覽器看的懂的內容。


    例:Gulp, npm script

    View Slide

  25. 五倍學院
    那 Vite 算是哪一種?

    View Slide

  26. 五倍學院
    Vite 本身就是個 dev server

    View Slide

  27. 五倍學院
    閱讀原始碼

    View Slide

  28. 五倍學院
    Why?

    View Slide

  29. 五倍學院
    你不需要每行都看懂

    View Slide

  30. 五倍學院
    使用工具:Visual Studio Code
    sual Studio Code

    View Slide

  31. 五倍學院
    Goto / Ctrl + -

    View Slide

  32. 五倍學院
    {


    "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

    View Slide

  33. 五倍學院
    $ npm run dev

    View Slide

  34. 五倍學院
    CLI


    Command-Line Interface

    View Slide

  35. 五倍學院
    const cli = cac('vite')
    node/cli.ts

    View Slide

  36. 五倍學院

    View Slide

  37. 五倍學院
    const { createServer } = await import('./server')
    node/cli.ts

    View Slide

  38. 五倍學院
    const watcher = chokidar.watch(


    [root, ...config.configFileDependencies, config.envDir],


    resolvedWatchOptions,


    ) as FSWatcher
    node/server/index.ts

    View Slide

  39. 五倍學院

    View Slide

  40. 五倍學院
    watcher.on('change', async (file) => {


    file = normalizePath(file)


    moduleGraph.onFileChange(file)


    await onHMRUpdate(file, false)


    })
    node/server/index.ts

    View Slide

  41. 五倍學院
    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

    View Slide

  42. 五倍學院
    Vite 是一個 dev server

    View Slide

  43. 五倍學院
    原始碼檔案異動時...

    View Slide

  44. 五倍學院
    透過 client(ws) 發動 import

    View Slide

  45. 五倍學院
    Pre-Bundling

    View Slide

  46. 五倍學院
    現在不是原生支援 ESM 了嗎?

    View Slide

  47. 五倍學院
    大量的 import request?

    View Slide

  48. 五倍學院

    View Slide

  49. 五倍學院
    esbuild

    View Slide

  50. 五倍學院
    掃描原始碼裡的 import

    View Slide

  51. 五倍學院
    node_modules/.vite

    View Slide

  52. 五倍學院
    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

    View Slide

  53. 五倍學院
    if (cachedMetadata && cachedMetadata.hash === getDepHash(config, ssr)) {


    log?.('Hash is consistent. Skipping. Use --force to override.')


    return cachedMetadata


    }
    node/optimizer/optimizer.ts

    View Slide

  54. 五倍學院
    啟動 → 檢查 Hash

    View Slide

  55. 五倍學院
    Module Graph

    View Slide

  56. 五倍學院
    Module Node

    View Slide

  57. 五倍學院
    async ensureEntryFromUrl(


    rawUrl: string,


    ssr?: boolean,


    setIsSelfAccepting = true,


    ): Promise {


    return this._ensureEntryFromUrl(rawUrl, ssr, setIsSelfAccepting)


    }
    node/server/moduleGraph.ts

    View Slide

  58. 五倍學院
    // 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 {


    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

    View Slide

  59. 五倍學院
    // main transform middleware


    middlewares.use(transformMiddleware(server))
    node/server/index.ts

    View Slide

  60. 五倍學院
    小結

    View Slide

  61. 五倍學院
    Vite 出生在對的時代

    View Slide

  62. 五倍學院
    瀏覽器對 ESM 的原生支援

    View Slide

  63. 五倍學院
    importmap 也是

    View Slide

  64. 五倍學院
    把粗重活交給別人處理

    View Slide

  65. 五倍學院
    原始碼 → Webpack → 打包 →
    丟給 dev server

    View Slide

  66. 五倍學院
    原始碼 → Vite → 給瀏覽器 →
    有異動再 import

    View Slide

  67. 五倍學院
    esbuild + rollup

    View Slide

  68. 五倍學院
    解決了 DX 不佳的問題


    DX = Developer Experience

    View Slide

  69. 五倍學院
    真香!

    View Slide

  70. 五倍學院
    工商服務

    View Slide

  71. 五倍學院
    talentd.cc

    View Slide

  72. 五倍學院
    歡迎加
    好友

    View Slide