Webpack 在 bundle 中包含自己的依赖项

Posted

技术标签:

【中文标题】Webpack 在 bundle 中包含自己的依赖项【英文标题】:Webpack including its own dependencies in bundle 【发布时间】:2020-12-08 07:31:44 【问题描述】:

我是 webpack 的新手,我有一个使用 vue cli 的 Vue 项目。在使用webpack-bundle-analyzer 分析webpack 包(使用vue-cli-service build 在生产模式下构建)时,我发现一个特定文件bn.js 被多次包含在包中。运行npm ls bn.js时发现它的父依赖是webpack本身。

`-- webpack@4.44.1
  `-- node-libs-browser@2.2.1
    `-- crypto-browserify@3.12.0
      +-- browserify-sign@4.2.1
      | +-- bn.js@5.1.3
      | +-- browserify-rsa@4.0.1
      | | `-- bn.js@4.11.9
      | +-- elliptic@6.5.3
      | | `-- bn.js@4.11.9
      | `-- parse-asn1@5.1.6
      |   `-- asn1.js@5.4.1
      |     `-- bn.js@4.11.9
      +-- create-ecdh@4.0.4
      | `-- bn.js@4.11.9
      +-- diffie-hellman@5.0.3
      | +-- bn.js@4.11.9
      | `-- miller-rabin@4.0.1
      |   `-- bn.js@4.11.9
      `-- public-encrypt@4.0.3
        `-- bn.js@4.11.9

所以我的问题是,为什么在项目中将 webpack 作为 devDependency 添加(之前它是一个依赖项,然后我将其更改为 devDepenency)时,webpack 在最终包中包含它自己的依赖项?

或者,如果这是正确的行为,请指出任何解释此行为的文档/资源。

【问题讨论】:

我遇到了这个问题,因为直接导入 -- 以及使用间接导入的节点包 -- 节点 crypto 模块。摆脱它是一只熊,因为我并没有真正找到一种方法来追踪哪个依赖是负责任的。这是一个错误的尝试。最终我用浏览器友好的版本替换了所有需要crypto 的东西。感谢tweetnacljsrsasign @kjur 【参考方案1】:

事实证明这是一个 npm 的事情。早些时候,我在 package.json 中有 webpack 作为依赖项。然后我运行npm uninstall webpack --save,然后再次运行npm install webpack --save-dev,以使其成为开发依赖项。事实证明这还不够。只有在我删除了我的 node_modules 文件夹然后再次执行 npm install 之后,我才停止在我的包中获取 webpack 依赖项。

【讨论】:

【参考方案2】:

关于我如何找到问题所在框架的提示。在 Webpack 配置中,我设置了 node: false,然后构建了生产代码。 Webpack 应该标记有问题的框架。对于最初为服务器端编写并期望某些包可用并且不会显示在 package-lock.json 上的代码,这可能是一个问题。

如果您使用的是 create-react-app 之类的东西,那么您可以使用 react-app-rewired 之类的框架来自定义 Webpack 配置。

未使用的代码破坏快乐!

【讨论】:

【参考方案3】:

我遇到了一个类似的问题,我无法找到为什么要导入名为 bn.js、elliptic 等的库。

事实证明,这是因为我们使用了一个名为 [generate-password][1] 的库,即 importing crypto,因此我看到了多个从未导入的模块。看看下面这张图片。

如果您发现自己处于无法在代码库中找到特定库的导入语句的情况,请执行以下操作:

npm ls libname

在某些情况下,某些库会在内部导入这些方法,因此会导致您的供应商捆绑包膨胀。 对于generate-password,它正在从节点导入加密模块。由于generate-password 正在使用加密模块中的一个函数,因此整个模块最终都在供应商捆绑包中。

我如何避免导入加密货币:

    将生成密码源代码作为实用程序复制到我的代码库中。 将加密库中的 randomBytes 函数替换为特定的 npm version of the randomBytes。 删除 node_modules 并使用 yarn/npm 重建。

【讨论】:

以上是关于Webpack 在 bundle 中包含自己的依赖项的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 webpack 在 nodejs 应用程序中包含 jquery?

使用 webpack 在 Vue PWA 中包含大型 js 依赖项

webpack 代码优化压缩方法

如何使用 webpack 在 index.html 中包含第三方库,如 jquery 和 bootstrap-table?

Webpack 优化导致 Bundle 大小增加

webpack 插件: html-webpack-plugin