博客 / 詳情

返回

Taro編譯mini-runner包的作用

什麼是Taro

Taro 是一套遵循多端開發的解決方案。只需要一套代碼,就可以編譯轉換成 RN、H5、小程序、快應用多端的運行代碼,其運轉流程主要分為編譯時,運行時兩個階段。

Taro2(重編譯,輕運行)

  • 編譯時:通過taro工具將Taro源代碼轉換成目標代碼
  • 運行時:目標代碼運行時,通過運行時的庫去適配不同端

圖片

Taro3(輕編譯,重運行)
Taro3主要通過在小程序端模擬實現 DOM、BOM API 來讓前端框架直接運行在小程序環境中,而對於生命週期、組件庫、API、路由等差異,通過定義統一標準,在運⾏時會提供 React 和 Vue 對應的適配器進⾏適配,然後調⽤Taro提供的 DOM 和 BOM API, 最後把整個程序渲染到所有的⼩程序端上⾯。

圖片

編譯流程

Taro本質上是進行多端編譯和運行,而Taro的編譯主要依賴於webpack配置,Taro則通過mini-runner完成webpack配置的組裝,然後根據 webpack 配置生成編譯後的代碼。

tarojs/mini-runner的作用

  • 負責根據開發者的編譯配置調整 webpack 配置
  • 注入自定義的 插件 和 loader
  • 調用 webpack 開啓編譯
  • 修改 webpack 的編譯產物,調整最終的編譯結果

圖片

目錄結構

圖片

主流程(index)

主要分為兩個流程,根據項目配置生產webpack的構建配置,利用webpack進行代碼編譯。

圖片

基礎配置

base.config.ts 文件記錄基本配置信息,主要是Taro 構建過程中一部分 webpack 配置的初始化工作(包括文件擴展名、模塊解析路徑、別名等)。

圖片

自定義配置

buildConf.conf.ts 中主要負責配置一些構建過程中所需的插件、常量和選項,確保構建過程中能夠根據配置進行適當的處理和優化。

圖片

合併webpack配置

合併webpack配置,確保小程序項目在構建時能夠按照用户的配置和需求生成合適的 Webpack 配置。

圖片

分析配置

通過分析主包來進一步瞭解tarojs/mini-runner在其中的作用。

圖片

查看config配置

圖片

  • projectName: 項目名稱
  • date: 項目創建日期
  • designWidth: 設計稿寬度,用於進行適配
  • deviceRatio: 不同設備寬度的適配比例
  • sourceRoot: 源代碼目錄
  • outputRoot: 輸出目錄,根據環境變量進行不同的配置
  • plugins: 配置Taro框架使用的插件
  • env: 環境變量配置
  • defineConstants: 常量配置
  • copy: 複製文件的配置,將一些靜態文件複製到輸出目錄
  • framework: 項目框架
  • mini: 針對小程序的配置
  • h5: 針對H5平台的配置
  • alias: 路徑別名配置,簡化在代碼中的引用路徑

defineConstants

defineConstants 主要進行常量的相關配置。

圖片

首先將環境變量,靜態常量,運行時常量合併為一個常量對象definePlugin,通過getDefinePlugin 函數返回了一個配置好的 DefinePlugin 實例,definePlugin是Webpack的一個內置插件,用於替換代碼中的變量為其對應的值。

通過這個配置,Webpack 在構建時會將代碼中的 APPNAME 替換為 process.env.APPNAME 的值。同樣,其他常量也會按照相應的方式被替換。

圖片

copy

copy複製文件的配置,將一些靜態文件複製到輸出目錄,

  • patterns: 一個數組,指定了需要拷貝的文件或目錄的規則
  • options: 配置選項

圖片

不同環境拷貝不同的目標路徑,主要用於對地圖的適配。

圖片

在 patterns 數組中添加了一個額外的拷貝規則,將 plugin/doc 目錄拷貝到輸出目錄的 doc 目錄下,如果配置中存在copy 調取getCopyWebPackPlugin。

圖片

getCopyWebpackPlugin 函數接收一個包含 copy 配置的對象以及應用程序路徑 appPath。通過 CopyWebpackPlugin 創建實例,配置 patterns,將配置項中的相對路徑轉換為絕對路徑,確保正確的拷貝。返回創建的 CopyWebpackPlugin 實例。

圖片

alias

alias主要用於簡化在代碼中的引用路徑。

圖片

resolve 是一個配置選項,用於指定解析模塊請求的規則。alias 配置會被合併到 resolve 中。

在構建過程中,Webpack 將會使用這些別名來解析模塊的引入路徑。例如,當代碼中出現 import '@/ecoExpress/someModule' 時,Webpack 將會解析為 path.resolve(__dirname, '..', 'src/ecoExpress/someModule')。

圖片

mini

postcss

pxtransform 配置:

  • enable: true 表示開啓對 CSS 中的 px 單位進行轉換
  • config: 可以用於配置 pxtransform 的詳細選項,比如配置項的轉換規則
    url 配置:
  • enable: true 表示開啓對樣式文件中的圖片、字體等資源的 URL 轉換
  • config: { limit: 1024 } 限制轉換的資源大小,超過這個大小的資源將被單獨輸出文件,小於這個大小的資源將被轉換成 base64 編碼並嵌入樣式文件中

這個配置的目的是將小圖片、字體等資源直接轉換成 base64 編碼,減少網絡請求,提高小程序的加載速度。
cssModules 配置:

  • enable: false 表示不開啓 CSS Modules 功能。
  • config: 可以配置一些關於 CSS Modules 的選項,包括命名規則等

開啓了 CSS Modules,可以通過配置項進行定製化,CSS Modules 允許將 CSS 樣式作用域限制在組件內,避免全局樣式的污染。

圖片

查看config基礎配置,進行了一些預處理。

圖片

webpackChain

在 webpack 中,webpackChain 通常指的是一種鏈式調用的方式來配置 Webpack 的構建過程。在 Taro 中,webpackChain 主要是用於自定義和擴展 Webpack 配置的工具。

Taro 封裝了 webpack 的配置,提供了一些默認的配置,同時也允許開發者通過 webpackChain 自定義和擴展這些配置。這種鏈式調用的方式可以更方便地對 Webpack 配置進行修改和增強。

如下代碼可知,mini-runner 將內部 webpackChain 和開發者配置的 webpackChain 相結合,得到最終的webpackChain。

圖片

針對小程序進行配置。

圖片

先查看mini中的webpackChain,查看第一個插件 hitchFeCompontsImportPlugin,可以得出主要功能是匹配不同依賴路徑確定不同的配置。

圖片

multiPlatformPlugin,接着看下一個函數,這個方法的作用是為 Taro 項目配置 Webpack 的解析插件,限制只解析以 '@hb/' 開頭的模塊路徑,以支持 Taro 項目的多平台打包需求。

圖片

使用 webpack-bundle-analyzer 插件,並傳遞一個空數組 [] 作為配置(webpack-chain中 use的第二個參數,作為插件的配置,可以不填,但必須要是數組)。

圖片

使用自定義的 Stats 類創建的插件。這個插件的作用是在 Webpack 構建完成後將統計信息寫入一個文件(stats.json),以供進一步分析和處理。

圖片

  • 使用 chain.optimization 配置 Webpack 的優化
  • 調用 .minimizer() 方法,傳遞一個包含 TerserPlugin 實例的數組。TerserPlugin 用於壓縮 JavaScript 代碼
  • extractComments: false,配置了禁止提取註釋的選項,以防止將註釋提取到單獨的文件中

圖片

optimizeMainPackage

配置項 optimizeMainPackage 控制了主包的優化,只有在構建目標環境是微信小程序(TARO_ENV === 'weapp')時才啓用。主要的目的是在微信小程序中優化主包的構建。

