关于 Atatoscope
关于 Atatoscope
Content Analysis 内容分析
Statoscope 与谁一起使用
目前第一公民是 Webpack 搭配使用
如何接收 stats
Webpack CLI
命令行输入带上 webpack –json stats.json
Webpack Plugin【推荐】
因为会收集有关您的捆绑包的更多信息
config.plugins.push(new StatoscopeWebpackPlugin())
什么是 stats
{
"modules": [/*...*/],
"chunks": [/*...*/],
"assets": [/*...*/],
"entrypoints": {/*...*/},
/*...*/
}Stats 是来自 webpack 的内部信息:它遇到了哪些模块、JS、TS 和 CSS 文件,这些文件被组合到哪些块中,以及生成的资产。所有这些都被合并到一个大 .json 文件中,然后 Statoscope 对其进行分析。
模块详情
{
"identifier": "babel-loader!./src/index.js",
"name": "./src/index.js",
"reasons": [/*...*/],
/*...*/
}例如:我们的主应用程序文件 , index.js 具有标识符和文件名;它位于此路径中。在属性中 reasons ,我们可以看到此文件的导入位置以及使用位置。这是 Webpack 在 stats
Statoscope处理统计数据,执行分析并提供可视化表示,以方便的形式解释结果:

在上面的中间图像中,我们可以看到异步的块 main 。
块通常有两种类型:
initial
加载页面时必须加载此页面。async
这是动态导入的结果,可能不会立即加载到页面上;因此得名asynchronous。如果将应用程序拆分为动态部分(例如,如果您有一个大型动画库,该库仅在需要动画时才需要加载),则这是一个asynchronous块。

软件包及其版本的副本

基于相同的信息,Statoscope 还计算包树 — 基本上是捆绑包中使用的 npm -package:哪些包以及每个包的副本数量
例如,在设置包 A 和包 B 时,可能会遇到这种情况。这两个软件包都使用相同的软件包 C,但版本不同。事实证明,突然间,您的捆绑包中出现了双倍的套餐 C。Statoscope告诉您:“您有两个版本的软件包 fbjs 。在根目录下,使用版本 0.8.17,而版本 2.0.0 在 draft-js 中的某个地方使用。请解决此问题。更新你的依赖项,包副本就消失了。
正如你所看到的,Statoscope 用一些额外的信息来丰富它 stats :例如,关于包版本。最初,Webpack stats 不包含有关包版本的信息。稍后我将解释这是如何发生的
MODULE MAP 模块映射

如果您已经使用过其他工具进行分析 stats ,例如。Webpack Bundle Analyzer,那么你应该熟悉模块映射
模块映射是 Statoscope 的一部分。区别在于 Webpack Bundle Analyzer 分析的是 Webpack 的内部结构,而不是 stats .想法基本相同,但方法不同。
Statoscope 允许您在一个地方分析模块、模块映射、块和资产
COMPARING BUNDLES 比较捆绑包


我们可以选择 以前的 和 当前 stats ,单击按钮,Statoscope 将显示已更改的内容,通常:哪些模块在那里,哪些模块被创建、删除、添加或简单地更改(例如,大小更改);添加、更改、删除了哪些块,等等
例如,假设当前 feature 来自当前 stats 分支。你正在做一个很棒的功能,“之前” stats 可能 stats 来自主分支。您想知道:我的新功能会拖累捆绑包吗?我是否使母版中当前的内容变得更糟?你可以向Statoscope询问这些事情,它会告诉你它是否变得更糟(或更好),以及如何变得更糟
Custom Reports 自定义报表
如果 Statoscope 没有为您提供足够的报告,那么您可以生成自己的报告。
但是Statoscope也可以解决一些问题。
Stats 是大文件,可以变成几千兆字节大 .json 。此文件是其自己的格式,要提取数据,通常需要编写大量代码。可能没有人愿意编写这些代码,尤其是在有很多代码的情况下。要是有更简单的方法就好了
JORA # (opens in a new tab) 乔拉#
这个问题的一个解决方案是称为 jora (opens in a new tab) 的查询语言。
以下是一些 JS 代码,我们可以用来从 stat 模块列表中提取并按名称对它们进行排序:
const modules = [];
for (const compilation of compilations) {
for (const module of compilation.modules) {
modules.push(module);
}
}
modules.sort((a, b) => a.name.localeCompare(b.name))这是 Jora 中的一小段代码,它做了完全相同的事情。
compilations.modules.sort(=>name)
Filter # (opens in a new tab) 滤波器#
modules.[size > 1000]
我们可以说:给我所有大于一千字节的模块。
Map # (opens in a new tab) 地图#
modules.({module: $, size})
我们制作一个地图,为了得到结果对象,我们还生成了一个函数,将对象返回给我们。
UI # (opens in a new tab) 用户界面#
因此,我们已经研究了 Statoscope 如何让我们使用查询语言 Jora 进行统计查询和创建报告。但是如何显示它呢?我们需要一些 UI——我们不能只显示 JS 对象的结构。我们想要添加列表、标题、按钮和徽章。
似乎我们可以在 React 中制作 UI。但是我们遇到了更多的问题:接口必须捆绑并托管在某个地方。Statoscope提供了一种解决此问题的方法。
Discovery.js (opens in a new tab) 是一个声明式 UI 的平台。
PUTTING IT ALL TOGETHER # (opens in a new tab) 放一起

