搜索博客与维基

技术/前端/构建

为什么把 mermaid 从依赖里删掉

装了又卸。npm audit 报出五个高危漏洞,链条全在 mermaid 的解析器依赖上,最后改成从 CDN 懒加载。

踩坑记录。结论先放前面:mermaid 不要装成 npm 依赖,改成浏览器里按需从 CDN 加载。

事情经过

画流程图需要 mermaid。第一反应是照常规做法装包:

npm install mermaid

装完顺手跑了一次审计:

npm audit

输出里跳出 5 个 high:

漏洞位置类型
lodash-es@chevrotain/* 链路Code Injection via _.template
lodash-es@chevrotain/* 链路Prototype Pollution via _.unset
lodash-es@chevrotain/* 链路Prototype Pollution via _.omit

问题不在 mermaid 本身,在它用来做语法解析的 chevrotain 那一串依赖,里面拖着 lodash-es。这些包是运行时进浏览器的,不是只在构建期跑。

怎么处理的

先把包卸掉:

npm uninstall mermaid

再审计一次:

npm audit

结果是 found 0 vulnerabilities。

然后改成在页面里按需加载。只有页面真的出现 <div class="mermaid"> 时才去 CDN 拉脚本,其他页面一个字节都不下载。代价是离线环境下图表渲染不出来,这个已经写进关于页的已知边界里了。

取舍要说清楚

卸包解决的是「这些代码没有被我们的构建产物打包进去」。CDN 那条路是另一件事:图表源码会经过第三方 CDN。图表里如果不放敏感内容,这个代价可以接受;要放敏感内容,就得把 mermaid 自托管到 public/ 下面。

顺带说一个更常见的坑

不是所有依赖都值得装。判断标准大概三条:

  1. 它是不是只在某一个页面用得到?是的话,按需加载比打进主包划算。
  2. 它是运行时依赖还是构建期依赖?构建期的包不进用户浏览器,风险小一截。
  3. 它拖进来多少间接依赖?npm ls <包名> 能看清整棵树,树太深就要警惕。

可复现的检查清单

npm install <候选包>
npm audit                    # 看有没有漏洞
npm ls <候选包>              # 看依赖树有多深
npx depcruise src            # 可选,看模块耦合

不满意就 npm uninstall 回退,npm 里这是无损操作。

给之后的自已

加任何依赖之前先看一眼依赖树。省下来的排查时间比省下来的配置时间多得多。