圖片

判斷 optimizeMainPackage.enable 是否為 true,如果為 true,則使用 getMiniSplitChunksPlugin 函數創建了一個插件實例,並將其配置合併了 optimizeMainPackage 和 fileType。這個插件的作用是對小程序主包進行分包優化。

圖片

Webpack 提供了 SplitChunkPlugin 進行分包優化。SplitChunksPlugin 插件可以將應用程序中共享的代碼拆分成單獨的塊,以便將其從應用程序代碼中分離出來,從而提高性能和加載速度。

miniCssExtractPluginOption

miniCssExtractPluginOption用於指定 Mini CSS Extract 插件的選項。,其中 ignoreOrder 主要是為了避免關於樣式引入順序的警告。當為 true 時,表示忽略 CSS 文件的引入順序,不會拋出關於引入順序的警告。

圖片

baseLevel

對於不支持模板遞歸的小程序(微信、QQ、京東小程序),在 DOM 層級達到一定數量後,Taro 會使用原生自定義組件協助遞歸。

簡單理解就是 DOM 結構超過 N 層後,會使用原生自定義組件進行渲染。N 默認是 16 層,可以通過修改配置項 修改 N。

H5

再查看下H5中webpackChain的作用

圖片

首先跟小程序配置類似,先調用multiPlatformPlugin這個方法的作用是為 Taro 項目配置 Webpack 的解析插件,限制只解析以 '@hb/' 開頭的模塊路徑,以支持 Taro 項目的多平台打包需求。

然後chain.module.rules.get('script').exclude.clear().add([...]);:這一段代碼涉及到對 Webpack 規則的修改

  • chain.module.rules.get('script') 表示獲取名為 'script' 的規則
  • exclude.clear() 清空原有的排除規則
  • add([...]) 添加新的排除規則,其中傳入的函數用於判斷是否應該排除某個文件

這個規則的目的是排除一些特定的文件,包括 @tarojs/components 目錄下的文件,以滿足一定條件的 node_modules 下的文件,但不包括包含 taro 和 @hb/ 的文件。為了定製 Taro 在 H5 平台的構建規則。

圖片

然後調用hitchFeCompontsImportPlugin。

圖片

總結

總的來説在編譯方面,mini-runner 支持多端開發,使開發者能夠通過一套代碼適配不同的小程序平台。還提供了默認的構建配置,包括 loader、plugin、resolve 規則等,以滿足 Taro 框架的開發需求,並允許開發者通過配置文件或插件進行對構建過程的定製和擴展。

在對webpack配置方面,mini-runner 提供了webpackChain方法,使得開發者可以在 Webpack 配置中進行鏈式調用,方便自定義和增強配置。封裝了一套默認的 Webpack 配置,以適應 Taro 框架的特性和小程序平台的要求。此外,mini-runner 控制構建過程,提供一些配置項,例如是否監聽文件變化、是否啓用 source map 等。

附錄 - (mini-runner 部分源碼解析)

目錄結構

圖片

主流程(index)

主要分為兩個流程,根據項目配置生產webpack的構建配置,利用webpack進行代碼編譯。

圖片

基礎配置

進入 buildConf 函數,由代碼可知,首先調用了 getBaseConf ,進入該函數查看配置。

圖片

查看該配置,主要是Taro 構建過程中一部分 webpack 配置的初始化工作(包括文件擴展名、模塊解析路徑、別名等)。通過配置解析選項和引入 MultiPlatformPlugin 插件,支持跨平台文件。

  • 源文件使用的擴展名,這裏包括 '.js', '.jsx', '.ts', '.tsx', '.mjs', '.vue'
  • 指定導入模塊時使用 package.json 中的哪個字段,這裏的配置將優先使用 browser 屬性解析文件,其次是 module,最後是 main
  • symlink
  • 告訴 webpack 解析模塊時應該搜索的目錄,這裏對應的就是 node_modules 目錄
  • 解析 webpack loader 包,指定 node_modules 目錄
  • 代碼包是包含副作用的,不希望被 tree shaking 優化
  • 配置node環境,在構建過程中對 fs(文件系統模塊)和 path(路徑模塊)的引用替換為一個空對象,從而在瀏覽器環境中模擬文件系統和路徑操作,在瀏覽器環境中,一些 Node.js 特定的模塊是不可用的,因此需要通過這種方式進行處理
  • 添加MultiPlatformPlugin 插件,支持跨平台文件

