IntelliJ IDEA 发行版可视化器:用一条命令解剖 Plugin Model v2 与 Product DSL 的安装分布
IntelliJ IDEA 发行版可视化器用一条命令解剖 Plugin Model v2 与 Product DSL 的安装分布【免费下载链接】intellij-communityIntelliJ IDEA IntelliJ Platform项目地址: https://gitcode.com/GitHub_Trending/in/intellij-community本指南围绕 intellij-community 仓库中的 docs/dist-visualizer/README.md 及其配套实现讲解如何把一个已安装的 JetBrains IDE 发行目录Distribution解析为一份可交互的单文件 HTML 视图插件、内容模块、加载模式、嵌入模块、可见性、依赖边与启动类路径一览无余。读完本文你将掌握该可视化器的运行方式、六大视图的读图口径以及它从product-info.json与module-descriptors.jar两级数据源构建数据模型、内联生成自包含页面的完整实现原理。它解决什么问题现代 JetBrains IDE 发行版早已不是“一个可执行文件”而是由数百个插件、上千个模块、共享的lib/*.jar巨型 jar、以及bootClassPathJarNames启动类路径组成的复杂体系。Plugin Model v2 与 Product DSL 定义了这一切如何被声明、打包和加载但普通开发者很难直观回答几个问题lib/util-8.jar里到底挤了多少个模块它们都是谁某个插件的内容模块是required、optional还是on-demand加载平台核心的“模块拆分extraction”进行到了哪一步还有多少模块仍以嵌入式embedded方式共享 jar仓库中的 dist-visualizer 就是为回答这些问题而生的工具它以单文件 HTML 的形式输出一个面向已安装 IDE 发行版的交互式可视化器主题严格围绕Plugin Model v2与Product DSL的核心概念展开。两条正交轴Scope 与 Extraction可视化器对每个模块沿两条互相独立的轴进行分类行图标row icon在每一行列表中同时传达这两个维度见 assets/viewer.js 中的 SVG 图标定义Scope作用域——模块类文件位于何处取值含义行图标样式core类被打包进lib/下的 jar由平台自身的RuntimeModuleRepository直接加载青色teal实心方块plugin类被打包进plugins/X/lib/下的 jar由且仅由一个插件拥有蓝色描边方块Extraction抽取度——模块是否是其 jar 的唯一住户取值含义行图标样式extracted独占一个专用 jar如lib/intellij.platform.core.jar实心方块embedded与其他模块共享同一个 jar如lib/util-8.jar打包了 17 个传统 core 模块lib/intellij.platform.ide.impl.jar打包了 23 个模块插件主 jar 也常打包大量内容模块带分隔线的方块两个轴判定的信号源都是modules/module-descriptors.jar中每个模块的resource-root path…/条目。值得注意的是有描述符但没有productInfo.layout[]条目的模块典型是$legacy_jps_module命名空间例如intellij.platform.util会被提升为core模块展示从而让正在进行的模块抽取工作的进度完全可见——这正是 lib/product-info.mjs 中“descriptor-only modules”分支的作用。快速运行一条命令扫描任意已安装 IDE可视化器以 Bun 作为运行时visualize.mjs的 shebang 为#!/usr/bin/env bun。它不需要任何构建步骤不依赖pnpm install也不需要 HTTP 服务器。# 默认路径/Applications/Idea.appmacOS bun docs/dist-visualizer/visualize.mjs # 指定任意已安装的 JetBrains IDEmacOS .app 包 bun docs/dist-visualizer/visualize.mjs /Applications/PyCharm.app # Linux/Windows传入安装根目录包含 product-info.json 与 lib/ 的目录 bun docs/dist-visualizer/visualize.mjs /opt/idea-IC-262.SNAPSHOT从 visualize.mjs 可以看到完整流程解析命令行参数缺省为/Applications/Idea.app调用buildModel(distRoot)读取发行版并构建富数据模型控制台打印摘要统计产品名 版本 (构建号) · N layout entries · N plugins · N modules · N edges [耗时 ms]调用buildHtml(model)生成自包含 HTML写入操作系统临时目录文件名形如idea-dist-viewer-productCode-build.html调用系统默认浏览器打开macOS 用openWindows 用cmd /c startLinux 用xdg-open打开失败时会打印file://路径供手动访问。数据来源只有两个文件发行目录中的product-info.json与modules/module-descriptors.jar。查找布局根目录时依次尝试distRoot、Contents/Resources、Resources三个候选找不到product-info.json会直接抛错见 lib/product-info.mjs。六大视图逐一看生成页面顶部有六个标签页Overview / Plugins / Modules / Treemap / Graph / Boot支持 URL hash 直达如#modules与明暗主题切换主题偏好持久化在localStorage.distViewerTheme。Overview概览Distribution 统计卡片layout 条目总数按plugin/moduleV2/productModuleV2/pluginAlias分别计数、插件数含 bundled 数、模块数core 与 plugin-content 分列、插件别名数、发行总大小与依赖边总数、首个 launch 配置的启动类路径 jar 数Core modules → extraction state展示lib/下“已抽取extracted”与“嵌入式embedded”模块数量及占比点击卡片可直接跳转 Modules 页并套用对应过滤Container jars 表列出共享lib/*.jar的巨石 jarTop 10及其住户tenant数量点击可跳转过滤Plugin content modules → loading mode按required/embedded/optional/on-demand四类展示数量与占比Top 10 plugins by aggregate size按聚合体积排序的插件排行榜。Plugins插件可搜索列表按插件 id 过滤。展开某个插件后可以看到插件描述符模块plugin descriptor module及其命名空间、主 classpathclassPath[]所有 jar、内容模块列表每项带加载模式 chip 与required-if-available标注、以及所有 classpath 位于该插件目录下的模块。Modules模块moduleV2productModuleV2以及仅存在于描述符中的 legacy core 模块的可搜索列表。每一行展示scope/extraction 图标、加载模式、宿主 jar点击即可按该容器 jar 过滤、可见性、所属插件与大小。工具栏提供core | plugin-content、extracted | embedded、四种加载模式、三种可见性的过滤 chip以及一个 Container jar 下拉框。列表为虚拟化渲染无过滤时最多展示前 500 行并提示继续输入以收窄。Treemap矩形树图ECharts发行体积的三种分组模式container jar → tenant先按 scopecore / plugin分组再按 jar 分组突出共享巨石 jarkind → plugin → jar按条目类型 → 插件 → jar 分组plugin → module → jar按插件 → 模块 → jar 分组。共享多住户jar 在图中用加粗边框强调。Graph力导向依赖图ECharts模块依赖关系的力导向图。选择某个插件可将视图限定到该插件的邻域深度滑块控制向外的依赖跳数15。图例口径节点颜色 条目类型kind边框样式 加载模式实线 required/embedded虚线 optional点线 on-demand嵌入式模块边框更亮。不选择插件时展示“插件总览图”节点为插件、边为跨插件依赖关系节点大小对应聚合体积。点击任一节点可跳转到对应模块/插件详情。Boot启动类路径按 OS/arch 选择器切换展示对应launch[]配置的bootClassPathJarNames有序列表及每个 jar 的体积——这是 JVM 实际按序加载的引导路径。离线使用默认情况下只有 ECharts 从 CDNcdn.jsdelivr.netecharts5.5.1加载页面其余部分全部内联。离线场景下可以先把 ECharts 下载到本地资产目录再修改模板中的常量curl -sLo docs/dist-visualizer/assets/echarts.min.js \ https://cdn.jsdelivr.net/npm/echarts5.5.1/dist/echarts.min.js然后修改 lib/template.mjs 中的ECHARTS_CDN指向该文件并让buildHtml将文件内容内联进生成页。实现解剖五个模块如何协作docs/dist-visualizer/ ├── visualize.mjs # CLI 入口——读发行目录、构建 HTML、打开浏览器 ├── lib/ │ ├── zip.mjs # 极简 ZIP 读取器STORE DEFLATE基于 zlib.inflateRawSync │ ├── descriptors.mjs # 解析 module-descriptors.jar 中的 XML 描述符 │ ├── product-info.mjs # 解析 product-info.json、附加 jar 体积、与描述符合并 │ └── template.mjs # buildHtml(data)——把 CSS JS 数据内联进一个 HTML 文件 └── assets/ ├── viewer.css # 深色 IntelliJ 风格主题含浅色主题变量 └── viewer.js # 标签式 SPA——纯 vanilla JS无框架zip.mjs零依赖的 ZIP 解析lib/zip.mjs 手工实现了 ZIP 的 EOCD / 中央目录 / 本地文件头解析支持 STORE方法 0与 DEFLATE方法 8用 Node 内置zlib.inflateRawSync解压两种压缩方式只读取需要的条目不引入任何第三方库。descriptors.mjs模块描述符解析lib/descriptors.mjs 将构建期生成的module-descriptors.jar解析为两类数据pluginModules: MappluginId, { mainModule, contentModules }——插件描述符模块与内容模块清单其中每个内容模块记录namespace、loading与required-if-availablemodules: MapmoduleName, { namespace, visibility, package, dependencies, resourceJars }——模块的依赖区分 module / plugin / library 三种 kind与资源 jar 列表。关键口径源码注释明确记载loading ∈ { required, embedded, optional, on-demand }缺省为optionalembedded意味着模块被打包进插件主 jar与插件描述符模块共享类加载器。描述符中的资源路径形如../lib/foo.jar会被剥离../前缀统一成与productInfo.layout[].classPath相同的lib/foo.jar格式。product-info.mjs数据模型核心lib/product-info.mjs 的buildModel是整个工具的心脏它完成读取product-info.json的layout[]数组为每个条目按 classpath 中的 jar 附加真实体积statSync().size合并描述符数据建立“模块 → 加载模式”“模块 → 所属插件”两个索引对仅存在于描述符的 legacy 模块$legacy_jps_module命名空间补充进模块列表并标记fromLayout: false计算每个插件的聚合体积主 classpath 其拥有的模块体积与模块数计算 scope 与 extraction以描述符首个resource-root无描述符时取 layout 的classPath[0]作为宿主 jar统计每个 jar 的住户数——独居即extracted合住即embeddedjar 以lib/开头为core以plugins/开头为plugin汇总jarTenants容器 jar 表、四种加载模式分布、core/plugin-content 的抽取状态计数等统计量解析launch[]为每个 OS/arch 配置附加bootClassPathJarNames各 jar 的体积。数据模型的局限也在源码中如实标注多个描述符共享一个 jar 时无法按类拆分各模块体积因此 embedded 模块的sizeBytes置 0由容器 jar 承载总大小。template.mjs 与 assets单文件前端lib/template.mjs 的buildHtml把 CSS、内联脚本、window.__DIST_DATA__数据JSON 中的被转义为\u003c以防注入、ECharts CDN 标签与viewer.js拼装成一个完整 HTML。assets/viewer.js 则是一个无框架的标签式 SPA数据注入后由各renderers惰性渲染Modules 列表采用 DOM 虚拟化、无过滤时封顶 500 行主题切换后会对图表类视图强制重绘以套用新配色。适用前提与限制运行环境需要 Bun 运行时脚本本身零第三方运行时依赖仅使用 Node 内置模块。数据完整性可视化完全依赖发行目录中的product-info.json与modules/module-descriptors.jar这两个文件缺失或过旧会直接影响结果模块体积在嵌入式场景下按 jar 整体统计。文档定位可视化的概念口径加载模式、类加载器、可见性、嵌入模块的语义以 Plugin Model v2 规范为基准本仓库的docs/dist-visualizer/只提供工具本体规范文档位于上游仓库的docs/IntelliJ-Platform/4_man/Plugin-Model/与platform/build-scripts/product-dsl/docs/目录当前仓库未包含。如果你想深入前端交互实现可继续阅读 assets/viewer.js 中的图表配置与过滤逻辑若关心数据模型的边界情况如required-if-available、legacy 命名空间、容器 jar 推导则 lib/product-info.mjs 与 lib/descriptors.mjs 是首选入口。【免费下载链接】intellij-communityIntelliJ IDEA IntelliJ Platform项目地址: https://gitcode.com/GitHub_Trending/in/intellij-community创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →