你可能不需要work-loader來處理worker

相信很多人爲了在webpack開發的時候使用 web-worker 而使用了 worker-loader 去進行處理,但是這個 loader 也存在一些問題,其實在webpack下不通過 worker-loader 也是可以使用的,僅僅需要非常簡單的配置就可以。

背景:在多個worker中使用相同的包,最終build後,每個使用的worker中都集成了相同的第三方包,導致打包出來的 app.js 體積暴增,相同的第三方包無法抽離的情況。所以需要將這種方式剔除掉。並且該loader在github上的issue很多問題都沒人解決,並不是很穩定。於是決定替換成web-worker原生方式

未抽離worker-loader時打包出來的包情況

Xnip2019-09-05_14-46-02

從上圖可以看出,同一個 xlsx-populate.min.js 包,在worker中使用後,和worker的邏輯代碼打包到了一起,在非 worker 中使用則被抽離到了 vendor 中,等於多打包了一次,如果多個worker都要用到這個包,那就每個worker都會打包一次。想想都可怕。。。

抽離worker-loader後打包出來的情況

Xnip2019-09-05_15-00-22

從上面打包後的結果來看 xlsx-populate 這個包已經不存在了,整個app.js 的體積明顯減少。

解決思路: 既然使用原生 web-worker 方式,那麼在worker中引入第三方包的話,就只能使用遠程資源的方式了,相應的其他地方用到 這個包的時候,如果使用 import 方式引入,那麼就需要設置 external 來解決

在抽離過程中出現的一些坑記錄如下

  1. 配置 external 屬性時,如下的方式配置會導致xlsx爲undefined

    // webpack 配置
    externals: {
       'xlsx-populate': 'xlsx-populate'
    },
      
    // 組件內使用
    import xlsx from 'xlsx-populate';

    正確配置如下:其中externals 中的value值,應該是引入該scripts後,該scripts在window上暴露出來的全局變量名稱,在這裏就是 XlsxPopulate ,全局變量不一定和包名相同。這一點在webpack的文檔中雖然給了一個 jquery 設置 external 的例子,但是如果不注意很容易忽略掉。

    // webpack 配置
    externals: {
       'xlsx-populate': 'XlsxPopulate'
    },
      
    // 組件內使用
    import xlsx from 'xlsx-populate';
  2. 在 worker 中使用時, importScripts 並不是返回一個暴露出來的模塊供我們使用,所以去哪找掛載在worker中的這個模塊呢?其實這個模塊被掛載在了 該worker的 self 對象上,self 就等於頁面中的 windows 對象

    importScripts('https://cdn-src.aiyunxiao.com/xlsx-populate/1.20.1/xlsx-populate.min.js');
    const XlsxPopulate = self.XlsxPopulate;
    // ... 使用 XlsxPopulate 做接下來的事

看一下最後上線後的結果:

Xnip2019-09-05_15-21-30

頁面中使用 script 標籤引入 xlsx-populate

Xnip2019-09-05_15-23-31

在導出 excel 時,直接使用的緩存的 xlsx-populate 文件,所以整體只加載一次。

原文:chaijinsong-blog

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章