圖片

自定義配置

查看 buildConf 的其餘配置,這段代碼主要負責初始化和配置一些構建過程中所需的插件、常量和選項,確保構建過程中能夠根據配置進行適當的處理和優化

  • 如果是構建插件(isBuildPlugin 為真),就會處理複製文件的邏輯。如果存在 copy 對象,則將其現有的 patterns 屬性提取出來,如果不存在,則創建一個空數組。隨後,將插件相關的文件夾路徑加入這個數組。最後,使用 Object.assign 將更新後的 patterns 放回到 copy 對象中。這樣,如果之前已經有一些複製規則,現在就添加了插件相關的複製規則
  • 配置插件,將 copy 屬性解析為 copy-webpack-plugin 插件,加入到 webpack 中
  • 設置環境變量
  • 預備構建過程中所需的常量和入口文件的配置。首先,通過 getRuntimeConstants(runtime) 獲取運行時常量,其中可能包含運行時所需的配置或環境常量。接着,通過 mergeOption([processEnvOption(env), defineConstants, runtimeConstants]) 合併來自不同來源的常量選項,包括從環境變量提取的配置、預定義的常量以及之前獲取的運行時常量。最後,通過 getEntry({ sourceDir, entry, isBuildPlugin }) 獲取項目的入口文件配置,其中包括源代碼目錄、入口文件的配置以及構建是否為插件
  • 配置共享的代碼塊(Common Chunks)以用於構建。首先,根據是否構建插件來設置默認的共享代碼塊列表 defaultCommonChunks,其中包括了運行時、第三方庫、Taro 框架和通用代碼塊。接着,通過一系列條件語句,允許用户自定義共享代碼塊的配置。如果 commonChunks 是一個函數,則調用它,將默認的共享代碼塊傳遞給它,允許用户根據需要修改或替換默認的配置。如果 commonChunks 是一個非空數組,則將其用作自定義的共享代碼塊配置。最後,通過調用 getDefinePlugin([constantsReplaceList]) 獲取定義插件的配置,其中包括了前面整理好的常量替換列表。有利於靈活地配置和生成最終的共享代碼塊配置,以便在構建過程中進行優化
  • 判斷是否開啓了主包優化,如果開啓了就配置相應的分割插件

圖片

圖片

圖片

Taro 構建過程中 webpack 配置的核心部分,通過鏈式調用 webpack-chain 庫的方法逐步配置了 webpack 的各項參數,包括模式、入口、出口、目標、解析規則、插件、優化等

  • mode:提供 mode 配置選項,告知 webpack 使用相應模式的內置優化。
  • devtool:控制是否生成 source-map。
  • entry:入口文件,也就是 app.js。
  • output:定義代碼編譯後的生產目錄。
  • target:指定目標(target)環境。
  • resolve:合併 alias 別名選項。
  • module:配置 module,這裏主要是配置一些不同的 loader。
  • plugin:配置 plugin 插件。
  • optimization:手動配置了一些編譯選項優化。

圖片

webpack 代碼編譯

webpack 的編譯過程,支持 watch 模式,並提供了一些回調函數用於處理編譯結果。

圖片

(本文作者:劉健)

圖片

user avatar chongdianqishi 頭像 _raymond 頭像 jianqiangdepaobuxie 頭像 waweb 頭像 nihaojob 頭像 codeoop 頭像 lihaixing 頭像 layouwen 頭像
8 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.