浏览器中误用Node.JS模块导致编译结果体积膨胀

以 jsonwebtoken 库为例说明在前端随意使用 Node.js 的库可能带来的问题。

浏览器中误用Node.JS模块导致编译结果体积膨胀

软件版本的选择 一文中提到过一个原则:通过使用前后端通用的组件来减少组件的总体数量。由于 webpack 等工具的存在,许多原本设计给 Node.JS 使用的库,也能在未经修改的情况下给浏览器使用,乍看之下组件的通用度大幅提高了,但实际用下来,却发现存在着导致编译结果体积膨胀的问题。

因此在实际使用过程中,对库的选择还要进一步审视和辨别,正如该文中所说:

裁剪不能过度的牺牲功能、性能或用户体验。

首先,事情发生在某个项目中,之前一直没有太过关注编译结果的体积,毕竟第三方库该用就得用,随着库的累积,编译结果随之变大也是没有办法的事。但是今天却发现 vendor.js 的体积似乎有些离谱,已经到了 1.2M ,而项目中又没有使用什么体积特别大的库。

于是开启 webpack 的分析功能,得到如下结果:

Image

第一反应就是 bn.js 是什么东西,再一看感觉它的外层都是加密方法的名称,到底是哪个库用了这些东西呢?于是使用 npm list 来打印出项目的依赖树。内容过多,这里就不贴出来了,在输出的结果中,倒着找上去,发现不是我自己引入的某个库在使用这些加密方法,而是 webpack 用到了它们。于是推测是某种 polyfill 机制被触发了,但具体怎么触发的就没思路了。于是通过搜索引擎,尝试几个模糊的关键字组合来碰碰运气,最终定位到了 jsonwebtoken 这个库,和 相关的解释

总体而言,就是 jsonwebtoken 这个库在开发过程中没有考虑要在浏览器环境中使用,所以内部使用了 Node.JS 自带的 crypto 模块。由于浏览器中没有这个模块,webpack 只好把其在浏览器中的对等实现以 polyfill 的形式加到了输出的 vendor.js 中,于是就出了上图的结果。

一旦定位到原因,解决方式就很简单,用另一个库 jwt-decode 替换掉 jsonwebtoken 就可以了(当然,前提是前端不需要对 token 进行有效性验证,否则功能上将无法替代)。

Image

这就是事情的经过:将后端使用的库,在最少模块的思路下引入前端,却由于水土不服,最终不得不引入另一个库的来作为结束。同时为何时不该裁剪提供了一个良好的范例

浙ICP备15043004号-1