babel 使用不当 致使ssr内存泄漏

背景

基于vue-cli 开发的自定义组件 A 被另一个ssr 项目引用vue

A 经过默认命令打包 生成 dist/A.umd.js 和dist/A.common.jsnode

package.json 设置 main 为 dist/A.umd.jswebpack

表现

搜索服务 出现告警 查询系统监控发现服务 由于内存暴涨在不断重启web

内存泄漏严重vue-cli

调查

1.比对最近提交的代码 在发现A的使用会致使内存泄露之后 想查出npm

2.该组件 经过webpack 打包进入服务端渲染的vue-server-bundle.json中json

3.删除该组件 内存泄露修复segmentfault

测试重现

1.组件在webpack 配置了nodeExternals whitelist 打包进项目中 内存泄露babel

2.组件main 设置为 umd 或者commonjs 在上述条件下都会引发内存泄露app

3.组件 直接经过 nodeExternals 过滤 不打包进vue-server-bundle.json 在ssr node 项目中 npm install 组件A 运行 不会内存泄露

4.nuxt 调用该组件 没有内存泄露

分析缘由

<template>
  <i />
</template>

<script>
export default {
  props: {
    test: {
      type: Number
    }
  }
}
</script>
复制代码

将组件最小化 而后进行打包 以后分析打包结果 发现内存引入了针对Number的polyfill

总结缘由

  1. vue-cli 默认的 useBuiltIns 是 usage
  2. 组件中用了 Number 作 props 的 validation,Number 的 polyfill 被打包到 package 中
  3. 这个 polyfill 对global进行了定义
  4. 而且这个组件被加到了 webpack 的 externals whitelist里面,代码会 build 到 vue-server-bundle.json 中
  5. SSR 的运行环境是 runInNewContext: true,每次请求进来以后都会从新建立上下文

修复

1.组件服务端安装 不要打包到vue-server-bundle.json中

2.打包组件的时候 babel 配置中使用 useBuiltIns:false不要将polyfill 打包到代码当中去 调用方本身使用polyfill

3.打包组件的时候 若是是为了提供给服务端渲染使用 babel 配置 @vue/app 而且 node:current polyfill 也不会打包进去

引伸

babelrc babel.config.js 加载逻辑: segmentfault.com/a/119000001…

相关文章
相关标签/搜索