如果单击 Statoscope 中的 Make report 按钮,则可以在顶部输入 Jora 中的任何查询,在下面的字段中可以输入 UI,即以 JSON 表单描述布局,然后在下面输入报告。
INTEGRATING INTO UI # (opens in a new tab) 集成到 UI 中#
像这样的自定义报告也可以使用适用于 Webpack 的 Statoscope 插件嵌入到 CI 中的报告中。这个插件有属性 reports ,你告诉:将我的自定义报告嵌入到我的HTML报告中。这实际上与之前的变体相同,但在这里我们只有前 20 个最重的模块;我们切断了下边界。
new StatoscopeWebpackPlugin({
reports: [
{
id: 'top-20-biggest-modules',
name: 'Top 20 biggest modules',
data: { some: { custom: 'data' } }, // or () => fetchAsyncData()
view: {
{
data: `#.stats.compilations.(
$compilation: $;
modules.({
modules: $,
hash: $compilation.hash,
size: getModuleSize($compilation.hash)
})
).sort(size.size desc)[:20]`,
view: 'list',
item: 'module-item',
},
},
},
],
})报告的名称在第 5 行,数据在第 6 行——如果需要的话。例如,如果我们想创建一个自定义报告,其中包含有关捆绑包如何更改的指标,则可能需要它。我们可以将信息从指标存储导入到 data .例如,我们可以记录每日平均捆绑包构建时间,将其与指标一起发送到存储,然后将其嵌入到自定义报告中。我们说:从那里获取指标,并创建一个带有折线图的 UI 报告,显示我们的捆绑包如何随时间变化。 Discovery.js 也可以创建这样的图表。太方便了。

Validation # (opens in a new tab) 验证#
这是一件非常酷、非常重要的事情。为什么它对我如此重要?几个星期以来,我一直在掌握它,试图弄清楚如何验证 stats .我想设置它,以便我们的拉取请求不会最终进入主节点,以防它们恶化我们的捆绑包的质量(例如,通过增加捆绑包大小或构建时间)。主人不需要那个。
如何使验证过程变得简单?我环顾四周,但找不到任何简单的解决方案。
我尝试了不同的方法来想出一些东西,尝试和失败,尝试和失败......但最后我解决了。Statoscope CLI 就是这样诞生的。它是一个控制台实用程序,可用于验证统计信息。
## **Install CLI 安装 CLI**
npm install -D @statoscope/stats-validator-plugin-webpack
## **安装用于验证 webpack 包的插件**
npm install -g @statoscope/cliRUNNING VALIDATION # (opens in a new tab) 运行验证
这一切都很简单。我们在控制台中运行它:#
statoscope validate --input ./stats.json我们输入命令 statoscope validate ,它允许我们进行验证,并指示我们要在哪个 stats 文件上运行测试。我们收到一份报告(在控制台和浏览器中)。
在这里,我们验证了一个 stats 文件。但是,除了分析单个 stats 文件的规则(例如“有双精度吗?”)之外,我们是否可以制定一个规则来比较,例如,您增加了多少捆绑包大小?例如,您希望增加不超过 2%。为此,您需要同时使用 stats 当前分支和主分支。
RECEIVING A REPORT # (opens in a new tab) 接收报告#
让我们看看我们在控制台中看到的内容,但格式易于理解:
Stats Queries # (opens in a new tab) 统计查询#
继续下一部分关于 CLI。为什么我们需要 stats 查询?
这是您的 stats.json :有关模块、块和资产的信息。我们希望从您的捆绑包的大小或长度中获得 stats 信息。例如,您可能需要它来为拉取请求创建自定义注释或发送指标。

如果您只能访问视觉部分,则会成为一个问题:不清楚如何从那里提取数据。但是你有 控制台实用程序 statoscope query ,我们可以用它来解决所有问题。它允许我们进行 Jora 查询。

