当前位置: 首页>后端>正文

浅析 webpack 打包流程(原理) 三 - 生成 chunk

鎺ヤ笂鏂囷細娴呮瀽 webpack 鎵撳寘娴佺▼(鍘熺悊) 浜?- 閫掑綊鏋勫缓 module

浜斻€佺敓鎴?chunk

鐢熸垚 chunk 闃舵姒傝堪锛氬湪compilation.finish鍥炶皟涓墽琛岀殑 seal 鏂规硶涓紝瑙﹀彂娴烽噺閽╁瓙锛屽氨姝や镜鍏?webpack 鐨勫皝鍖呴樁娈碉紱
1.棣栧厛瀵规墍鏈?import 鍜?export 鍋氭爣璁帮紝浠ュ疄鐜版渶鍚庢瀯寤鸿祫婧愰樁娈电殑 treeshaking锛?br> 2.閬嶅巻鍏ュ彛鏂囦欢涓烘瘡涓叆鍙g敓鎴愬垵濮?chunk 鐨勫悓鏃讹紝涔熷疄渚嬪寲浜?EntryPoint(缁ф壙鑷?ChunkGroup 绫?锛屽苟寤虹珛浜嗗叆鍙?module 鍜?chunk銆乪ntryPoint 涔嬮棿鐨勮仈绯?/strong>锛?br> 3.閫氳繃 buildChunkGraph 鐨勪笁涓樁娈碉紝鐢熸垚寮傛 chunk 鍜?鍖呭惈瀹冪殑chunkGroup锛屽皢鎵€鏈?module銆乧hunk銆乧hunkGroup 閮藉缓绔嬭捣鍏宠仈锛屽舰鎴愪簡 chunkGraph銆?br> 4.鏈€鍚庡皢compilation.modules鎺掑簭锛屽啀瑙﹀彂afterChunks 閽╁瓙锛宑hunk 鐢熸垚缁撴潫銆?br> 杩欓儴鍒嗛兘鏄?webpack 鐨勯澶勭悊 鍜?chunks 榛樿瑙勫垯鐨勫疄鐜帮紝鍚庨潰 chunk 浼樺寲闃舵浼氭毚闇插緢澶氶挬瀛愶紝webpack 浼氭牴鎹垜浠厤缃殑鎻掍欢鏉ヨ繘琛屼紭鍖栥€?/p>

涓婁竴姝ユ垜浠?addEntry 鏂规硶 this._addModuleChain 鐨勪紶鐨勫洖璋冮噷return callback(null, module);锛屽洖鍒?strong>compile鏂规硶鐨?compiler.hooks.make.callAsync()锛屾墽琛屽畠鐨勫洖璋冿細

// /lib/Compiler.js
this.hooks.make.callAsync(compilation, err => {
  if (err) return callback(err);
  compilation.finish(err => {
    if (err) return callback(err);
    compilation.seal(err => {
      if (err) return callback(err);
      this.hooks.afterCompile.callAsync(compilation, err => {
        if (err) return callback(err);
        return callback(null, compilation);
      });
    });
  });
});

姝ゆ椂compilation.modules宸茬粡鏈変簡鎵€鏈夌殑妯″潡锛?code>a銆乧銆乥銆乨銆?br> 鎵цcompilation.finish鏂规硶锛岃Е鍙?strong>compilation.hooks锛歠inishModules锛屾墽琛屾彃浠?FlagDependencyExportsPlugin 娉ㄥ唽鐨勪簨浠讹紝浣滅敤鏄亶鍘嗘墍鏈?module锛屽皢 export 鍑烘潵鐨勫彉閲忎互鏁扮粍鐨勫舰寮忥紝鍗曠嫭瀛樺偍鍒?module.buildMeta.providedExports 鍙橀噺涓嬨€?br> 鐒跺悗閫氳繃閬嶅巻涓烘瘡涓€涓?module 鎵цcompilation.reportDependencyErrorsAndWarnings锛屾敹闆嗙敓鎴愬畠浠椂鏆撮湶鍑烘潵鐨?err 鍜?warning銆?/p>

鏈€鍚庤蛋鍥炶皟鎵цcompilation.seal锛屾彁渚涗簡娴烽噺璁╂垜浠镜鍏?webpack 鏋勫缓娴佺▼鐨?hooks銆?strong>seal 瀛楅潰鎰忔€濇槸灏佸寘锛屼篃灏辨槸寮€濮嬪涓婁竴姝ョ敓鎴愮殑 module 缁撴灉杩涜灏佽銆?/strong>
鍏堟墽琛?(鎴戜滑鍏堢暐杩囨病鏈夋敞鍐屾柟娉曠殑閽╁瓙)this.hooks.seal.call();锛岃Е鍙戞彃浠?WarnCaseSensitiveModulesPlugin锛氬湪 compilation.warnings 娣诲姞 妯″潡鏂囦欢璺緞闇€瑕佸尯鍒嗗ぇ灏忓啓鐨勮鍛娿€?/p>

鍐嶆槸this.hooks.optimizeDependencies.call(this.modules)锛?strong>production 妯″紡浼氳Е鍙戞彃浠讹細

  • SideEffectsFlagPlugin锛氳瘑鍒?package.json 鎴栬€?module.rules 鐨?sideEffects 鏍囪鐨勭函 ES2015 妯″潡锛堢函鍑芥暟)锛屽畨鍏ㄥ湴鍒犻櫎鏈敤鍒扮殑 export 瀵煎嚭锛?/li>
  • FlagDependencyUsagePlugin锛氱紪璇戞椂鏍囪渚濊禆 unused harmony export 锛岀敤浜?Tree shaking

5.1 chunk 鍒濆鍖?/h4>

鍦ㄨЕ鍙?strong>compilation.hooks锛歜eforeChunks鍚庯紝寮€濮嬮亶鍘嗗叆鍙e璞?this._preparedEntrypoints锛屾瘡涓叆鍙?module 閮戒細閫氳繃addChunk鍘诲垱寤轰竴涓┖ chunk(骞舵坊鍔犲埌compilation.chunks)锛?strong>姝ゆ椂涓嶅寘鍚换浣曚笌涔嬬浉鍏宠仈鐨?module銆備箣鍚庡疄渚嬪寲涓€涓?EntryPoint锛屾妸瀹冩坊鍔犲埌compilation.chunkGroups涓€傛帴涓嬫潵璋冪敤 GraphHelpers 妯″潡鎻愪緵鐨勬柟娉曟潵寤虹珛璧?chunkGroup 鍜?chunk 涔嬮棿鐨勮仈绯伙紝浠ュ強 chunk 鍜?鍏ュ彛 module 涔嬮棿鐨勮仈绯?杩欓噷杩樻湭娑夊強鍒板叆鍙d緷璧栫殑 module)锛?/p>

