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…

相關文章
相關標籤/搜索