在绿线下:我们要进行哪个查询;在蓝色下:我们要查询哪些统计信息。例如,我们说:给我们模块的数量。公用事业公司会做出回应。
我们可以进行任何 Jora 查询并将其保存在单独的文件中。所以,我们可以说:给我来自 query.jora 文件的查询,将其发送到 statoscope 查询,将其应用于这些 stats ,然后将结果保存在 result.json 文件中。
CI — PUTTING IT ALL TOGETHER # (opens in a new tab) CI — 把它们放在一起#
让我们看看如果我们将验证和 statoscope 查询结合在一起会发生什么。我将根据 Github Actions 展示这一点
COMMITS IN PULL REQUESTS # (opens in a new tab) 在拉取请求中提交#
但最有趣的是:我们在拉取请求中也有注释。对于拉取请求中的每个提交,我们构建捆绑包,从中获取 webpack stats ,调用该文件, reference.json 下载上一步中的工件 input.json ,您现在有两个文件。我们将这两个 stats 提供给 statoscope validate(我们得到一个 )和 statoscope query(我们得到一个 report.html result.json )。
就是这样!我们有一个 UI 报告和来自查询的自定义数据,我们现在可以代表我们的机器人创建(例如)一些自定义评论。

Plans # (opens in a new tab) 计划#
在本文的最后,我将向您介绍我们即将到来的计划,因为它们非常庞大。
- Custom
statsformat. 自定义stats格式。
请记住,我正在将 Statoscope 独立于任何特定的捆绑器。但为了不阻止它与不同的stats格式隔绝,我想将它们全部转换为一种通用格式。 - I really want to let you extend the UI. 我真的很想让你扩展 UI。
一般来说,可扩展性是这个项目的一个关键特殊性,我正在努力实现这一点。我希望 Statoscope 使用插件进行扩展。 - The above-mentioned support from other bundlers. 来自其他捆绑器的上述支持。
我想将 Statoscope 与 webpack 分离,这样 Statoscope 中就不会提到 webpack——只在插件中提及。 - Simpler process. 流程更简单。
我想将 CI 中的集成过程合并到一个 Github Action 中,并将其作为包发布,这样您就不必复制和粘贴源代码,而是安装 Github Action 并使用它。 - A single portal for documentation. 单一的文档门户。
目前,所有文档都已推送到存储库中的自述文件中。如果你去仓库,你会看到包文件夹,基本上有一些包的文档。我真的很想要一个单一的文档门户——就像 Jest 所做的那样(我喜欢他们这样做的方式)。 - I want to support
rempl(a technology which appeared in demo form as Webpack Bundle Analyzer in 2016). 我想支持rempl(该技术在 2016 年以演示形式出现为 Webpack Bundle Analyzer)。
这个想法是,如果你在像 HMR(热模块替换)这样的监视模式下使用捆绑包,你打开浏览器,你就可以直接在浏览器的开发者工具中访问 Statoscope。你更改源代码中的某些内容(例如某些 React 组件的属性),保存它,HMR 会为您解决,Statoscope 也在浏览器的开发工具中,并且您不需要不断生成报告。 - Analysis of the bundler config. 分析捆绑器配置。
配置,特别是 webpack,当然是一个独立的故事和单独的技能。而且我真的很想给同事们一些建议,实时修改配置,让它有效。当 Statoscope 具有这样的功能时,制作有效的捆绑包会更容易。 - Recommendation on the optimization of bundles. 关于捆绑包优化的建议。
我希望 Statoscope 能够说:“听着,同事,你搞错了,你可以在这里优化一些东西——进行这些更改,你就会将捆绑包的大小减少这么多兆字节。 - Redesign. 重新设计。
我要特别感谢我的同事Danila Avdoshin,她找到了空闲时间进行重新设计。目前,它只保存在 Figma 原型中,但我相信我们很快就会完成它。 - And my personal dream: bundle rating. 还有我个人的梦想:捆绑评级。
我希望能够比较捆绑包的质量。现在,我只是在考虑如何做到这一点,但我希望看到在配置效率、使用 webpack 可能性的效率等方面的顶级捆绑包。
FAQ
如何快速找出目标模块与入口模块的依赖关系
输出 stats.json 文件
CodeShandbox 在线 Demo (opens in a new tab)
新增 stats-analyze 命令产出一份 stats.json 文件
{
"scripts": {
"build": "webpack",
++ "stats-analyze": "webpack --config webpack.config.js --json > stats.json",
}
}上传至 Statoscope 分析平台
前往: https://statoscope.tech (opens in a new tab)

上传成功后会看到如下

找到目标模块
Modules -> e.js (输入框输入你的目标模块名)

查看其 Issuer Path
能看到模块文件级别的整个依赖关系 然后就可以递归的向上找到有问题的那一次引入了