// /lib/Compilation.js
for (const preparedEntrypoint of this._preparedEntrypoints) {
  const module = preparedEntrypoint.module;
  const name = preparedEntrypoint.name;
  // addChunk 鏂规硶杩涜缂撳瓨鍒ゆ柇鍚庢墽琛?new Chunk(name)锛屽苟鍚屾椂娣诲姞 chunk 鍒?compilation.chunks
  const chunk = this.addChunk(name);
  // Entrypoint 绫绘墿灞曚簬 ChunkGroup 绫伙紝鏄?chunks 鐨勯泦鍚堬紝涓昏鐢ㄦ潵浼樺寲 chunk graph
  const entrypoint = new Entrypoint(name); // 姣忎竴涓?entryPoint 灏辨槸涓€涓?chunkGroup
  entrypoint.setRuntimeChunk(chunk); // 璁剧疆 runtimeChunk锛屽氨鏄繍琛屾椂 chunk
  entrypoint.addOrigin(null, name, preparedEntrypoint.request);
  this.namedChunkGroups.set(name, entrypoint);
  this.entrypoints.set(name, entrypoint);
  this.chunkGroups.push(entrypoint); // 鎶?entryPoint 娣诲姞鍒?chunkGroups

  // 寤虹珛 chunkGroup 鍜?chunk 涔嬮棿鐨勮仈绯伙細
  GraphHelpers.connectChunkGroupAndChunk(entrypoint, chunk);
  // 寤虹珛 chunk 鍜?鍏ュ彛 module 涔嬮棿鐨勮仈绯?杩欓噷杩樻湭娑夊強鍒板叆鍙g殑渚濊禆妯″潡)
  GraphHelpers.connectChunkAndModule(chunk, module);

  chunk.entryModule = module;
  chunk.name = name;
  // 鏍规嵁鍚勪釜妯″潡渚濊禆鐨勬繁搴︼紙澶氭渚濊禆鍙栨渶灏忓€硷級璁剧疆 module.depth锛屽叆鍙fā鍧楀垯涓?depth = 0銆?
  this.assignDepth(module);
}

姣斿鎴戜滑鐨?demo锛屽彧閰嶇疆浜嗕竴涓叆鍙o紝閭d箞杩欐椂浼氱敓鎴愪竴涓?chunkGroup(Entrypoint) 鍜屼竴涓?chunk锛岃繖涓?chunk 鐩墠鍙寘鍚叆鍙?module銆?/p>

5.2 鐢熸垚 chunk graph

鎵ц buildChunkGraph(this, /** @type {Entrypoint[]} */ (this.chunkGroups.slice()));
buildChunkGraph 鏂规硶鐢ㄤ簬鐢熸垚骞朵紭鍖?chunk 渚濊禆鍥撅紝寤虹珛璧?module銆乧hunk銆乧hunkGroup 涔嬮棿鐨勫叧绯汇€傚垎涓轰笁闃舵锛?/p>

// /lib/buildChunkGraph.js

// PART ONE
visitModules(compilation, inputChunkGroups, chunkGroupInfoMap, chunkDependencies, blocksWithNestedBlocks, allCreatedChunkGroups);

// PART TWO
connectChunkGroups(blocksWithNestedBlocks, chunkDependencies, chunkGroupInfoMap);

// Cleaup work
cleanupUnconnectedGroups(compilation, allCreatedChunkGroups);
绗竴闃舵 visitModules

鍏堟墽琛岋細visitModules 鐨?const blockInfoMap = extraceBlockInfoMap(compilation);
瀵规湰娆?compliation.modules 杩涜涓€娆¤凯浠i亶鍘嗭紝鎰忓湪瀹屽畬鏁存暣鏀堕泦鎵€鏈夌殑妯″潡(鍚屾銆佸紓姝?鍙婃瘡涓ā鍧楃殑鐩存帴渚濊禆銆?/p>

鍏蜂綋澶勭悊閫昏緫锛?br> 閬嶅巻姣忎釜妯″潡compilation.modules锛屽厛鎶婂叾鍚屾渚濊禆(dependencies)瀛樺叆 modules Set 闆嗭紝鍐嶉亶鍘嗗紓姝ヤ緷璧?blocks)锛屾妸姣忎釜寮傛渚濊禆瀛樺叆妯″潡鐨?blocks 鏁扮粍銆?br> 鐒跺悗杩欎簺寮傛渚濊禆浼氬啀鍔犲叆鍒?code>while寰幆閬嶅巻涓?浣滀负涓€涓ā鍧?锛屼笉浠呬负瀹冨湪blockInfoMap鍗曠嫭寤虹珛璧蜂竴涓?code>ImportDependenciesBlock绫诲瀷鐨勬暟鎹?閲岄潰鍖呭惈杩欎釜寮傛 module 鏈韩)锛屽啀鍘婚亶鍘嗗畠瀛樺偍涓€涓?code>NormalModule绫诲瀷鐨勬暟鎹?鍖呭惈瀹冪殑鍚屾 modules 鍜屽紓姝?blocks)锛屼箣鍚庨亣鍒板紓姝ヤ緷璧栭兘鏄紭鍏堣繖鏍峰鐞嗗紓姝ヤ緷璧栥€?/p>

閬嶅巻缁撴潫馃敋鍚庝細寤虹珛璧峰熀鏈殑 Module Graph锛屽寘鎷墍鏈夌殑NormalModule鍜?code>ImportDependenciesBlock锛屽瓨鍌ㄥ湪涓€涓?strong>blockInfoMap Map 琛ㄥ綋涓?姣忎竴椤圭殑鍊奸兘鏄畠浠殑鐩存帴渚濊禆锛屽悓姝ュ瓨 modules锛屽紓姝ュ瓨 blocks)銆?br> 浠ャ€愭祬鏋?webpack 鎵撳寘娴佺▼(鍘熺悊) - 妗堜緥 demo銆戜负渚嬶紝寰楀埌 blockInfoMap锛?/p>

浅析 webpack 打包流程(原理) 三 - 生成 chunk,第1张
Map缁撴瀯锛屼竴鍏?椤癸紝鏈埅瀹屽叏

鐪嬪叿浣撴暟鎹簲璇ヨ兘澶ц嚧鐞嗚В纰板埌寮傛灏卞幓杩唬閬嶅巻寮傛鐨勫鐞嗛『搴忥細

