webpack import() 動態加載模塊踩坑

import

webpack根據ES2015 loader 規範實現了用於動態加載的import()方法。react

這個功能能夠實現按需加載咱們的代碼,而且使用了promise式的回調,獲取加載的包。webpack

在代碼中全部被import()的模塊,都將打成一個單獨的包,放在chunk存儲的目錄下。在瀏覽器運行到這一行代碼時,就會自動請求這個資源,實現異步加載。es6

這裏是一個簡單的demo。web

import('lodash').then(_ => {
    // Do something with lodash (a.k.a '_')...
  })

能夠看到,import()的語法十分簡單。該函數只接受一個參數,就是引用包的地址,這個地址與es6的import以及CommonJS的require語法用到的地址徹底一致。能夠實現無縫切換【寫個正則替換美滋滋】。express

而且使用了Promise的封裝,開發起來感受十分自在。【包裝一個async函數就更爽了】api

然而,以上只是表象。promise

只是表象。瀏覽器

我在開發的時候就遇到了問題。場景是這樣的:一個對象,存儲的是各級的路由信息,及其對應的頁面組件。爲減小主包大小,咱們但願動態加載這些頁面。app

同時使用了react-loadable來簡化組件的懶加載封裝。代碼以下所示。異步

function lazyLoad(path) {
  return Loadable({
    loader: () => import(path),
    loading: Spin,
  });
}

而後我就開始開心的在代碼中寫上lazyLoad('./pages/xxx')。果不其然,掛了。瀏覽器表示,沒有魚丸沒有粗麪,也不知道這個傻逼模塊在哪裏。

因而我查看了官方文檔,發現有一個黃條提示。

clipboard.png

emmm,看來問題出在這裏了。

這個現象實際上是與webpack import()的實現高度相關的。因爲webpack須要將全部import()的模塊都進行單獨打包,因此在工程打包階段,webpack會進行依賴收集。

此時,webpack會找到全部import()的調用,將傳入的參數處理成一個正則,如:

import('./app'+path+'/util') => /^\.\/app.*\/util$/

也就是說,import參數中的全部變量,都會被替換爲【.*】,而webpack就根據這個正則,查找全部符合條件的包,將其做爲package進行打包。

clipboard.png

所以,若是咱們直接傳入一個變量,webpack就會把 (整個電腦的包都打包進來[不鬧]) 認爲你在逗他,而且拋出一個WARNING: Critical dependency: the request of a dependency is an expression。

因此import的正確姿式,應該是儘量靜態化表達包所處的路徑,最小化變量控制的區域

如咱們要引用一堆頁面組件,可使用import('./pages/'+ComponentName),這樣就能夠實現引用的封裝,同時也避免打包多餘的內容。

另一個影響功能封裝的點,是import()中的相對路徑,是import語句所在文件的相對路徑,因此進一步封裝import時會出現一些麻煩。

由於import語句中的路徑會在編譯後被處理成webpack命令執行目錄的相對路徑.

友情連接:

https://webpack.js.org/api/mo...

相關文章
相關標籤/搜索