编辑:
最初我只是让给定的例子工作,但并没有真正了解应该如何使用所有内容。我写了这个(块下面的新内容):
好的,我认为我至少掌握了一部分内容。
我会告诉你如何使你的示例程序工作。
有两种方法可以使其工作:
从包含文件夹即顶层的package.json
(和node_modules
,如果必要的话)中删除preact
。现在你只有dll
文件夹中的preact
。
然后在dll-user
文件夹中的example.js
中更改require
调用为
require("../dll/node_modules/preact")
这应该有效,但不完全是我们想要的。
现在反过来。从dll文件夹中删除preact
,但仅将其安装到包含文件夹中。
运行两个构建脚本,查看output.js
是否按照应有的委托进行,包括preact
。
新:
好的,经过更多的探索,我认为它是这样工作的。(由于我们彼此相识并且有点共同合作,所以可以用较少的词语,但是如果我在细节上更加明确,我认为这也可能会帮助其他人,所以请耐心等待。)
初步说明:我假设您想创建一个dll文件,您可以通过npm将其安装到项目中,并通过单独的脚本标签包含在HTML中。该脚本在执行时创建一个全局变量,公开一个函数,该函数又被您的应用程序脚本用于解决依赖关系。
此外,我假设您已经设置了一个dll捆绑目录,其中只有一个package.json
和已安装的webpack。
首先,您需要创建一个像这样的webpack.config.js
:
var webpack = require("webpack");
var path = require("path");
module.exports= {
entry: ["preact"],
output: {
path: __dirname,
filename: "index.js",
library: "[name]_[hash]"
},
plugins: [
new webpack.DllPlugin({
path: path.join(__dirname, "[name]-manifest.json"),
name: "[name]_[hash]"
})
]
};
现在使用以下代码创建捆绑包及其清单:
$ 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
This 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
中看到类似以下内容的东西:
有人可能会问:“为什么我不能像使用
require("preact")
那样使用我的标准requires呢?”答案是:你可以,但是。但是在这种情况下,你必须在你的dll bundle中安装所有这些依赖项,并且在你的应用程序中也要安装它们。因为在这种情况下,你将使用“映射模式”而不是“作用域模式”(参见
Webpack Docs)。
在作用域模式下,你必须明确地require
相对于清单的模块路径。好处是:你不必在你的应用程序中安装模块(并将其作为package.json
中的依赖项)。
在映射模式下,你可以像通常一样需要模块(就像它已经安装在你的应用程序的node_modules中一样),但你也必须在使用app的dll中安装它。这是因为Webpack将首先评估require
调用,然后意识到相同的模块也在dll bundle中,因此只渲染一个别名(“委托...”)到输出中。
现在我认为这两种模式都有用例。如果你只是构建一个本地应用程序dll来加速构建,那么映射模式很酷。在这种情况下,您将安装和保存所有进入dll的依赖项。但是,如果您想将dll捆绑成可安装模块并在应用程序之间共享它 - 而且您不想在每个这些应用程序中跟踪dll中的所有模块 - 您很可能希望使用作用域模式,付出更多冗长的require
调用的代价。