// blockInfoMap
{
  0: {
    key: NormalModule,  // a锛宒ebugId锛?000锛宒epth锛?
    value: {
      blocks: [ImportDependenciesBlock], // 寮傛 c
      modules: [NormalModule] // b (modules涓簊et缁撴瀯) debugId锛?002锛宒epth锛?
    }
  },
  1: {
    key: ImportDependenciesBlock,
    value: {
      blocks: [],
      modules: [NormalModule] // c锛宒ebugId锛?001锛宒epth锛?
    }
  },
  2: {
    key: NormalModule, // c锛宒ebugId锛?001锛宒epth锛?
    value: {
      blocks: [ImportDependenciesBlock], // 寮傛 b
      modules: [NormalModule] // d锛宒ebugId锛?004锛宒epth锛?
    }
  }
  3: {
    key: ImportDependenciesBlock,
    value: {
      blocks: [],
      modules: [NormalModule] // b锛宒ebugId锛?002锛宒epth锛?
    }
  },
  4: {
    key: NormalModule, // b锛宒ebugId锛?002锛宒epth锛?
    value: {
      blocks: [],
      modules: [NormalModule] // d锛宒ebugId锛?004锛宒epth锛?
    }
  },
  5: {
    key: NormalModule, // d锛宒ebugId锛?004锛宒epth锛?
    value: {
      blocks: [],
      modules: []
    }
  }
}

瀛樺偍瀹屽叆鍙fā鍧?a 鐨勭洿鎺ヤ緷璧?鍚屾鍜屽紓姝?锛屼細浼樺厛鍏堝幓寰幆澶勭悊瀹冪殑寮傛渚濊禆 c锛屾敹闆?c 鐨勭洿鎺ヤ緷璧?鍚屾鍜屽紓姝?锛岀劧鍚庡張浼樺厛閬嶅巻 c 鐨勫紓姝ヤ緷璧?..杩囩▼涓亣鍒扮殑鎵€鏈夊紓姝ヤ緷璧栭兘浼氬缓绔嬩竴涓?code>ImportDependenciesBlock瀵硅薄锛屽€煎唴鍖呭惈涓€椤瑰唴瀹逛负瀹冭嚜韬殑NormalModule銆傚悓鏃跺亣濡傛湁閲嶅鐨勫紓姝ユā鍧楋紝浼氱敓鎴愬椤?code>ImportDependenciesBlock銆傚叾浣欎細鐢熸垚鍑犻」鍜?compliation.modules 涓€涓€瀵瑰簲鐨?code>NormalModule(a銆乥銆乧銆乨)

鎺ョ潃鐢?code>reduceChunkGroupToQueueItem鍑芥暟澶勭悊鐩墠鍙湁涓€涓?EntryPoint 鐨?chunkGroups锛?/p>

// 鐢?reduceChunkGroupToQueueItem 澶勭悊姣忎竴涓?chunkGroup
let queue = inputChunkGroups
  .reduce(reduceChunkGroupToQueueItem, [])
  .reverse();

灏嗗畠杞寲涓轰竴涓?queue 鏁扮粍锛屾瘡椤逛负鍏ュ彛 module銆乧hunk 浠ュ強瀵瑰簲鐨?action 绛変俊鎭粍鎴愮殑瀵硅薄锛?strong>璇﹁涓嬮潰婧愮爜銆?br> 璇存槑涓?strong>action锛氭ā鍧楅渶瑕佽澶勭悊鐨勯樁娈电被鍨嬶紝涓嶅悓绫诲瀷鐨勬ā鍧椾細缁忚繃涓嶅悓鐨勬祦绋嬪鐞嗭紝鍒濆涓?ENTER_MODULE: 1锛屽叏閮ㄧ被鍨嬪涓嬶細

  • ADD_AND_ENTER_MODULE = 0
  • ENTER_MODULE = 1
  • PROCESS_BLOCK = 2
  • LEAVE_MODULE = 3

绱ц窡鐫€璁剧疆chunkGroupInfoMap锛屽畠鏄犲皠浜嗘瘡涓?chunkGroup 鍜屼笌瀹冪浉鍏崇殑淇℃伅瀵硅薄銆?/p>

// /lib/buildChunkGraph.js
for (const chunk of chunkGroup.chunks) {
  const module = chunk.entryModule;
  queue.push({
    action: ENTER_MODULE, // 闇€瑕佽澶勭悊鐨勬ā鍧楃被鍨嬶紝涓嶅悓澶勭悊绫诲瀷鐨勬ā鍧椾細缁忚繃涓嶅悓鐨勬祦绋嬪鐞嗭紝鍒濆涓?ENTER_MODULE: 1
    block: module, // 鍏ュ彛 module
    module, // 鍏ュ彛 module
    chunk, // seal 闃舵涓€寮€濮嬩负姣忎釜鍏ュ彛 module 鍒涘缓鐨?chunk锛屽彧鍖呭惈鍏ュ彛 module
    chunkGroup // entryPoint
  });
}
chunkGroupInfoMap.set(chunkGroup, {
  chunkGroup,
  minAvailableModules: new Set(), // chunkGroup 鍙拷韪殑鏈€灏?module 鏁版嵁闆?
  minAvailableModulesOwned: true,
  availableModulesToBeMerged: [], // 閬嶅巻鐜妭鎵€浣跨敤鐨?module 闆嗗悎
  skippedItems: [],
  resultingAvailableModules: undefined,
  children: undefined
 });

鐒跺悗鍩轰簬module graph锛屽 queue 杩涜浜?2 灞傞亶鍘嗐€傛垜浠彁渚涚殑 demo 鏄崟鍏ュ彛锛屽洜姝?queue 鍙湁涓€椤规暟鎹€?/p>

