1. 程式人生 > 其它 >webpack 原始碼淺析tree sharking的原理

webpack 原始碼淺析tree sharking的原理

之所以寫這篇文章,是因為前幾天被一個標題黨給騙了,開頭寫的多高階說是大廠面試官問起tree sharking的原理,面試者回答不上,然後就解答了這個原理,還引起我的好奇心,就讀了下去,最後結論簡單來說1.要用es6 2.webpack是通過ast解析來完成的,讀完之後我覺得自己被騙了,寫的什麼東西啊。
然後我自己去讀了下程式碼,算是簡單瞭解了webpack的加入unused harmony export註釋的原理,然後徹底刪除是壓縮外掛來做的。

FlagDependencyUsagePlugin

這個外掛就是用來檢測module有哪些export使用了。以下程式碼都是精簡過的


// 從入口檔案開始一級一級去解析每個module,preparedEntrypoint.module是入口module
for (const preparedEntrypoint of compilation._preparedEntrypoints) {
    if (preparedEntrypoint.module) {
        processModule(preparedEntrypoint.module, true);
    }
}
// 在這裡把每個module有哪些依賴給遍歷一下,篩選出import型別的依賴
for (const dep of depBlock.dependencies) {
    // 這個module是使用import的module
    const reference = compilation.getDependencyReference(module, dep);
    if (!reference) return;
    const referenceModule = reference.module;
    const importedNames = reference.importedNames;
    const oldUsed = referenceModule.used;
    const oldUsedExports = referenceModule.usedExports;
    if (
        !oldUsed ||
        (importedNames &&
            (!oldUsedExports || !isSubset(oldUsedExports, importedNames)))
    ) {
        // 如果找到了那麼給這個引用module打上使用標籤,importedNames就是引用的名字 比如import { mul }  from './ddd';
        // 那importedNames就是 mul
        processModule(referenceModule, importedNames);
    }
}
// 最後一步就是 給被使用的module加一個識別符號,然後這個外掛的任務就完成了
module.usedExports = importedNames

// 在轉換為真實檔案的時候,獲取module的所有HarmonyExportSpecifierDependency的依賴,簡單說就是export依賴
// 比如說export了2個函式mul 和 feq,那麼會有2個export依賴
// dep.name 就是mul這個函式名,然後判斷在這個module的usedExports陣列是否有這個名字就決定是否加unused harmony export註釋
dep.originModule.isUsed(dep.name)

自己去讀了下程式碼,至少比有一些博人眼球的文章要深入一點