webpack chunk 讀出來是空的該怎麼辦

總之最近有需求所以用上了 webpack 的 code splitting,就在用爽爽以為世界為我所有的時候,碰到神秘的現象。

環境

為了稍微釐清一下關係,以下的主角分別稱為 A & B

A - 嵌入式的工具,設計為可以嵌入各種網站使用(使用 webpack code splitting) B - 新的 project(使用 webpack),有嵌入 A 做進階使用

這天 B 需要嘗試加入 code splitting,目前只需要分成兩個 chunk,一個 chunk 代表一個 route。

簡單的 code splitting 示意寫法如下:

import dyna from '_util/createDynamicComponent';

const Main = dyna((resolve) => {
  require.ensure([], require => {
    resolve(require('_components/Main').default);
  });
});

照常理來說,webpack 會確保 require.ensure 的 callback 裡面需要執行的東西在讀進來之後才執行;然而,此處的 require('_components/Main') 在實際執行的時候,卻時不時是空的 {}

設身處地的想想,這個 bug 有多難 deeeeeeeeeeeeeeee

webpack magic

在經過多方交叉測試確認不是我程式碼這邊的問題之後,所有的矛頭指向了 webpack。但 webpack 的能力太強、文件寫得不夠詳盡,對我來說 code splitting 這件事就是一個 magic,也因此還真的不知道該怎麼 de webpack 的 bug。

於是我在 google 上搜尋各種可能的 keyword

webpack chunk load failed webpack chunk doesn’t load

然後實際上很莫名的會一直搜到它的文件,以及各種 tutorial 或 opinion 文章,頓時真是覺得這個生態系是不是有什麼問題…

直到我從上面的環境中 identify 了關鍵的可能原因,重新用了這個 keyword

webpack multiple instance

搜尋結果其實看起來還是一樣沒有一矢中的的感覺,不過答案其實默默地藏在第三個結果裡。

Ref: https://github.com/webpack/docs/wiki/configuration#outputjsonpfunction

output.jsonpFunction The JSONP function used by webpack for asnyc loading of chunks. A shorter function may reduce the filesize a bit. Use different identifier, when having multiple webpack instances on a single page.

output.jsonpFunction

有稍微 trace 一下的話,可以知道 webpack 想要載入 chunk 的時候會需要使用這個一個名為 webpackJsonp 的 global function (在 window 底下),而這個設定 output.jsonpFunction 就是用來設定這個 function name 的。

在同一個網頁上面有多個 webpack instance 的時候 (ex: AB 都是 webpack,而且都有做 code split),這個 jsonpFunction 的名字相同會讓兩者其中一方的 chunk loading 陷入錯亂(似乎是編號-based,而編號會混在一起)。

所以最後只需要把 Aoutput.jsonpFunction 改成比較 unique 的就解決了。

TL;DR

條件

  • 同一個頁面會用到兩個以上的 webpack instance
    (一般來說就是兩個從 webpack 面來看沒有相關的 bundle)
  • 有需要做 chunk 載入

需要

  • 透過 output.jsonpFunction 確保兩個 instance 的 jsonp function name 不同
/* file: webpack.config.js */

var config = {
  ...
  output: {
    ...
    jsonpFunction: 'somethingPrettyUniqueJsonp'  // so important
  }
};

後記

是說 multiple webpack instance 需要改 jsonp function name 這種事情這麼重要,也太難找!!!!!!