// /lib/buildChunkGraph.js
// 鍩轰簬 Module graph 鐨勮凯浠i亶鍘嗭紝涓嶇敤閫掑綊鍐欐槸涓轰簡闃叉鍙兘鐨勫爢鏍堟孩鍑?
while (queue.length) { // 澶栧眰閬嶅巻
  logger.time("visiting");
  while (queue.length) { // 鍐呭眰閬嶅巻
    const queueItem = queue.pop(); // 鍒犻櫎骞惰繑鍥?queue 鏁扮粍鐨勬渶鍚庝竴椤?
    // ...
    if (chunkGroup !== queueItem.chunkGroup) {
      // 閲嶇疆鏇存柊 chunkGroup
    }
    switch (queueItem.action) {
      case ADD_AND_ENTER_MODULE: {
        // 濡傛灉 queueItem.module 鍦?minAvailableModules锛屽垯灏嗚 queueItem 瀛樺叆 skippedItems
        if (minAvailableModules.has(module)) {
          Items.push(queueItem);
          break;
        }
        // 寤虹珛 chunk 鍜?module 涔嬮棿鐨勮仈绯伙紝灏嗕緷璧栫殑 module 瀛樺叆璇?chunk 鐨?_modules 灞炴€ч噷锛屽皢 chunk 瀛樺叆 module 鐨?_chunks 閲?
        // 濡傛灉 module 宸茬粡鍦?chunk 涓垯缁撴潫 switch
        if (chunk.addModule(module)) {
          module.addChunk(chunk);
        }
      }
      case ENTER_MODULE: {
        // 璁剧疆 chunkGroup._moduleIndices 鍜?module.index锛岀劧鍚?
        // ...  
        // 缁?queue push 涓€椤?queueItem(action 涓?LEAVE_MODULE)锛屼緵鍚庨潰閬嶅巻鐨勬祦绋嬩腑浣跨敤銆?
        queue.push({
          action: LEAVE_MODULE,
          block,
          module,
          chunk,
          chunkGroup
        });
      }
      case PROCESS_BLOCK: {
        // 1. 浠?blockInfoMap 涓煡璇㈠埌褰撳墠 queueItem 鐨勬ā鍧楁暟鎹?
        const blockInfo = blockInfoMap.get(block);

        // 2. 閬嶅巻褰撳墠妯″潡鐨勫悓姝ヤ緷璧?娌℃湁鍒欏瓨鍏?queue锛屽叾涓?queueItem.action 閮借涓?ADD_AND_ENTER_MODULE
        for (const refModule of blockInfo.modules) {
          if (chunk.containsModule(refModule)) {
            // 璺宠繃宸茬粡瀛樺湪浜?chunk 鐨勫悓姝ヤ緷璧?
            continue;
          }
          // 濡傛灉宸茬粡瀛樺湪浜庣埗 chunk (chunkGroup 鍙拷韪殑鏈€灏?module 鏁版嵁闆?-- minAvailableModules)
          // 鍒欏皢璇?queueItem push 鍒?skipBuffer(action 涓?ADD_AND_ENTER_MODULE)锛屽苟璺宠繃璇ヤ緷璧栫殑閬嶅巻

          // 鍊掑簭灏?skipBuffer 娣诲姞 skippedItems锛宷ueueBuffer 娣诲姞鍒?queue

          // enqueue the add and enter to enter in the correct order
          // this is relevant with circular dependencies
          // 浠ヤ笂閮戒笉绗﹀悎鍒欏皢 queueItem push 鍒?queueBuffer(action 涓?ADD_AND_ENTER_MODULE)
          queueBuffer.push({
            action: ADD_AND_ENTER_MODULE,
            block: refModule,
            module: refModule,
            chunk,
            chunkGroup
          });
        }
        
        // 3. 鐢?iteratorBlock 鏂规硶杩唬閬嶅巻妯″潡鎵€鏈夊紓姝ヤ緷璧?blocks
        for (const block of blockInfo.blocks) iteratorBlock(block);

        if (blockInfo.blocks.length > 0 && module !== block) {
          blocksWithNestedBlocks.add(block);
        }
      }
      case LEAVE_MODULE: {
        // 璁剧疆 chunkGroup._moduleIndices2 鍜?module.index2
      }
    }
  }
  // 涓婃枃 while (queue.length) 浠庡叆鍙?module 寮€濮嬶紝寰幆灏嗘墍鏈夊悓姝ヤ緷璧栭兘鍔犲叆鍒板悓涓€涓?chunk 閲岋紝灏嗗叆鍙?module 鍙婂畠鐨勫悓姝ヤ緷璧栭噷鐨勫紓姝ヤ緷璧栭兘鍚勮嚜鏂板缓浜哻hunkGroup 鍜?chunk锛屽苟灏嗗紓姝ユā鍧楀瓨鍏?queueDelayed锛屽紓姝ヤ緷璧栦腑鐨勫紓姝ヤ緷璧栬繕鏈鐞嗐€?

  while (queueConnect.size > 0) {
    // 璁$畻鍙敤妯″潡
    // 1. 鍦?chunkGroupInfoMap 涓缃墠涓€涓?chunkGroup 鐨?info 瀵硅薄鐨?resultingAvailableModules銆乧hildren
    // 2. 鍦?chunkGroupInfoMap 涓垵濮嬪寲鏂扮殑 chunkGroup 涓庝粬鐩稿叧鐨?info 瀵硅薄鐨勬槧灏勫苟璁剧疆浜?availableModulesToBeMerged
    if (outdatedChunkGroupInfo.size > 0) {
      // 鍚堝苟鍙敤妯″潡
      // 1. 鑾峰彇/璁剧疆鏂扮殑 chunkGroup info 瀵硅薄鐨?minAvailableModules
      // 2. 灏嗘柊鐨?chunkGroup info 瀵硅薄鐨?skippedItems push 鍒?queue
      // 3. 濡傛灉鏂扮殑 chunkGroup info 瀵硅薄鐨?children 涓嶄负绌猴紝鍒欐洿鏂?queueConnect 閫掑綊寰幆
    }
  }
  // 褰?queue 闃熷垪鐨勬墍鏈夐」閮借澶勭悊鍚庯紝鎵ц queueDelayed
  // 鎶?queueDelayed 鏀惧叆 queue 璧?while 鐨勫灞傚惊鐜紝鐩殑鏄湪鎵€鏈夊悓姝ヤ緷璧?while 澶勭悊瀹屼箣鍚庯紝鎵嶅鐞嗗紓姝ユā鍧?
  // 濡傛灉寮傛妯″潡閲岃繕鏈夊紓姝ヤ緷璧栵紝灏嗘斁鍒颁竴涓嬫鐨?queueDelayed 璧?while 鐨勫灞傚惊鐜?
  if (queue.length === 0) {
    const tempQueue = queue; // ImportDependenciesBlock
    queue = queueDelayed.reverse();
    queueDelayed = tempQueue;
  }
}

while 寰幆鍙鏉′欢涓?true 灏变細涓€鐩村惊鐜唬鐮佸潡锛屽彧鏈夊綋鏉′欢涓嶆垚绔嬫垨鑰呭唴閮ㄦ湁if(condition){ return x;}銆?code>if(condition){ break; }鎵嶈兘璺冲嚭寰幆銆? while+push 闃查€掑綊鐖嗘爤锛屽悗搴忔繁搴︿紭鍏?

杩涘叆鍐呭眰閬嶅巻锛屽尮閰嶅埌case ENTER_MODULE锛屼細缁?queue push 涓€涓?action 涓?code>LEAVE_MODULE鐨?queueItem 椤逛緵鍚庨潰閬嶅巻娴佺▼涓娇鐢ㄣ€傜劧鍚庤繘鍏ュ埌PROCESS_BLOCK闃舵锛?/p>

浠?code>blockInfoMap涓煡璇㈠埌褰撳墠 queueItem 鐨勬ā鍧楁暟鎹紝鍙湁褰撳墠妯″潡鐨勭洿鎺ヤ緷璧?/strong>锛屽湪鏈緥灏辨槸锛?/p>

浅析 webpack 打包流程(原理) 三 - 生成 chunk,第2张
blockInfo

