我能在webpack开始构建之前获取依赖树吗?

18

在构建完成前,webpack是否会公开依赖树?我已经在编译器实例中搜索了很久,但没有找到关于依赖树的任何信息。看起来应该有一个隐藏在该对象中的依赖树,因为webpack必须知道这个树才能后期输出stats.json。

我尝试使用dependency-tree npm包,但它不支持我的webpack配置中的某些东西,因此该树是不完整的。


目前的问题表述方式不太可能得到好的答案。它看起来像是一个 XY 问题,但问题并没有说明获取依赖树所要解决的问题。我在使用 webpack 的许多情况下都遇到了获取树可以用来解决问题的情况,但结果却不是必需的。因此,有一整套问题的答案是“你不需要这棵树,在没有它的情况下,这是如何做 Y 的方法”。还有一个重要的可能性是,为了做 Y 而获取树是不可能的。 - Louis
@PetrAveryanov,你在那里看到的并不满足这里所提出的问题标题中所指定的“在webpack开始构建之前获取依赖树”或者在问题正文中指定的“在构建被封存之前公开依赖树”的要求。那个问题中展示的是如何在webpack完全构建完成后获取依赖树。 - Louis
2个回答

25

简短概述: 是的,你可以在依赖树被封闭之前访问它。

要做到这一点,请将以下代码添加到您的webpack.config.js文件中:

class AccessDependenciesPlugin {
  apply (compiler) {
    compiler.hooks.compilation.tap('AccessDependenciesPlugin', compilation => {
      compilation.hooks.finishModules.tap('AccessDependenciesPlugin', modules => {
        /*
        |---------------------------------------------------
        | Here we go, `modules` is what we're looking for!
        |---------------------------------------------------
        */
      })
    })
  }
}


module.exports = {
  // ...
  plugins: [
    new AccessDependenciesPlugin()
  ]
}

查看下面的解释以了解更多细节。


我们正在寻找的钩子

我们可以通过 finishModules 编译钩子访问预先封装的依赖树。


如何确定?

由于 webpack 钩子文档非常简洁(最起码是这样),因此我们不得不阅读 webpack 源代码来确定它是否是我们要寻找的内容:

在封装依赖树之前,编译器执行的最后一件事是"完成"它。

完成依赖树为编译提供了一个钩子。


代码示例

我们创建了一个名为 AccessDependenciesPlugin 的插件:

// Basic webpack plugin structure
class AccessDependenciesPlugin {
  apply (compiler) {

  }
}

要使用编译钩子,我们需要先获得访问 compilation 对象的权限。我们可以使用compilation 钩子实现:

class AccessDependenciesPlugin {
  apply (compiler) {
    compiler.hooks.compilation.tap('AccessDependenciesPlugin', compilation => {
      // We have access to the compilation now!
    })
  }
}

现在我们会调用compilationfinishModules钩子:

class AccessDependenciesPlugin {
  apply (compiler) {
    compiler.hooks.compilation.tap('AccessDependenciesPlugin', compilation => {
      compilation.hooks.finishModules.tap('AccessDependenciesPlugin', modules => {
        // Here we go, `modules` is what we're looking for!
      })
    })
  }
}

modules参数是一个包含Webpack模块及其依赖关系以及其他可用数据的数组。

最后,我们需要将插件添加到我们的webpack配置中:

module.exports = {
  plugins: [
    new AccessDependenciesPlugin()
  ]
}

我们完成了。


希望这有所帮助。


额外内容:webpack 3

根据评论的要求:以下是适用于 webpack 3 的旧插件系统的 AccessDependenciesPlugin 版本。

class AccessDependenciesPlugin {
  apply (compiler) {
    compiler.plugin('compilation', compilation => {
      compilation.plugin('finish-modules', modules => {
        /*
        |---------------------------------------------------
        | Here we go, `modules` is what we're looking for!
        |---------------------------------------------------
        */
      })
    })
  }
}

有没有办法在webpack 3中做同样的事情?我看到这些钩子只在webpack 4中可用。 - Subhendu Kundu
据我所知,这个钩子在webpack 3中已经存在了(虽然是以kebab-case的形式存在的,而且当时访问钩子的方式与上述描述不同):https://github.com/webpack/webpack/blob/webpack-3/lib/Compilation.js#L561 - Loilo
@SubhenduKundu,我已经在我的原始答案中添加了一个兼容webpack 3的版本。 - Loilo

-2

也许 这个GitHub线程 中的代码行能帮助你:

"使用 webpack --profile --json > stats.json 进行编译

( node.js API: { profile: true }stats.toJson())

前往 http://webpack.github.io/analyse/#modules

加载你的状态文件(它没有上传,分析工具只是一个客户端工具)。

稍等片刻,直到图表稳定下来。"

如果这不是你需要的,那么我建议你看看 @Loilo 的回答 - 更复杂,但可能更符合你的需求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接