構建工具和腳手架:從源碼到dist

構建工具和腳手架:從源碼到dist

    • **1. 為什么需要工程轉換?**
    • **2. 構建工具的核心職責**
      • 為什么要求轉換
      • **1)明確三種關鍵問題**
      • **(2)Webpack 的打包機制**
    • **3. 開發服務器(Webpack Dev Server)**
    • **4. 文件指紋與源碼地圖**
      • **(1)文件指紋(Hash)**
      • **2)源碼地圖(Source Map)**
    • **5. 腳手架:工程化的最后一環**

1. 為什么需要工程轉換?

  • 開發環境 vs. 運行時環境的不一致性

    • 開發時:使用現代語法(JSX/Sass/ESM)、npm 管理依賴
    • 運行時:瀏覽器僅支持標準 JS/CSS,無法直接識別 node_modules
    • 構建工具的作用:將開發環境的代碼轉換成瀏覽器可執行的代碼
  • 工程結構的變化

    • 開發時:模塊化、依賴關系清晰(import/require

    • 運行時:扁平化靜態資源(dist 目錄,含 index.html + bundle.js

工程的轉換,命令是 **npm run build** 進行打包,打包完成會生成一個 dist 目錄,這個目錄里面有個 html 文件,有個 js 有 css,還有 assets 文件,這就是轉換的結果。

2. 構建工具的核心職責

為什么要求轉換

思考一個問題,我們為什么要去轉換? 是因為我們開發和維護的代碼和運行時需要的代碼不一致了。

我們使用一個語言新的特性,不想去考慮兼容問題,但是運行時不能不考慮,運行時的代碼就希望兼容性更好。再比如說,開發和維護的代碼希望使用一些非常簡便的語法,像 jsx,sass,我們需要對語言進行增強,這個寫起來更舒服,生產效率更高,但是這個運行時它不支持,而運行時需要的代碼是什么呢,是一個非常純粹滿足語言標準的代碼,沒有那些花里胡哨的代碼。

因為開發和維護的代碼和運行時的代碼不一致,所以我們需要一個東西去轉換,這是對代碼層面的。同樣,工程層面也是一個道理,我們開發和維護的工程和運行時的工程不一樣。我們開發和維護的時候希望可以使用 npm 去安裝各種第三方庫,生成 node_modules,但是運行時不行,瀏覽器環境并不支持 npm ,所以我們運行時的工程是非常傳統的,也就是說打包之后的代碼它就完全脫離了開發的環境。我們打包之后的代碼跟傳統代碼一樣通過index.html 右鍵在瀏覽器上運行。

我們開發的時候的工程和運行時的工程結構不一致了,所以我們就需要找一個東西來進行這個轉換,而進行轉換的工具就叫做構建工具。所以構建工具是用來進行工程的轉換的。

1)明確三種關鍵問題

  1. 哪種工程更適合開發和維護?

    • Webpack:一切皆模塊(JS/CSS/圖片均可 import
  2. 哪種工程更適合運行時?

    • 傳統 HTML+JS+CSS 結構,可直接在瀏覽器運行
  3. 如何轉換(打包)?

    • 依賴分析 → 代碼轉換(Babel/Loader)→ 合并優化

這三個問題沒有標準,這就造成了在不同的需求下,從不同的角度出發,著力點不一樣,這三個點的理解可能就不一樣,于是就造成了各種構建工具的差異。構建工具有很多,webpack、rollup、esbuild等等,這些構建工具的本質差異是什么,其實就是對上邊這三點的理解不一致。

webpack的這三個東西

  1. 哪種工程更適合開發和維護 (一切皆為模塊,都可以進行導入)
  2. 哪種工程更適合運行時 (傳統工程,就是最開始的html右鍵瀏覽器運行)
  3. 如何轉換(打包) (以一個文件為入口點出發,去尋找他們的依賴關系,導入誰就依賴誰,然后就形成了一大堆文件,最后進行合并,把所有的 JS 文件合并在一起,把所有的 CSS 文件合并在一起,less 代碼該轉換轉換,資源文件就單獨形成各自的文件)

(2)Webpack 的打包機制

  • 依賴分析(不運行代碼,而是解析 AST)

    • 支持 ESM (import)CJS (require)

    • 模塊查找規則:

      • ./../ → 相對路徑
      • ./ 開頭 → node_modules 查找(遵循 package.jsonmain 字段)
  • 打包結果的特點

    • 無模塊化語法(import/require 被替換)
    • 合并 JS/CSS(減少 HTTP 請求)
    • 文件指紋(Hash 值,優化緩存)

    weboack 的入口,在分析依賴關系的時候,具體是如何分析的呢?它分析的方式并不是去運行這個代碼,而是把整個代碼看成是一個字符串,webpack 是不會去運行代碼的,它就是來進行打包轉換的,把入口文件告訴 webpack,會把這個文件的內容讀出來,讀出來過后分析一下這個文件用到了哪些其他的文件。

    它是怎么知道用到了哪些其他的文件的,它就是把整個代碼看成一個字符串,然后把這個字符串分解成為一個 AST(抽象語法樹),然后通過抽象語法樹去找到那些導入的語句,而且 webpack 是同時支持 ESM 和 CMJ 的,這就意味著在代碼中即可以使用 import 來進行導入,也可以使用 require 來進行導入,它都支持。

    這就解決了一個疑惑,說瀏覽器環境并不支持 CMJ,不能使用 require,那么為什么在 VUE 和 React 代碼里邊可以使用這個 require,是因為寫的 require、import 壓根不是給瀏覽器看的,是給構建工具看的,像 webpack 它來識別導入語句,因為它兩者都支持,所以兩種導入語句都能寫。

    無論寫的哪一種,實際上都是告訴 webpack 這里邊有依賴關系,然后它把依賴關系分析完之后進行打包,打包結果里邊不會包含任何的導入語句。也就是說在源代碼中寫的import、require 在打包結果里邊壓根就不存在了,打包結果里面是不存在任何的模塊化代碼。

    到哪里去找這個依賴的文件呢,也就是模塊的查找,在 webpack 中所有都是模塊,哪怕一個圖片都是模塊,到哪里去找這個圖片,去哪找這個 JS 呢? 有模塊的查找規則。

    比如說 import ‘./cover’,cover 是一個文件夾,會默認的去找這個文件夾的 index.js 文件,比如說 import $ from ‘jquery’,目錄里面沒有 jquery文件夾,這又是一個查找規則,當給的路徑不以’./‘,’…/'開頭時,這個時候用的是 node 模塊規則,看一下當前目錄有沒有 node_modules,然后在 node_modules 這個目錄里邊去尋找 jquery文件夾,又找到這個文件夾下面的package.json找到 'main’字段對應的文件,然后在這個文件找到對應的 jquery.js 文件。

3. 開發服務器(Webpack Dev Server)

  • 作用:實時編譯 + 自動刷新

  • 運行機制

    1. 啟動 express 服務器
    2. 內存打包(不生成 dist,直接放在內存)
    3. 監聽文件變化 → 重新編譯 → 通知瀏覽器刷新

現在是可以進行轉換了,但是該怎么運行呢,不能說每寫一行代碼就去運行一個命令 npm run build 把 dist 在新的工程打開把頁面運行出來。能不能一邊寫代碼一邊自動運行,在 webpack 中使用的辦法就是使用開發服務器

運行命令 npm run serve,運行之后會給地址。點擊打開就運行出來了,就不用再去先打包然后再用 VScode 去打開這個打包結果再運行。

開發服務器(webpack serve)是由 webpack-dev-server(是webpack 的一個庫) 啟動的,webpack-dev-server 里面又依賴了 express 。

當我們運行 webpack serve 的時候,它會利用 webpack-dev-server 啟動一個開發服務器,與此同時它會去進行打包,相當于幫我們運行了一個 npm run build,只不過這次打包是在內存里邊完成,并不會把打包的結果形成文件,在內存中形成打包結果。

然后控制臺會給一個提示,讓去訪問哪一個地址,當訪問地址時就會打開瀏覽器,瀏覽器會自動的出現這個地址,由瀏覽器去訪問開發服務器,于是瀏覽器向開發服務器發送請求,然后開發服務器會從內存中的打包結果中去拿到一個頁面(index.html),把頁面響應給瀏覽器。瀏覽器就可以看到頁面了,瀏覽器拿到頁面之后就要去渲染頁面了,渲染頁面的工程中會去繼續請求 JS、CSS,開發服務器又回去內存中的打包結果取出相應的 JS、CSS相應給瀏覽器,這樣一來瀏覽器就把整個頁面運行出來了。

這就是整個過程,省略了手動的去打包,手動的去運行瀏覽器的過程。

這樣還能實現源碼變化后自動刷新的功能。是因為 webpack serve 還有個功能,它可以監聽文件的變化,當文件發生變化時,它會觸發重新打包,也就是說更改了內存中的打包結果。光更改沒用,還得讓瀏覽器刷新,一刷新就要重新請求,重新請求得重新拿打包結果,就拿到了新的打包結果,相應的就是新的內容。

4. 文件指紋與源碼地圖

(1)文件指紋(Hash)

  • 作用:確保內容不變時用緩存,內容變化時立即更新
  • 示例main.a3b4c5.js(哈希值隨內容變化)

打包的 js 或 css 名稱奇奇怪怪的字母數字是文件指紋,其實就是哈希值的前幾位,會隨著源碼的內容的變化而變化的。文件指紋既可以保證文件內容沒變時一直使用緩存結果,也可以保證內容變化之后立即使用最新的結果。

2)源碼地圖(Source Map)

  • 作用:調試時映射回原始代碼(而非打包后的代碼)
  • 文件.map 文件(關聯 bundle.js 和源碼)

源碼地圖:打包后’.map’后綴的,是可以讓我們更好的去調試,如果沒有源碼地圖,我們去調試時開發者工具打斷點顯示的代碼是打包之后的代碼而不是源碼,源碼地圖讓打包后的代碼和源碼相對應。

5. 腳手架:工程化的最后一環

vue-cli 、 vite 、 cra 、umijs 等等

雖然有了構建工具,這些目錄結構的安排得自己去組織,構建工具里面的配置得一行一行去寫,各種具體的插件得自己去安裝。這時候就希望有一個工具能幫我們把這些給做了,這個工具就是腳手架,腳手架是用來干什么的,就是來搭工程的。
  • 為什么需要腳手架?

    • 構建工具配置復雜(Webpack 配置、Babel、Loader)
    • 項目結構標準化(如 Vue/React 官方推薦目錄)
  • 核心功能

    1. 命令行交互(選擇框架、配置項)

    2. 生成標準化工程模板(預置 webpack.config.jsbabelrc 等)

    根據你的選擇,它給你提供一個工程結構,那些依賴幫我們處理好,配置幫我們考慮好

    1. 集成最佳實踐(如 Vue CLI 默認支持 SassRouter

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94090.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94090.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94090.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數字化生產管理系統設計

下面提供一個基于Python的數字化管理系統框架,使用現代技術棧實現。這個系統將包含設備監控、故障管理、裝配配套表生成、生產計劃管理等功能。系統架構數字化生產管理系統 ├── 設備監控模塊 ├── 故障管理模塊 ├── 產品裝配管理模塊 ├── 生產計劃管理模…

【vue】創建響應式數據ref和reactive的區別

目錄 1、所謂響應式數據 2、ref創建基本類型響應式數據 3、reactive創建對象類型響應式數據 4、ref定義對象類型響應式數據 5、總結:ref和reactive對比 6、補充:toRefs與toRef 1、所謂響應式數據 所謂響應式數據就是,在vue頁面中&#…

YOLO12 改進、魔改|直方圖 Transformerm模塊HTB ,通過動態范圍特征分組、針對性注意力與多尺度融合,提高對遮擋以及多尺度目標的關注能力

在惡劣天氣(如雨、雪、霧)下的圖像恢復任務中,傳統 Transformer 模型為降低計算量,常將自注意力限制在固定空間范圍或僅在通道維度操作,導致難以捕捉長距離空間特征,尤其無法有效處理天氣退化像素&#xff…

涉水救援機器人cad【12張】三維圖+設計書明說

涉水救援機器人設計 摘 要 隨著城市化進度的加快,各種水上游樂設備的增多,水上災害和溺水事件頻繁發生,水上救援任務困難重重,特別是在一些水流湍急的環境下進行救援。傳統的水上救援工作比較緩慢,大多數是通過投射救…

電子病歷:現代HIS系統不可或缺的核心組成部分

一、電子病歷在 HIS 系統中扮演了一個什么角色?電子病歷在醫院信息系統(HIS)中扮演著核心、基礎且不可替代的角色,可以說是整個HIS系統的臨床信息中樞和業務驅動引擎。它的重要性體現在以下幾個方面:1、臨床診療活動的核心載體&a…

【深度學習】通俗易懂的基礎知識:指數加權平均

一、什么是指數加權平均? 指數在數學中表示一個數的冪次運算(如a?中的n),而在統計學中特指隨時間變化的幾何衰減系數,加權指對不同數據賦予不同權重,使重要數據對結果產生更大影響。指數加權平均指是一種時…

c++-list

C-list std::list是C標準模板庫(STL)提供的雙向鏈表容器&#xff0c;它提供了高效的插入和刪除操作&#xff0c;特別適合頻繁修改的序列。定義在 <list> 頭文件中&#xff0c;屬于 std 命名空間。該類的接口與常規容器接口基本一致。 模板原型&#xff1a; template <…

【筆試真題】2024秋招京東后端開發崗位-第一批筆試

31.牛牛與切割機 有一個序列 a1,a2,...,ana_1,a_2,...,a_na1?,a2?,...,an? &#xff0c; 牛牛將對這個序列切割一刀&#xff08;劃分分成兩個不相交的非空序列&#xff0c;一個序列為 a1,...,apa_1,...,a_pa1?,...,ap?&#xff0c;另一個序列為 ap1,...,ana_{p1},...,a_na…

【整數轉羅馬數字】

思路計算數字的位數&#xff1a; 通過 while(x) 循環計算輸入數字 num 的位數 n。提取各位數字&#xff1a; 將數字 num 的每一位分解并存儲到 nums 數組中&#xff0c;順序為從高位到低位。羅馬數字映射&#xff1a; 使用固定數組 Roman 存儲羅馬數字符號&#xff1a;Roman {…

spring Scheduled注解詳解

spirng Scheduled注解詳解 用于標記需要安排執行的方法的注解。必須指定 cron、fixedDelay 或 fixedRate 中的恰好一個屬性。 被標注的方法必須不接受任何參數。它通常會具有 void 類型的返回值&#xff1b;如果不是這樣&#xff0c;那么在通過調度器調用該方法時&#xff0c;返…

新升級超值型系列32位單片機MM32G0005

靈動微推出的新型MM32G0005系列基于ArmCortex - M0內核&#xff0c;具備高可靠性、低功耗、高性價比等特性。Flash升級至64KB&#xff0c;SRAM為4KB&#xff0c;還有1KB Data Flash。Flash全溫擦寫次數超過10萬次。采用24Pin封裝&#xff0c;最多有22個IO。QFN20和TSSOP20封裝與…

Spark SQL 的詳細介紹

Spark SQL 是 Apache Spark 生態系統中用于處理結構化數據的模塊&#xff0c;它將 SQL 查詢與 Spark 的分布式計算能力相結合&#xff0c;提供了一種高效、靈活的方式來處理結構化和半結構化數據。以下是對 Spark SQL 的詳細介紹&#xff1a;1. 核心定位與優勢結構化數據處理&a…

【FreeRTOS】空閑任務與鉤子函數原理、實現與功能詳解

一、FreeRTOS空閑任務概述FreeRTOS中的空閑任務(Idle Task)是系統自動創建的一個特殊任務&#xff0c;具有最低優先級(優先級0)。當沒有其他更高優先級的任務運行時&#xff0c;調度器就會運行空閑任務。空閑任務的主要功能系統資源回收&#xff1a;自動清理被刪除任務的內存和…

imx6ull-驅動開發篇6——Linux 設備樹語法

目錄 前言 設備樹 設備樹概念 DTS、 DTB 和 DTC DTS 語法 .dtsi 頭文件 設備節點 /根節點?? 節點命名與標簽 節點層次結構? 屬性數據類型? 標準屬性 compatible 屬性 model 屬性 status 屬性 #address-cells 和#size-cells 屬性 reg 屬性 ranges 屬性 n…

ansible簡單playbook劇本例子2

1. 準備主機組[rootansible-master ansible_quickstart]# vim inventory/hosts[web:vars] ansible_port22 ansible_passwordAdmin123456[web] 192.168.100.1822.準備劇本 vim hello.yml--- - hosts: webremote_user: roottasks:- name: Ping the target hostsping:- name: 獲取…

EmpService 和 EmpMapper接口的作用

在這個項目中&#xff0c;EmpService 和 EmpMapper 都定義接口&#xff0c;是基于面向接口編程&#xff08;Interface Oriented Programming&#xff0c;IOP&#xff09;的設計思想&#xff0c;這兩種接口在項目中承擔著不同的職責&#xff0c;具體說明如下&#xff1a; EmpSer…

【語音技術】什么是動態實體

目錄 動態實體的定義和維度 1.1 動態實體的資源 1.2 生效維度 1.2.1 應用級 1.2.2 用戶級 1.2.3 自定義級 2. 動態實體的上傳及使用 2.1 WebAPI 2.1.1 授權認證 2.1.2 上傳資源接口 2.1.2.1 參數說明 2.1.2.2 返回說明 2.1.3 查詢打包狀態 2.1.3.1 參數說明 2.1.…

STM32學習記錄--Day3

今天了解了下I2C&#xff1a;1.I2C電路結構I2C通信示意圖&#xff1a;數據傳輸階段????主→從模式??&#xff08;寫操作&#xff09;&#xff1a;主機控制SCL時鐘&#xff08;把SCL拉低&#xff09;主機向SDA線發送數據&#xff08;每次8位1位ACK&#xff09;??主←從模…

裂變數據看板:5個核心指標決定活動生死?

數據是裂變活動的“指南針”。本文詳解曝光量、轉化率、裂變系數等5大核心指標&#xff0c;結合工具與案例&#xff0c;教你用數據驅動活動優化&#xff0c;避免“自嗨式裂變”。?為什么數據是裂變的“生死線”&#xff1f;&#xff08;認知重構&#xff09; 很多企業裂變活動…

iOS 類存儲 與 C# 類存儲 的差異

C# 中類的代碼&#xff08;包括方法、屬性等成員&#xff09;的存儲機制與 Objective-C 有顯著差異&#xff0c;其核心依賴于 ?CLR&#xff08;公共語言運行時&#xff09;的方法表&#xff08;Method Table&#xff09;和虛擬方法表&#xff08;vtable&#xff09;機制&#…