鎺ヤ笅鏉ラ亶鍘嗘ā鍧楃殑鎵€鏈夊崟灞傚悓姝ヤ緷璧?modules锛岃烦杩囧凡缁忓瓨鍦ㄤ簬 chunk 鐨勫悓姝ヤ緷璧栵紱濡傛灉鍚屾渚濊禆宸插湪 minAvailableModules(chunkGroup 鍙拷韪殑鏈€灏?module 鏁版嵁闆?锛屽垯灏?queueItem push 鍒?skipBuffer锛岀劧鍚庤烦鍑鸿渚濊禆鐨勯亶鍘嗭紱浠ヤ笂閮芥病鏈夊垯灏?queueItem 瀛樺叆缂撳啿鍖?queueBuffer锛宎ction 閮借涓?ADD_AND_ENTER_MODULE(鍗充笅娆¢亶鍘嗚繖涓?queueItem 鏃讹紝浼氬厛杩涘叆鍒?ADD_AND_ENTER_MODULE)銆傚悓姝?modules 閬嶅巻瀹岋紝灏嗗緱鍒扮殑 queueBuffer 鍙嶅簭娣诲姞鍒?queue銆備篃灏辨槸鍚庨潰鐨勫唴灞傞亶鍘嗕腑锛屼細浼樺厛澶勭悊鍚屾渚濊禆宓屽鐨勫悓姝ユā鍧楋紝(涓嶉噸澶嶅湴)娣诲姞瀹屽啀鍘诲鐞嗗悓绾у悓姝ヤ緷璧?/strong>銆?/p>

鎺ヤ笅鏉ヨ皟鐢?strong>iteratorBlock鏉ヨ凯浠i亶鍘嗗綋鍓嶆ā鍧楃殑鍗曞眰寮傛渚濊禆 blocks锛屾柟娉曞唴閮ㄤ富瑕佸疄鐜扮殑鏄細

  1. 璋冪敤addChunkInGroup涓鸿繖涓紓姝?block 鍒涘缓涓€涓?chunk 鍜?chunkGroup锛屽悓鏃跺缓绔嬭繖涓よ€呬箣闂寸殑鑱旂郴銆傛鏃惰繖涓?chunk 鏄┖鐨勶紝杩樻病鏈夋坊鍔犱换浣曞畠鐨勪緷璧栵紱
  2. 鎶?chunkGroup 娣诲姞鍒?code>compilation.chunkGroups(Array) 鍜?code>compilation.namedChunkGroups(Map)锛宑hunkGroupCounters(璁℃暟 Map)銆乥lockChunkGroups(鏄犲皠渚濊禆鍜?ChunkGroup 鍏崇郴鐨?Map)銆?code>allCreatedChunkGroups(鏀堕泦琚垱寤虹殑 ChunkGroup Set)銆?/li>
  3. 鎶婅繖椤?block 鍜?block 鎵€灞炵殑 chunkGroup 浠ュ璞$殑褰㈠紡 push 鍒?chunkDependencies Map 琛ㄤ腑 鉃★笍 褰撳墠 module 鎵€灞?chunkGroup (Map 鐨?key)涓嬶紝姣忎竴閮芥槸{ block: ImportDependenciesBlock, chunkGroup: chunkGroup }鐨勫舰寮忋€傚缓绔嬭捣 block 鍜屽畠鎵€灞?chunkGroup 鍜?鐖?chunkGroup 涔嬮棿鐨勪緷璧栧叧绯汇€俢hunkDependencies 琛ㄤ富瑕佺敤浜庡悗闈紭鍖?chunk graph锛?/li>
  4. 鏇存柊 queueConnect锛屽缓绔嬬埗 chunkGroup 涓庢柊 chunkGroup 鐨勬槧灏勶紱
  5. 鍚?queueDelayed 涓?push 涓€涓?{ action:PROCESS_BLOCK, module: 褰撳墠 block 鎵€灞?module, block: 褰撳墠寮傛 block, chunk: 鏂?chunkGroup 涓殑绗竴涓?chunk, chunkGroup: 鏂?chunkGroup } 锛岃椤逛富瑕佺敤浜?queue 鐨勫灞傞亶鍘嗐€?/li>

iteratorBlock澶勭悊瀹屽綋鍓嶆ā鍧楁墍鏈夌洿鎺ュ紓姝ヤ緷璧?(block) 鍚庯紝缁撴潫鏈疆鍐呭眰閬嶅巻銆?br> 鍓嶉潰涓?queue push 浜嗕袱椤?queueItem锛屼竴涓槸鍏ュ彛妯″潡 a(action 涓?LEAVE_MODULE)锛屼竴涓槸鍚屾妯″潡 b(action 涓?ADD_AND_ENTER_MODULE)銆傚洜姝ょ户缁亶鍘?queue 鏁扮粍锛屽弽搴忓厛閬嶅巻 b锛屽尮閰嶅埌ADD_AND_ENTER_MODULE锛屾妸 b 娣诲姞鍒?鍏ュ彛 chunk (_modules灞炴€?涓紝涔熸妸鍏ュ彛 chunk 瀛樺叆 b 妯″潡鐨?code>_chunks灞炴€ч噷銆傜劧鍚庤繘鍏?code>ENTRY_MODULE闃舵锛屾爣璁颁负LEAVE_MODULE锛屾坊鍔犲埌 queue銆?br> 鐒跺悗杩涘叆PROCESS_BLOCK澶勭悊 b 鐨勫悓姝ヤ緷璧栧拰寮傛渚濊禆(杩囩▼濡備笂鏂?锛?/p>

馃挭灏藉姏璇村緱閫氫織浜涚殑鎬荤粨锛?br> 灏嗘ā鍧?strong>鐩存帴鍚屾渚濊禆鏍囪涓?code>ADD_AND_ENTER_MODULE娣诲姞鍒?queue 鐢ㄤ簬鎺ヤ笅鏉ョ殑閬嶅巻锛宲ush 鏃跺叾浣欏睘鎬?block 鍜?module 鏄畠鏈韩锛?chunk銆乧hunkGroup 涓嶅彉锛?br> 鐩存帴寮傛渚濊禆鍒欐爣璁颁负PROCESS_BLOCK娣诲姞鍒扮敤浜庡灞傞亶鍘嗙殑 queueDelayed锛宲ush 鏃朵紶鐨勬槸鏂扮殑 chunk 鍜?chunkGroup锛宐lock 鏄畠鏈韩锛宮odule 鏄畠鐨勭埗妯″潡銆傚悓鏃朵細涓烘寮傛渚濊禆鏂板缓涓€涓寘鍚竴涓┖ chunk 鐨?chunkGroup銆?br> 澶栧眰 while 鐨勬墽琛屾椂鏈烘槸绛夋墍鏈夊叆鍙fā鍧楃殑鍚屾渚濊禆(鍖呮嫭闂存帴)閮藉鐞嗗畬鍚庛€?br> 寤虹珛鍒濇鐨?chunk graph 椤哄簭鍙互绠€鍗曞湴鎹嬫垚锛?br> 1.棣栧厛鍏ュ彛鍜屾墍鏈?鐩存帴/闂存帴)鍚屾渚濊禆褰㈡垚涓€涓?chunkGroup 缁?娣诲姞妯″潡鐨勯『搴忎负锛氬厛鏄悓姝ヤ緷璧栧祵濂楃殑鍚屾渚濊禆閮藉鐞嗗畬锛屽啀鍘婚亶鍘嗗钩绾х殑鍚屾渚濊禆)锛?br> 2.鐒跺悗鎸夋瘡涓紓姝ヤ緷璧栫殑鐖舵ā鍧楄澶勭悊鐨勯『搴?/strong>锛屼负瀹冧滑鍚勮嚜寤虹珛涓€涓?chunk 鍜?chunkGroup銆傚紓姝?chunk 涓彧浼氬寘鍚叆鍙?chunk 涓笉瀛樺湪鐨勫悓姝ヤ緷璧栥€傜浉鍚岀殑寮傛妯″潡浼氶噸澶嶅垱寤?chunk銆?/p>

鐒跺悗璧?code>while (queueConnect.size > 0)寰幆锛屾洿鏂颁簡chunkGroupInfoMap涓埗 chunkGroup 鐨?info 瀵硅薄锛屽垵濮嬪寲鏂扮殑 chunkGroup info 瀵硅薄锛屽苟鑾峰彇浜嗘渶灏忓彲鐢ㄦā鍧椼€?/p>

鐒跺悗绛夊唴灞傚惊鐜妸 queue 鏁扮粍 (鍐呭眰鍙妯″潡鎵€鏈夊悓姝ヤ緷璧?/strong>) 涓€涓釜鍙嶅簭澶勭悊瀹?鏁伴噺涓?)锛屽氨鎶?queueDelayed 璧嬬粰 queue 锛岃蛋澶栭儴while(queue.length)寰幆澶勭悊寮傛渚濊禆 (鐪熸澶勭悊寮傛妯″潡)銆傝繖鏃惰繖浜?queueItem 鐨?action 閮戒负PROCESS_BLOCK锛宐lock 閮戒负 ImportDependenciesBlock 渚濊禆銆傛洿鏂?chunkGroup 鍚庯紝 switch 鐩存帴璧?PROCESS_BLOCK 鑾峰緱寮傛椤瑰搴旂殑鐪熸妯″潡锛屽拰涔嬪墠鍚屾妯″潡涓€鏍峰鐞?鏈夊紓姝ヤ緷璧栧氨鏂板缓 chunk 鍜?chunkGroup [鏃犺涔嬪墠鏃犱负鍚屾牱鐨勫紓姝ュ潡鍒涘缓杩?chunkGroup锛屽潎浼氶噸澶嶅垱寤篯锛屽苟鏀惧叆 queueDelayed)锛屽鐞嗘暟鎹兘灏嗗瓨鍌ㄥ湪鏂扮殑 chunkGroup 瀵硅薄涓娿€傛渶缁堝緱鍒颁竴涓?Map 缁撴瀯鐨?code>chunkGroupInfoMap銆備互 demo 涓轰緥锛?/p>

