如何在webpack DLL中包含npm模块?

Pat*_*und 10 webpack

我正在尝试使用webpack的DLL插件(版本1.13)创建一个DLL包,其中包含我需要的各种反应项目所需的所有npm模块(即preact,preact-compat,redux,react-redux,redux-saga) ,重新组合).我想通过我店的内部npm repo分发包含所有这些npm模块的DLL包.一些Web应用程序应该从npm repo加载DLL包并使用其中包含的模块.

GitHub上的webpack repo中使用webpack中的DLL的示例中,名为的模块module包含在alpha-DLL中.module来自node_modules示例目录中的目录(dll dir下面的一个目录).

这工作,当我使用节点build.js在dll-user目录中构建示例并查看时dll-user/js/output.js,我可以看到这些行:

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

命名的模块module不是真正的npm模块,它只是一个名为module.js直接坐在node_module目录中的文件.在这种情况下,我尝试包含一个"真实世界"的npm模块preact.

在构建dlldll-user项目之后,查看output.js文件,我可以看到preact模块的整个代码包含在输出中,没有委托发生.

我该如何正常工作?这是webpack中的错误吗?

我基于webpack DLL示例在GitHub上创建了一个代码示例,该示例显示了问题:https://github.com/pahund/webpack-dll-problem

4nd*_*ril 6

编辑:

最初我只是给出了给定的示例工作,但并不知道应该如何使用所有内容.我写了这个(块下面的新内容):


好的,所以我认为我至少得到了它的一部分.我会告诉你为了让你的例子有效你必须做些什么.

有两种方法可以使它工作:

  1. preact包含文件夹package.json(node_modules如果需要)中删除,即从顶层删除.现在你只有在文件夹中. 然后将 文件夹中的调用更改为 应该工作但不完全是我们想要的.preactdll
    requireexample.jsdll-user
    require("../dll/node_modules/preact")

  2. 现在反过来了.preactdll文件夹中删除但仅将其安装到包含的文件夹中.
    运行这两个构建脚本,看看output.js是否包含了所有委托的内容preact.


新:

好的,所以经过一番探讨之后,我认为它是如何运作的.(因为我们彼此了解并且一起工作的次数会减少,但我认为如果我对细节更加明确,这也可能对其他人有所帮助,所以请耐心等待.)

初步说明:我假设您要创建一个dll文件,您可以使用npm将其安装到项目中; 2)以某种方式在HTML中包含单独的脚本标记.该脚本在执行时创建一个全局变量,该变量公开一个函数,该函数又由应用程序脚本用于解析依赖关系.此外,我假设你已经设置了一个dll包的目录,只package.json安装了一个和webpack ready.

首先你创建一个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)
    })
  ]
};
Run Code Online (Sandbox Code Playgroud)

现在用它创建包及其清单

$ webpack
Run Code Online (Sandbox Code Playgroud)

dll项目文件夹的结构现在是:

dll-project
|_ node_modules
| |_ preact
|_ main.js
|_ main-mainifest.json
|_ package.json
|_ webpack.config.js
Run Code Online (Sandbox Code Playgroud)

现在您已将此软件包安装到另一个项目中,即您的应用:

app
|_ node_modules
| |_ dll-project
|_ index.js
|_ package.json
|_ webpack.config.js
Run Code Online (Sandbox Code Playgroud)

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")
    })
  ]
};
Run Code Online (Sandbox Code Playgroud)

在您index.js的应用程序代码中,您需要以这种方式在dll包中的模块:

var React = require("mydll/node_modules/preact/dist/preact");
Run Code Online (Sandbox Code Playgroud)

如果你运行,webpack -d你会在生成的内容中看到如下内容app.js:

/* 1 */
/*!***************************************************************************************************!*\
  !*** delegated ./node_modules/preact/dist/preact.js from dll-reference main_2057857de340fdcfd8aa ***!
  \***************************************************************************************************/
Run Code Online (Sandbox Code Playgroud)

人们可能会问:"为什么我不能只使用我的标准要求require("preact")?".答案是:你可以,但是.但在这种情况下,你将不得不安装所有这些依赖你在你的DLL包你的应用程序.因为在这种情况下,您将使用"映射模式"而不是"范围模式"(请参阅Webpack文档).

在作用域模式中,您必须显式require指向模块相对于清单的路径.好处是:您不必package.json在应用程序中安装模块(并将其作为依赖项).

在映射模式下,您可以照常使用该模块(就像它安装在您应用程序的node_modules中一样),但您还必须使用app在dll中安装它.这是因为Webpack将require首先评估调用,然后意识到同一模块也在dll包中,因此只将一个别名("委托...")呈现到输出中.


现在我认为这两种模式都有用例.如果您只构建一个app-local dll来加速构建,那么映射模式很酷.在这种情况下,您将安装并保存所有本地进入dll的deps.但是如果你想构建一个dll包作为可安装的模块并在应用程序之间共享它 - 并且你不想在每个这些应用程序中跟踪dll中的所有模块 - 你很可能想要使用作用域模式支付更多详细require电话的价格.