Nuxt 添加全局插件内存泄漏问题

问题描述

我在 Nuxt 2.13 通用模式下,我有严重的内存使用和泄漏!!

所以当我在寻找相关问题时,我在 Nuxt Docs Plugins - NuxtJS 中找到了这个:

不要使用 Vue.use()、Vue.component(),并且在全局范围内,不要在 Vue 中插入任何专用于 Nuxt 注入的函数。会导致服务器端内存泄漏。

谁能告诉我这是什么意思??

我目前正在使用许多外部插件和一些由 vue.component()vue.use() 全局添加的 mixin。可能是他们的问题?? (我还有一个 utils.js mixin 文件,其中包含许多全局添加nuxt.config方法和计算数据)

我的一些插件和 mixin 全局添加nuxt.config.js 文件中:

// Vuetify 2
import Vue from 'vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
import '@mdi/font/css/materialdesignicons.css' // Ensure you are using css-loader version "^2.1.1"
import 'font-awesome/css/font-awesome.min.css'
import '@fortawesome/fontawesome-free/css/all.css'
import colors from "vuetify/es5/util/colors";
import '~/assets/vuetify.scss'
// let siteDirection = process.env.SITE_DIRECTION

Vue.use(Vuetify)

export default ctx => {
  const vuetify = new Vuetify({
    rtl: process.env.SITE_DIRECTION === 'rtl',customVariables: ['~/assets/variables.scss','~/assets/colors.scss'],icons: {
      iconfont: 'mdi',// default - only for display purposes
    },theme: {
      dark: false,// From 2.0 You have to select the theme dark or light here
      themes: {
        dark: {
          primary: colors.deepPurple.lighten3,accent: colors.deepPurple.accent3,secondary: colors.Amber.darken3,info: colors.teal.lighten1,warning: colors.Amber.base,error: colors.deepOrange.accent4,success: colors.green.accent4
        }
      }
    }
  })

  ctx.app.vuetify = vuetify
  ctx.$vuetify = vuetify.framework
}

// Vue-Glide Package
import Vue from 'vue'
import { Glide,GlideSlide } from 'vue-glide-js'

Vue.component("vue-glide",Glide)
Vue.component("vue-glide-slide",GlideSlide)

// Noty package
import Vue from "vue";
import Noty from "noty";

Vue.prototype.$noty = (type,text) => new Noty({
    layout:process.env.SITE_DIRECTION === 'rtl' ? 'bottomLeft' : 'bottomright',type,text,timeout: 5000
});

// vue-product-zoomer package
import Vue from 'vue'
import ProductZoomer from 'vue-product-zoomer'
Vue.use(ProductZoomer)

我的 Mixins 也是添加的:

import Vue from 'vue'

const FormattedPrice = {
    install(Vue){
      Vue.mixin({
        methods:{
          formattedPrice(price,options){
            if(price !== null && price !== undefined){
              if(typeof price === 'object'){
                let min = price.min ? Number(price.min).toLocaleString() : 0
                let max = price.min ? Number(price.max).toLocaleString() : 0
                return min + ' - ' + max + (options && options.noSign ? '' : this.currencySign)
              }else{
                // try {
                //   return price.toString().replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g,",") + this.currencySign
                //   // return price.toString().replace(/\B(?=(\d{3})+(?!\d))/g,") + this.currencySign
                // } catch (error) {
                //   return Number(price).toLocaleString() + this.currencySign
                // }
                return Number(price).toLocaleString() + (options && options.noSign ? '' : this.currencySign)
              }
            }
            return '...' + (options && options.noSign ? '' : this.currencySign)
          }
        },computed:{
          currencySign(){
            return ' ' + this.shopInfo.currency.sign
          }
        }
      })
    }
  }
  
  Vue.use(FormattedPrice)

解决方法

对于您的问题:

不要使用 Vue.use()、Vue.component(),并且在全局范围内,不要在 Vue 中插入任何专用于 Nuxt 注入的函数。会导致服务器端内存泄漏。

看到这个PR,这是警告的原因。

更明确的解释是,您应该不要从导出的插件函数内部调用Vue.use()Vue.component()。您应该将调用放在全局范围内,并将它们应用到上下文中。

我相信您在从导出的函数内部调用 new Vuetify() 时会出现内存泄漏。他们完全有可能调用 Vue.use()Vue.component() 作为该调用的副作用。

您应该将该调用置于全局范围内。如果这不起作用,那么您可能需要考虑创建一个最小的可重现示例并在 Nuxt GitHub 存储库上打开一个问题。

// Vuetify 2
import Vue from 'vue'
import Vuetify from 'vuetify'
import 'vuetify/dist/vuetify.min.css'
import '@mdi/font/css/materialdesignicons.css' // Ensure you are using css-loader version "^2.1.1"
import 'font-awesome/css/font-awesome.min.css'
import '@fortawesome/fontawesome-free/css/all.css'
import colors from "vuetify/es5/util/colors";
import '~/assets/vuetify.scss'
// let siteDirection = process.env.SITE_DIRECTION

Vue.use(Vuetify)

const vuetify = new Vuetify({
    rtl: process.env.SITE_DIRECTION === 'rtl',customVariables: ['~/assets/variables.scss','~/assets/colors.scss'],icons: {
      iconfont: 'mdi',// default - only for display purposes
    },theme: {
      dark: false,// From 2.0 You have to select the theme dark or light here
      themes: {
        dark: {
          primary: colors.deepPurple.lighten3,accent: colors.deepPurple.accent3,secondary: colors.amber.darken3,info: colors.teal.lighten1,warning: colors.amber.base,error: colors.deepOrange.accent4,success: colors.green.accent4
        }
      }
    }
})

export default ctx => {
  

  ctx.app.vuetify = vuetify
  ctx.$vuetify = vuetify.framework
}