[英]Webpack 2 - Code splitting top-level dependencies
最終編輯
tl; dr決議這是不可能的。
雖然下面的最佳答案確實有一些很好的信息。
從contacts.js
考慮下面的代碼。 這是一個動態加載的模塊,在代碼中的其他地方使用System.import
按需加載。
如果SharedUtil1
也被用於在其中也動態加載與其它模塊System.import
,我將如何去了解有SharedUtility1
所有這些模塊的排除 ,只有按需加載第一次它的需要?
SharedUtil1
頂級System.import
將無法工作,因為我的導出依賴於它:導出只能放在模塊代碼的頂層,而不能放在任何類型的回調中。
Webpack可以實現嗎? 我的版本是2.0.7測試版。
import SharedUtil1 from '../../SharedUtilities/SharedUtility1';
class Contacts{
constructor(data){
this.data = data;
this.sharedUtil1 = new SharedUtil1();
}
}
export default Contacts;
更新1
我認為捆綁加載器是我想要的,但是沒有,它將你導入的模塊轉換為一個不同的函數,一旦它完成異步加載,你就可以通過回調來訪問實際的模塊。 這意味着你不能透明地使模塊X異步加載而不對代碼進行重大更改,更不用說你回到最初描述的問題,如果你的頂級模塊依賴於現在的異步加載依賴,沒有辦法導出它,因為導出必須在頂層。
Webpack中是否有辦法表示依賴加載依賴關系X(如果需要),並且有任何導入模塊導入它以透明地等待導入過程? 我認為這個用例對於任何遠程大型應用程序都是必不可少的 ,所以我不得不認為我只是遺漏了一些東西。
更新2
根據彼得的回答,我試圖讓重復數據刪除工作,因為commonChunk插件與端點之間共享代碼有關,正如他所提到的,並且由於require.ensure
將加載的代碼放入回調中,從而阻止您從ES6 export
任何代碼取決於它。
就重復數據刪除而言, contacts.js
和tasks.js
都像這樣加載相同的sharedUtil
import SharedUtil1 from '../../sharedUtilities/sharedUtility1';
我試過運行webpack
webpack --optimize-dedupe
並且還通過添加
plugins: [
new webpack.optimize.DedupePlugin()
]
到webpack.config。 在這兩種情況下,雖然sharedUtil代碼仍然放在聯系人和任務包中。
閱讀完博客文章后,我終於明白了你的意圖。 我對“頂級依賴”這個詞感到有些困惑。
您有兩個模塊( async-a
和async-b
),它們可以從任何地方(這里是模塊main
)按需加載,並且都有共享模塊的引用( shared
)。
- - -> on-demand-loading (i. e. System.import)
---> sync loading (i. e. import)
main - - -> async-a ---> shared
main - - -> async-b ---> shared
默認情況下,webpack會創建一個這樣的塊樹:
---> chunk uses other chunk (child-parent-relationship)
entry chunk [main] ---> on-demand chunk 1 [async-a, shared]
entry chunk [main] ---> on-demand chunk 2 [async-b, shared]
當shared
< async-a/b
或同一用戶使用async-a
和async-b
的概率很低時,這很好。 這是默認值,因為它是最簡單的行為,可能是您所期望的:一個System.import
=>一個塊。 在我看來,這也是最常見的情況。
但是如果shared
> = async-a/b
並且用戶加載async-a
和async-b
的概率很高,則有一個更有效的分塊選項:(有點難以可視化):
entry chunk [main] ---> on-demand chunk 1 [async-a]
entry chunk [main] ---> on-demand chunk 2 [async-b]
entry chunk [main] ---> on-demand chunk 3 [shared]
When main requests async-a: chunk 1 and 3 is loaded in parallel
When main requests async-b: chunk 2 and 3 is loaded in parallel
(chunks are only loaded if not already loaded)
這不是默認行為,但有一個插件可以將其歸檔:異步模式下的CommonChunkPlugin
。 它在一堆塊中找到公共/共享模塊,並創建一個包含共享模塊的新塊。 在異步模式下,它會將新塊與原始(但現在更小)的塊並行加載。
new CommonsChunkPlugin({
async: true
})
// This does: (pseudo code)
foreach chunk in application.chunks
var shared = getSharedModules(chunks: chunk.children, options)
if shared.length > 0
var commonsChunk = new Chunk(modules: shared, parent: chunk)
foreach child in chunk.children where child.containsAny(shared)
child.removeAll(shared)
foreach dependency in chunk.getAsyncDepenendenciesTo(child)
dependeny.addChunk(commonsChunk)
請記住,CommonsChunkPlugin有一個minChunks
選項來定義模塊何時作為shared
線程化(隨意提供一個自定義函數來選擇模塊)。
下面是一個詳細說明設置和輸出的示例: https : //github.com/webpack/webpack/tree/master/examples/extra-async-chunk
另一個配置更多: https : //github.com/webpack/webpack/tree/master/examples/extra-async-chunk-advanced
如果我已經正確理解了您,那么當不同的代碼塊將其聲明為依賴項時,您希望防止多次加載相同的依賴項。
是的,這是可能的; 如何做到這取決於您的應用程序中的上下文以及它是在ES6還是ES5中。
Webpack 1是在ECMA Script 5中構建的,通常使用CommonJS或RequireJS語法進行模塊導出和導入。 使用此語法時,可以使用以下功能來防止重復的代碼:
從webpack文檔 :
如果您使用一些具有很酷依賴樹的庫,則可能會出現某些文件相同的情況。 Webpack可以找到這些文件並對其進行重復數據刪除。 這可以防止在包中包含重復的代碼,而是在運行時應用該函數的副本。 它不會影響語義。
重點是我的,而不是來源
如文檔所述,代碼拆分保持不變; 需要sharedUtil1
每個模塊sharedUtil1
應該將require
聲明為正常。 為了防止多次加載相同的依賴項,啟用了webpack設置,該設置使webpack在運行時包含它們之前顯式檢查文件是否有重復。
使用--optimize-dedupe
resp啟用此選項。 new webpack.optimize.DedupePlugin()
從webpack文檔 :
require.ensure
函數接受另外的第3個參數。 這必須是一個字符串。 如果兩個分割點傳遞相同的字符串,則它們使用相同的塊...如果模塊位於多個子塊中,則require.include
可能很有用。 父require.include
中的require.include
將包含模塊,子塊中的模塊實例將消失。
簡而言之,模塊的加載被延遲到編譯后期。 這允許在包含重復定義之前將其刪除。 該文檔提供了示例。
從webpack文檔 :
CommonsChunkPlugin
可以將多個條目塊中出現的模塊移動到新的條目塊(公共塊)。 運行時也會移動到commons塊。 這意味着舊的條目塊現在是初始塊。
這非常特定於在多個頁面之間共享塊,這在其他情況下是不相關的。
對高級模塊導入功能的支持是......正在進行的工作。 要了解事物的位置,請參閱以下鏈接:
以下是ES6模塊和webpack的一個很好的總結: 帶有TypeScript和Webpack的ES6模塊
以上信息很可能會過時。
為了你自己的理智,我建議:
如果優化很重要 :當Webpack 2穩定並發布時,恢復為CommonJS / RequireJS語法並升級到ECMA Script 6。
如果ECMA Script 6語法很重要 :使用標准ECMA Script 6導入導出格式並在可用時添加優化功能。
嘗試在sill不穩定的webpack中使用高級模塊加載功能有太多的變化2.等待事情穩定下來,一些非常好的插件在嘗試之前變得可用。
System.import
已在Webpack中棄用。 Webpack現在支持import()
,這需要使用polyfill來實現承諾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.