浅析 webpack 打包流程(原理) 三 - 生成 chunk,第3张

children 涓烘瘡椤圭殑瀛?chunkGroup锛?strong>resultingAvailableModules 涓烘湰 chunkGroup 鍙敤鐨勬ā鍧?/p>

// chunkGroupInfoMap Map 瀵硅薄
[
  0: {
    key: Entrypoint, // groupDebugId: 5000
    value: {
      availableModulesToBeMerged: Array(0) // 閬嶅巻鐜妭鎵€浣跨敤鐨?module 闆嗗悎
      children: Set(1) {} // 瀛?chunkGroup锛実roupDebugId: 5001
      chunkGroup: Entrypoint
      minAvailableModules: Set(0) // chunkGroup 鍙拷韪殑鏈€灏?module 鏁版嵁闆?
      minAvailableModulesOwned: true
      resultingAvailableModules: Set(3) // 杩欎釜 chunkGroup 鐨勫彲鐢ㄦā鍧?a b d
      skippedItems: Array(0)
    }
  },
  1: {
    key: ChunkGroup, // groupDebugId: 5001
    value: {
      availableModulesToBeMerged: Array(0)
      children: Set(1) {} // 瀛?chunkGroup锛実roupDebugId: 5002
      chunkGroup: Entrypoint
      minAvailableModules: Set(3) // a b d
      minAvailableModulesOwned: true
      resultingAvailableModules: Set(4) // 杩欎釜 chunkGroup 鐨勫彲鐢ㄦā鍧?a b d c
      skippedItems: Array(1) // d
    }
  }
  2: {
    key: ChunkGroup, // groupDebugId: 5002
    value: {
      availableModulesToBeMerged: Array(0)
      children: undefined
      chunkGroup: Entrypoint
      minAvailableModules: Set(4)  // a b d c
      minAvailableModulesOwned: true
      resultingAvailableModules: undefined
      skippedItems: Array(1) // b
    }
  }
]

