2016-10-09 60 views
8

我試圖使用webpack(版本1.13)的DLL插件來創建一個DLL包,其中包含我需要用於各種React項目的所有npm模塊(即,preact,preact-compat,redux,react-redux,redux -saga,重新組合)。我想通過我店的內部npm回購來分發包含所有這些npm模塊的DLL包。幾個Web應用程序應該從npm repo中加載DLL包並使用其中包含的模塊。如何在webpack DLL中包含npm模塊?

using DLLs in webpack from the webpack repo on GitHub的示例中,名爲module的模塊包含在alpha-DLL中。 module來自示例dir中的node_modules目錄(dll目錄下的一個目錄)。然而

/*!*****************************************************************************************!*\ !*** delegated ../node_modules/module.js from dll-reference alpha_e0d5512587ca63cbbd71 ***! \*****************************************************************************************/

命名module該模塊是:

這工作,當我使用節點build.js建立在DLL用戶目錄的例子,看看dll-user/js/output.js,我可以看到這幾行不是一個真正的npm模塊,它只是一個名爲module.js的文件,直接位於node_module目錄中。我試過包括一個「真實世界」npm模塊,在這種情況下preact

在構建dlldll-user項目之後,看到output.js文件,我可以看到preact模塊的整個代碼都包含在輸出中,沒有代表團發生。

如何正確使用此功能?這是在webpack中的錯誤嗎?

我創建基礎上的WebPack DLL例如在GitHub上的代碼示例顯示了問題:https://github.com/pahund/webpack-dll-problem

回答

4

編輯

本來我只是做給定的例子工作,但並沒有真正的想法如何使用一切。我寫了這個(塊下面的新內容):


好的,所以我想我至少有一部分。 我會告訴你你必須做些什麼來使你的例子工作。

有兩種方法,使其工作:

  1. package.json(和node_modules如有必要)含即頂層的刪除preact。現在只有dll文件夾中有preact
    然後dll-user 文件夾內改變example.jsrequire調用
    require("../dll/node_modules/preact")
    這應該工作,但不正是我們想要的。

  2. 現在反過來。從dll文件夾刪除preact文件夾,但只安裝到包含文件夾。
    運行兩個構建腳本,並看到在output.js中包含preact,因爲它應該包括。


新:

好了,以後多一點關注着這裏是我怎麼想工作。 (既然我們彼此認識,並且一起工作的話會少一些字就可以,但是我認爲如果我對細節更加明確一些,也可以幫助其他人),所以請耐心等待。)

初步評論:我假設你想要創建一個dll文件,您可以使用npm和2)將該文件安裝到項目中)以某種方式將單獨的腳本標記包含到HTML中。該腳本在執行時創建一個全局變量,該變量公開一個函數,該函數又被應用程序腳本用於解決依賴關係。 此外,我假設你已經有一個只有package.json和webpack就緒安裝的dll包的目錄。

首先創建一個webpack.config.js這樣的:

var webpack = require("webpack"); 
var path = require("path"); 

module.exports= { 
    entry: ["preact"], // put here every module that goes into the dll 
    output: { 
    path: __dirname, 
    filename: "index.js", 
    library: "[name]_[hash]" 
    }, 
    plugins: [ 
    new webpack.DllPlugin({ 
     path: path.join(__dirname, "[name]-manifest.json"), 
     name: "[name]_[hash]" // (keep consistent with output.library) 
    }) 
    ] 
}; 

現在創建軟件包及其清單與

$ webpack 

DLL項目文件夾的結構是現在:

dll-project 
|_ node_modules 
| |_ preact 
|_ main.js 
|_ main-mainifest.json 
|_ package.json 
|_ webpack.config.js 

現在,您已經將此軟件包安裝到另一個項目中,即您的應用程序:

app 
|_ node_modules 
| |_ dll-project 
|_ index.js 
|_ package.json 
|_ webpack.config.js 

webpack.config.js樣子(或類似)如下:

var webpack = require("webpack"); 

module.exports= { 
    entry: "./index.js", 
    output: { 
    path: __dirname, 
    filename: "app.js" 
    }, 
    plugins: [ 
    new webpack.DllReferencePlugin({ 
     scope: mydll, 
     manifest: require("./node_modules/dll-project/main-manifest.json") 
    }) 
    ] 
}; 

在你index.js也就是說,你的應用程序代碼,您需要的是這樣的dll捆綁模塊:

var React = require("mydll/node_modules/preact/dist/preact"); 

如果運行webpack -d你會看到類似的產生012以下:

/* 1 */ 
/*!***************************************************************************************************!*\ 
    !*** delegated ./node_modules/preact/dist/preact.js from dll-reference main_2057857de340fdcfd8aa ***! 
    \***************************************************************************************************/ 

有人可能會問:「爲什麼我不能只是用我的標準要求一樣require("preact")?」。答案是:你可以,但是。但在這種情況下,您將不得不在您的應用程序中安裝所有這些依賴項,這些依賴項在您的dll軟件包中也有。因爲在這種情況下,您將使用「映射模式」而不是「範圍模式」(請參閱​​Webpack Docs)。

在範圍模式中,您必須明確require模塊相對於清單的路徑。好處是:您不必在您的應用程序中安裝該模塊(並將其作爲package.json的依賴項)。

在映射模式下,您可以像往常一樣要求模塊(就像它安裝在應用程序的node_modules中一樣),但是您必須在使用應用程序的dll中安裝它。這是因爲Webpack將首先評估require調用,然後意識到同一模塊也位於dll捆綁包中,因此僅向輸出呈現別名(「委託...」)。


現在我認爲這兩種模式都有用例。映射模式很酷,如果你只是建立一個本地應用程序的DLL來加快你的構建。在這種情況下,您將安裝並保存所有進入本地dll的代碼。但是,如果你想構建一個dll bundle作爲一個可安裝的模塊並在應用程序之間共享它 - 而且你不想跟蹤每個應用程序中的dll中的所有模塊 - 你很可能想使用scoped模式支付更詳細的require電話的價格。

+1

謝謝,我會檢查你的解決方案並回復你。 有趣的是,[Bilbasen](http://www.bilbasen.dk/)(手機優化版)上的人正在按照我的計劃進行,而且這對他們很有用。 –

+0

優秀的答案,謝謝! –

+0

這解決了三天的困惑。謝謝。我希望修改DllReferencePlugin以盲目接受manifest.json文件中的內容。當清單中存在需求時,我看不到webpack需要解決這個需求。 –