都2024年了你還傻傻分不清楚“編譯時”和“執行時”嗎?

前端欧阳發表於2024-07-22

前言

在寫vue3編譯原理揭秘電子書的時候,發現有不少粉絲還傻傻分不清楚什麼是編譯時?什麼是執行時?這篇文章我們來讓你徹底搞清楚編譯時和執行時的區別。

關注公眾號:【前端歐陽】,給自己一個進階vue的機會

編譯時

我將編譯這個詞語理解為翻譯,這句話是什麼意思呢?

比如你要和一個老外溝通,你的英文超級爛。所以你說的是中文,老外卻只理解英文。那你們兩個人怎麼溝通呢?所以你需要一個翻譯器來將你說的中文轉換為英文,這樣老外就能理解你說的話了,這個翻譯過程就是我們常說的編譯時

translate

看完上一個例子如果你還沒理解的話,我們再來看一個vue的例子。我們平時寫vue程式碼時一般都是寫在檔案字尾名為.vue檔案中,也就是官方說的單檔案元件 (SFC)。

但是瀏覽器認識字尾為.vue的單檔案元件 (SFC)嗎?

很明顯瀏覽器是不認識的,所以這個時候需要將字尾為.vue的單檔案元件 (SFC)編譯(翻譯)為瀏覽器認識的js檔案,這一過程就是我們常說的編譯時

在前端中,一般來說編譯時就是程式碼跑在node.js的階段。

大家都知道前端主要分為兩個環境:生產環境和開發環境。

  • 對於生產環境來說,編譯時就是在執行類似yarn build之類的命令,將原始碼打包成瀏覽器可直接執行的程式碼這一過程。打包生成的程式碼檔案是存在磁碟中,這一過程是在node.js中完成的。

  • 對於開發環境來說,編譯時就是在執行型別yarn dev這種啟動命令,同樣將原始碼編譯成瀏覽器可直接執行的程式碼這一過程。和生產環境不同的是生成的程式碼檔案是存在記憶體中,並不會寫到磁碟中,同樣這一過程是在node.js中完成的。

執行時

還是以vue舉例,大家都知道瀏覽器的渲染過程是將一個html檔案渲染到頁面上的。在SPA單頁面中瀏覽器接收到的index.html一般是下面這樣的,如下圖:
html

從上圖中可以看到接收到的html檔案中只有一個<div id="app"></div>,那麼瀏覽器又是怎麼從這個空div渲染成豐富多彩的頁面呢?

熟悉vue原始碼的同學應該比較清楚,首先是生成一個app物件,然後呼叫app物件的mount方法將經過編譯時處理後拿到的vue元件物件掛載到<div id="app"></div>上面。這一過程就是所謂的執行時。

對於前端來說,執行時就是程式碼執行在瀏覽器的階段。

在瀏覽器中編譯

看到這裡有的小夥伴會有疑惑了,vue好像還提供了一種全域性構建的版本。在這個版本中我們可以直接在html檔案中使用vue,無需使用webpack或者vite這種打包工具打包。比如下面這樣:
global

從上圖中可以看到,這種用法中除了將*.vue檔名替換為*.html檔名之外,其他的寫法基本是一模一樣的。在這種用法中由於沒有使用到構建工具webpack或者vite,當然就沒有在node.js中執行的編譯時,那麼這種用法中瀏覽器又是如何識別單檔案元件 (SFC)中的<template><script><style>等模組呢?

答案是在這種全域性構建版本的vue中會內建一個編譯器。在瀏覽器中執行時如果發現了<template><script><style>等模組的程式碼就會使用內建的編譯器將這些模組編譯成瀏覽器可執行的程式碼。

所以我們前面才會講:一般來說編譯時就是程式碼跑在node.js的階段。不一般的情況就是現在這種情況,vue直接內建了一個編譯器,在瀏覽器中進行編譯。但是話說回來,這種在瀏覽器中編譯的模式,效能肯定不如使用構建工具webpack或者vite提前將資源進行打包。

總結

一般情況下編譯時就是程式碼跑在node.js的階段,比如執行yarn dev或者yarn build時程式碼在node.js中執行的階段。後面我們又講了執行時實際就是程式碼在瀏覽器中執行的階段。

最後我們又講了還有一種特殊的情況,像全域性構建版本的vue中會內建一個編譯器。讓我們可以脫離webpack或者vite使用vue,這種情況就是在瀏覽器中進行編譯的模式,當然這種模式的效能肯定不如使用構建工具webpack或者vite提前將資源進行打包。

關注公眾號:【前端歐陽】,給自己一個進階vue的機會

相關文章