姝ゆ椂鐨?code>compilation.chunkGroups鏈変笁涓?chunkGroup锛?br> 鍖呭惈涓€涓?code>_modules: { a, b, d } chunk 鐨?EntryPoint锛涘寘鍚竴涓?code>_modules: { c } chunk 鐨?chunkGroup(鍏ュ彛寮傛寮曞叆鐨?c 鍒涘缓)锛涘寘鍚竴涓┖ chunk 鐨?chunkGroup(c 寮曞叆 b 鏃跺垱寤?銆?br> 鍗冲叆鍙e拰瀹冩墍鏈夊悓姝ヤ緷璧栫粍鎴愪竴涓?chunk(鍖呭惈鍦?EntryPoint 鍐?锛屾瘡涓紓姝ヤ緷璧栨垚涓轰竴涓?chunk(鍚勮嚜鍦ㄤ竴涓?chunkGroup 鍐?銆傞亣鍒扮浉鍚岀殑寮傛妯″潡浼氶噸澶嶅垱寤?chunk 鍜?chunkGroup锛屽鐞?chunk 鍚屾妯″潡鏃堕亣鍒板凡瀛樺湪浜庡叆鍙?chunk 鐨勬ā鍧楀皢璺宠繃锛屼笉鍐嶅瓨鍏?code>chunk._modules銆?/p>

浅析 webpack 打包流程(原理) 三 - 生成 chunk,第4张
鍒濇鐨?chunk graph
绗簩闃舵 connectChunkGroups

閬嶅巻 chunkDependencies锛屾牴鎹?ImportDependenciesBlock(block) 寤虹珛浜嗕笉鍚?chunkGroup 涔嬮棿鐨勭埗瀛愬叧绯汇€?br> chunkDependencies 鍙繚瀛樻湁瀛?chunkGroup 鐨?chunkGroup(涔熷氨鏄?EntryPoint 鍜岋紝鏈夊紓姝ヤ緷璧栫殑寮傛妯″潡鍒涘缓鐨?chunkGroup 鎵嶄細琚瓨鍒伴噷闈? 锛屽睘鎬ф槸 chunkGroup锛?鍊兼槸 chunkGroup 鐨勬墍鏈?瀛?chunkGroup 鍜?寮傛渚濊禆缁勬垚鐨勫璞?鐨勬暟缁勶細

// chunkDependencies Map 瀵硅薄
[
  0: {
    key: Entrypoint, // groupDebugId: 5000
    value: [
      { block: ImportDependenciesBlock, chunkGroup: ChunkGroup }, // groupDebugId: 5001
      // { block: ImportDependenciesBlock, chunkGroup: ChunkGroup }, // groupDebugId: 5003
      // 瀹為檯椤圭洰涓€鑸細瀛樺湪澶氶」
    ]
  },
  1: {
    key: ChunkGroup, // groupDebugId: 5001
    value: [
      { block: ImportDependenciesBlock, chunkGroup: ChunkGroup } // groupDebugId: 5002
    ]
  },
]

鏂囧瓧寰堢粫锛屽叧浜?chunkDependencies 鐢ㄤ竴涓ā鍧楁洿澶氱殑鍥惧氨瀹规槗鐞嗚В寰楀浜嗭細

浅析 webpack 打包流程(原理) 三 - 生成 chunk,第5张
澶氭ā鍧?demo2

杩欎釜渚嬪瓙鐨?chunkDependencies 鏄繖鏍风殑锛?/p>

// 绠€鍗曞湴鐢? groupDebugId 鎸囦唬瀛?chunkgroup 鍜?瀛?chunkgroup 鐨?chunk
{
  { key: EntryPoint 5000, value: [5001, 5002, 5003, 5004] },
  { key: ChunkGroup 5001, value: [5005, 5006] },
  { key: ChunkGroup 5002, value: [5007] }
}

閬嶅巻鏃?strong>瀛?chunkgroup 鐨?code>chunks[]._modules濡傛灉鏈夌埗 chunkGroup 鐨勫彲鐢ㄦā鍧?code>resultingAvailableModules涓笉鍖呭惈鐨勬柊妯″潡锛屽垯鍒嗗埆寤虹珛寮傛渚濊禆涓庡搴?chunkGroup(浜掔浉娣诲姞鍒板郊姝ょ殑chunkGroup鍜?code>_blocks)銆佺埗 chunkGroup 鍜屽瓙 chunkGroup 鐨勭埗瀛愬叧绯?浜掔浉娣诲姞鍒板郊姝ょ殑_children鍜?code>_parents)锛?br> (resultingAvailableModules閫氳繃鏌ヨchunkGroupInfoMap.get(鐖禼hunkGroup)鑾峰彇)

濡備笂闈?demo2锛孋hunkGroup 5001 鐨勫彲鐢ㄦā鍧楁槸a b d e c j锛屽畠鐨勫瓙 ChunkGroup 5005 鏄敱 b 鍒涘缓鐨?涓斿洜涓轰笉浼氶噸澶嶅垱寤哄叆鍙?chunk 涓瓨鍦ㄧ殑鍚屾妯″潡锛?5005 鐨?chunk 骞朵笉鍖呭惈浠讳綍妯″潡)锛屾病鏈夋柊妯″潡锛屾晠鑰屾病鏈夊缓绔嬭捣鍏崇郴銆傝€屽瓙ChunkGroup 5006 鏈夋柊妯″潡 k锛屽氨寤虹珛璧蜂簡涓婅堪鍏崇郴銆?/p>

// /lib/buildChunkGraph.js
// ImportDependenciesBlock 涓?chunkGroup 寤虹珛鑱旂郴锛屼簰鐩告坊鍔犲埌褰兼鐨?chunkGroup 鍜?_blocks
GraphHelpers.connectDependenciesBlockAndChunkGroup(
  depBlock,
  depChunkGroup
); 

// chunkGroup 涔嬮棿寤虹珛鑱旂郴锛氫簰鐩告坊鍔犲埌褰兼鐨?_children 鍜?_parents
GraphHelpers.connectChunkGroupParentAndChild(
  chunkGroup,
  depChunkGroup
);
绗笁闃舵 cleanupUnconnectedGroups

娓呯悊鏃犵敤 chunk 骞舵竻鐞嗙浉鍏崇殑鑱旂郴銆?br> 閫氳繃閬嶅巻allCreatedChunkGroups锛屽鏋滈亣鍒板湪绗簩闃舵娌℃湁寤虹珛璧疯仈绯荤殑 chunkGroup(濡備笂闈?demo2 chunkGroup 5005)锛岄偅涔堝氨灏嗚繖浜?chunkGroup 涓殑鎵€鏈?chunk 浠?chunk graph 渚濊禆鍥惧綋涓墧闄ゆ帀 ( demo2 涓殑寮傛 b chunk 姝ゆ椂琚垹闄?)銆?br> allCreatedChunkGroups鍗冲紓姝ユā鍧楄鍒涘缓鐨?chunkGroup锛屼緷娆″垽鏂?chunkGroup 鏈夋棤鐖?chunkGroup(_parents)锛屾病鏈夊垯鎵ц锛?/p>

// /lib/buildChunkGraph.js
for (const chunk of chunkGroup.chunks) {
  const idx = compilation.chunks.indexOf(chunk);
  if (idx >= 0) compilation.chunks.splice(idx, 1); // 鍒犻櫎 chunk
  chunk.remove('unconnected');
}
chunkGroup.remove('unconnected');

鍚屾椂瑙i櫎 module銆乧hunk銆乧hunkGroup 涓夎€呬箣闂寸殑鑱旂郴銆?/p>

鏈€缁堟瘡涓?module 涓庢瘡涓?chunk銆佹瘡涓?chunkGroup 涔嬮棿閮藉缓绔嬩簡鑱旂郴锛屼紭鍖栧舰鎴愪簡 chunk graph銆?/p>

浅析 webpack 打包流程(原理) 三 - 生成 chunk,第6张
姝ゆ椂鐨?鐨?chunk graph

buildChunkGraph 涓夐樁娈垫€荤粨锛?br> 1.visitModules锛氫负鍏ュ彛妯″潡鍜屽畠鎵€鏈?鐩存帴/闂存帴)鍚屾渚濊禆褰㈡垚涓€涓?EntryPoint(缁ф壙鑷?ChunkGroup)锛屼负鎵€鏈夊紓姝ユā鍧楀拰瀹冪殑鍚屾渚濊禆鐢熸垚涓€涓?chunk 鍜?chunkGroup(浼氶噸澶?銆傚 chunk 鐨勫悓姝ユā鍧楀凡瀛樺湪浜庡叆鍙?chunk锛屽垯涓嶄細鍐嶅瓨鍏ュ畠鐨?code>_modules銆傛闃舵鍒濆鐢熸垚浜?chunk graph(chunk 渚濊禆鍥?銆?br> 2.connectChunkGroups锛氭鏌ュ叆鍙?chunk 鍜?鏈夊紓姝ヤ緷璧栫殑寮傛 chunk, 濡傛灉瀹冧滑鐨勫瓙 chunk 鏈夊畠浠湭鍖呭惈鐨勬柊妯″潡锛屽氨寤虹珛瀹冧滑鍚勮嚜鎵€灞?chunkGroup 鐨?鐖跺瓙鍏崇郴銆?br> 3.cleanupUnconnectedGroups锛氭壘鍒版病鏈夌埗 chunkgroup 鐨?chunkgroup锛屽垹闄ゅ畠閲岄潰鐨?chunk锛屽苟瑙i櫎涓庣浉鍏?module銆乧hunk銆乧hunkGroup 鐨勫叧绯汇€?br> 2銆? 闃舵瀵?chunk graph 杩涜浜嗕紭鍖栵紝鍘婚櫎浜?鐢卞凡瀛樺湪浜庡叆鍙?chunk 涓殑 妯″潡鍒涘缓鐨勫紓姝?chunk銆?/p>

鍥炲埌 Compilation.js锛宑ompilation 鐨?seal 鏂规硶缁х画鎵ц锛屽厛灏?compilation.modules 鎸?index 灞炴€уぇ灏忔帓搴忥紝鐒跺悗鎵ц锛?strong>this.hooks.afterChunks.call(this.chunks)銆傝Е鍙戞彃浠?WebAssemblyModulesPlugin锛氳缃笌 webassembly 鐩稿叧鐨勬姤閿欎俊鎭紝鍒版 chunk 鐢熸垚缁撴潫銆?/p>

5.3 module銆乧hunk銆乧hunkGroup 瀛樺偍瀛楁鐩稿叧

module

module 鍗虫瘡涓€涓祫婧愭枃浠剁殑妯″潡瀵瑰簲锛屽 js/css/鍥剧墖 绛夈€傜敱 NormalModule 瀹炰緥鍖栬€屾潵锛屽瓨浜?strong>compilation.modules鏁扮粍銆?/p>

  • module.blocks锛歮odule 鐨勫紓姝ヤ緷璧?/li>
  • module.dependencies锛歮odule 鐨勫悓姝ヤ緷璧?/li>
  • module._chunks锛歮odule 鎵€灞?chunk 鍒楄〃
chunk

姣忎竴涓緭鍑烘枃浠剁殑瀵瑰簲锛屾瘮濡傚叆鍙f枃浠躲€佸紓姝ュ姞杞芥枃浠躲€佷紭鍖栧垏鍓插悗鐨勬枃浠剁瓑绛夛紝瀛樹簬compilation.chunks鏁扮粍銆?/p>

  • chunk._groups锛歝hunk 鎵€灞炵殑 chunkGroup 鍒楄〃
  • chunk._modules锛氱敱鍝簺 module 缁勬垚
chunkGroup

榛樿鎯呭喌涓嬶紝姣忎釜 chunkGroup 閮藉彧鍖呭惈涓€涓?chunk锛氫富 chunkGroup (EntryPoint) 鍖呭惈鍏ュ彛 chunk锛屽叾浣?chunkGroup 鍚勫寘鍚竴涓紓姝ユā鍧?chunk銆傚瓨浜?strong>compilation.chunkGroups鏁扮粍銆?br> 褰撻厤缃簡optimization.splitChunks锛孲plitChunksPlugin 鎻掍欢灏嗗叆鍙?chunk 鎷嗗垎涓哄涓悓姝?chunk锛岄偅涔堜富 ChunkGroup (EntryPoint) 灏变細鏈夊涓?chunk 浜嗐€傚彟澶栵紝濡?runtime 琚崟鐙娊鎴愪竴涓枃浠讹紝閭d箞 EntryPoint 灏变細澶氬嚭涓€涓?runtime chunk銆?/p>

  • chunkGroup.chunks锛氱敱鍝簺 chunk 缁勬垚
  • chunkGroup._blocks锛氬紓姝ヤ緷璧?ImportDependenciesBlock
  • chunkGroup._children锛氬瓙 chunkGroup
  • chunkGroup._parent锛氱埗 chunkGroup

涓嬫枃锛氭祬鏋?webpack 鎵撳寘娴佺▼(鍘熺悊) 鍥?- chunk 浼樺寲

webpack 鎵撳寘娴佺▼绯诲垪(鏈畬)锛?br> 娴呮瀽 webpack 鎵撳寘娴佺▼(鍘熺悊) - 妗堜緥 demo
娴呮瀽 webpack 鎵撳寘娴佺▼(鍘熺悊) 涓€ - 鍑嗗宸ヤ綔
娴呮瀽 webpack 鎵撳寘娴佺▼(鍘熺悊) 浜?- 閫掑綊鏋勫缓 module
娴呮瀽 webpack 鎵撳寘娴佺▼(鍘熺悊) 涓?- 鐢熸垚 chunk
娴呮瀽 webpack 鎵撳寘娴佺▼(鍘熺悊) 鍥?- chunk 浼樺寲
娴呮瀽 webpack 鎵撳寘娴佺▼(鍘熺悊) 浜?- 鏋勫缓璧勬簮
娴呮瀽 webpack 鎵撳寘娴佺▼(鍘熺悊) 鍏?- 鐢熸垚鏂囦欢

鍙傝€冮福璋細
webpack鎵撳寘鍘熺悊 鐪嬪畬杩欑瘒浣犲氨鎳備簡 !
webpack 閫忚鈥斺€旀彁楂樺伐绋嬪寲锛堝師鐞嗙瘒锛?br> webpack 閫忚鈥斺€旀彁楂樺伐绋嬪寲锛堝疄璺电瘒锛?br> webpack 4 婧愮爜涓绘祦绋嬪垎鏋?br> [涓囧瓧鎬荤粨] 涓€鏂囧悆閫?Webpack 鏍稿績鍘熺悊
鏈夌偣闅剧殑 Webpack 鐭ヨ瘑鐐癸細Dependency Graph 娣卞害瑙f瀽
webpack绯诲垪涔嬪叚chunk鍥剧敓鎴?/p>


https://www.xamrdz.com/backend/3h41939155.html

相关文章: