我正在尝试使用webpack的DLL插件(版本1.13)创建一个DLL包,其中包含我需要的各种反应项目所需的所有npm模块(即preact,preact-compat,redux,react-redux, redux-saga,重新组合)。我想通过我店的内部npm repo分发包含所有这些npm模块的DLL包。一些Web应用程序应该从npm repo加载DLL包并使用其中包含的模块。
在using DLLs in webpack from the webpack repo on GitHub的示例中,名为module
的模块包含在alpha-DLL中。 module
来自示例目录中的node_modules
目录(dll目录下方的一个目录)。
这很有效,当我使用node build.js在dll-user dir中构建示例并查看dll-user/js/output.js
时,我可以看到这些行:
/*!*****************************************************************************************!*\
!*** delegated ../node_modules/module.js from dll-reference alpha_e0d5512587ca63cbbd71 ***!
\*****************************************************************************************/
名为module
的模块不是真正的npm模块,它只是一个名为module.js
的文件直接位于node_module
目录中。我尝试了一个“真实世界”的npm模块,在这种情况下是preact
。
在构建dll
和dll-user
项目之后,查看output.js
文件,我可以看到preact模块的整个代码都包含在输出中,没有委托发生。
如何正常运作?这是webpack中的错误吗?
我基于显示问题的webpack DLL示例在GitHub上创建了一个代码示例:https://github.com/pahund/webpack-dll-problem
答案 0 :(得分:6)
修改强>:
最初我只是让这个给定的例子工作,但没有真正的想法如何使用一切。我写了这个(块下面的新内容):
好的,所以我认为我至少得到了它的一部分。 我会告诉你为了让你的例子发挥作用你必须做些什么。
有两种方法可以使它发挥作用:
从包含文件夹(即顶级)的preact
(以及必要时package.json
)中删除node_modules
。现在,您只有preact
文件夹中的dll
。
然后更改require
中example.js
内的dll-user
来电
文件夹到
require("../dll/node_modules/preact")
这应该有效但不完全是我们想要的。
现在反过来了。从 dll 文件夹中删除preact
,但仅将其安装到包含文件夹。
运行这两个构建脚本,并在output.js
中查看代理的所有内容,包括preact
。
新强>
好的,所以经过多一点探讨之后,我认为的工作原理。 (因为我们彼此了解并且一起工作的次数会减少,但我认为如果我对细节更加明确,这也可以帮助其他人,所以请耐心等待。)
初步评论:我假设您要创建一个dll文件,您可以使用npm将其安装到项目中; 2)以某种方式在HTML中包含单独的脚本标记。该脚本在执行时创建一个全局变量,该变量公开一个函数,该函数又由应用程序脚本用于解析依赖关系。
此外,我假设你已经设置了一个dll包的目录,只安装了package.json
和webpack。
首先,您可以像这样创建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
,您会在生成的app.js
中看到以下内容:
/* 1 */
/*!***************************************************************************************************!*\
!*** delegated ./node_modules/preact/dist/preact.js from dll-reference main_2057857de340fdcfd8aa ***!
\***************************************************************************************************/
有人可能会问"为什么我不能像require("preact")
那样使用我的标准要求?"。答案是:你可以,但是。但在这种情况下,您必须在应用中的dll包中中安装所有这些依赖项。因为在这种情况下你会使用"映射模式"而不是"范围模式" (见Webpack Docs)。
在作用域模式中,您必须显式require
模块相对于清单的路径。好处是:您不必在应用中安装模块(并将其作为package.json
中的依赖项)。
在映射模式下,您可以照常使用该模块(就好像它已安装在您应用的node_modules中),但您还必须使用app在dll中安装它。这是因为Webpack将首先评估require
调用,然后意识到同一模块也在dll包中,因此只将别名("委托...")呈现到输出中
现在我认为这两种模式都有用例。如果您只构建一个app-local dll来加速构建,那么映射模式很酷。在这种情况下,您将安装并保存所有本地进入dll的deps。但是如果你想构建一个dll包作为一个可安装的模块并在应用程序之间共享它 - 你不想在每个这些应用程序中跟踪dll中的所有模块 - 你很可能想要使用范围模式支付更详细的require
电话的价格。
答案 1 :(得分:0)
您可以尝试这种方式;
new webpack.DllReferencePlugin({
context: process.cwd(), // Important
manifest: manifest.json
}),