Nuxt and Ag Grid issue SyntaxError Missing stack frames

15,030

Solution 1

After trying every solution given here (Thanks for posting), I managed to render the ag-grid on a nuxt project using < no-ssr > tag and dynamic import (minute 7:40 is explained how to do it, if you are not familiar with codesplitting I deeply recommend to watch the whole video) dynamic import video.

How did I get there? Well, Since Andrew wrote that the problem may have something to do with ssr,I switched my nuxt project into mode: 'spa' and BOOM! ag-grid-vue showed up. Now the problem was, many of my features are heavely based on ssr stuff. So I had to make it work for srr mode, but now I know ag-grid-vue is fully available on the client side, so I switched back to mode: ssr and made the following:

Note: Please do not try to run the snippets since I only used them to share the source I have.

My agGridDemo.vue

<template>
  <ag-grid-vue
    style="width: 500px; height: 500px;"
    class="ag-theme-balham"
    :columnDefs="columnDefs"
    :rowData="rowData"
  ></ag-grid-vue>
</template>
<script>
import { AgGridVue } from 'ag-grid-vue'

export default {
  name: 'ag-grid-demo',
  data() {
    return {
      columnDefs: null,
      rowData: null
    }
  },
  components: {
    AgGridVue
  },
  beforeMount() {
    this.columnDefs = [
      { headerName: 'Make', field: 'make' },
      { headerName: 'Model', field: 'model' },
      { headerName: 'Price', field: 'price' }
    ]

    this.rowData = [
      { make: 'Toyota', model: 'Celica', price: 35000 },
      { make: 'Ford', model: 'Mondeo', price: 32000 },
      { make: 'Porsche', model: 'Boxter', price: 72000 }
    ]
  }
}
</script>

<style lang="scss">
  @import "~/node_modules/ag-grid-community/dist/styles/ag-grid.css";
  @import "~/node_modules/ag-grid-community/dist/styles/ag-theme-balham.css";
</style>

Nothing new here, I guess, just that importing the stylesheets in nuxt.config.js file, made the stylesheets unreachable (at leat in my case). So I added the < style > tag and import the stylsheets as is specified in the ag-grid docs

Here's where magic happened, dynamic imports (as you can see in the video I recomended) avoid to import the component code in the the first load, and import it only when is called, this often useful to optimize page load. So in my first attemp i wrote some this:

<template>
  <section>
      <comAgGridDemo v-if="mostrarGrid " ></comAgGridDemo>
  </section>
</template>

<script lang="ts">
import { Component, Vue } from "nuxt-property-decorator";
// import comAgGridDemo from '~/components/comAgGridDemo.vue'
const comAgGridDemo = () => import('~/components/comAgGridDemo.vue');

@Component({
  components: {
    comAgGridDemo
  }
})
export default class extends Vue {
  mostrarGrid: boolean = false;

  mounted() {
    this.mostrarGrid = true
  }

}
</script>

So comAgGridDemo will be rendered only when mostrarGrid is true, then in mounted hook (because mounted is available in client side) I made mostrarGrid = true. And It's done.

I went a little futher because, i was not happy using mounted hook for this matter, so I wrapped the component comAgGridDemo on a < srr > tag, remove the v-if, and ag-grid remained rendered just fine. So the index.vue file ended up like this:

My index.vue

<template>
  <section>
    <no-ssr>
      <comAgGridDemo ></comAgGridDemo>
    </no-ssr>
  </section>
</template>

<script lang="ts">
import { Component, Vue } from "nuxt-property-decorator";
// import comAgGridDemo from '~/components/comAgGridDemo.vue'
const comAgGridDemo = () => import('~/components/comAgGridDemo.vue');

@Component({
  components: {
    comAgGridDemo
  }
})
export default class extends Vue {

}
</script>

And that's it.

Note that if you. If you use, < no-ssr > tag with regular import, ag-grid will fail. If you use dymamic import without < no-ssr > tag, ag-grid will fail. If you use the "v-if way" no need to use < no-ssr > tag.

Something is weird on the ssr using ag-grid. But this is how managed to solve it. If there's a better solution, please advise.

I've made a github repo: https://github.com/warheartvik/nuxt-ag-grid

Solution 2

Firstly, although would likely not cause this error, the component in your template should be kebab case. <ag-grid-demo/>. From vue docs

The error you are getting is probably an ssr issue, and although you have specified ssr: false in your nuxt.config.js this doesn't always get the point across.

Could you try this:

<template>
  <section class="section">
    Welcome to test page
    <no-ssr>
      <ag-grid-demo></ag-grid-demo>
    </no-ssr>
  </section>
</template>
    
<script>
let AgGridDemo = {}
if (process.browser) {
  AgGridDemo = require('~/components/AgGridDemo')
}
export default {
  components: {
    'ag-grid-demo': AgGridDemo
  }
}
</script>

Also, as an aside, the modern way to import plugins in nuxt.config.js is as follows.

plugins: [
  '~/plugins/plugin-ag-grid.client.js'
  //Note the .client.js This is shorthand for the following which you can also use
  src: { '~/plugins/plugin-ag-grid.js', mode: client }
]

The use of ssr: false will be deprecated in the next major release. See docs

Edit

If this is still causing errors you may need to add the plugin to build-transpile in nuxt.config.js. Like so:

build: {
  ...
  transpile: [
    '/plugins',
  ],
}

This will transpile all your plugins but see how you go. Unfortunately the docs don't give us a lot about this.

If you can't get that to work the old fashioned approach was to add the component to a whitelist like this:

//nuxt.config.js
const nodeExternals = require('webpack-node-externals')

module.exports = {
  /**
   * All other config code
   */
  build: {
    extend(config, ctx) {
      if (ctx.isServer) {
        config.externals = [
          nodeExternals({
            whitelist: [/^@components\\AgGridDemo.vue/] 
            // or however you regex a windows path
          })
        ]
      }
    }
  }
}
Share:
15,030

Related videos on Youtube

nkostic
Author by

nkostic

Software developer based in Calgary. Grew up and graduated in Belgrade Serbia.

Updated on June 04, 2022

Comments

  • nkostic
    nkostic almost 2 years

    Trying to add ag-grid in the nuxt app.

    I followed the steps from https://www.ag-grid.com/vue-getting-started/ and How to use ag-grid in a Nuxt app

    • Added the styles in nuxt.config.js
    • Made a plugin and included in nuxt.config.js
    • Created the component AgGridDemo.vue
    • Including component in page index.vue

    Note: Please do not try to run the snippets since I only used them to share the source I have.

    My nuxt.config.js file

    require('dotenv').config()
    import pkg from './package'
    
    export default {
      mode: 'universal',
    
      /*
       ** Headers of the page
       */
      head: {
        title: pkg.name,
        meta: [
          { charset: 'utf-8' },
          { name: 'viewport', content: 'width=device-width, initial-scale=1' },
          { hid: 'description', name: 'description', content: pkg.description }
        ],
        link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
      },
    
      /*
       ** Customize the progress-bar color
       */
      loading: { color: '#fff' },
    
      /*
       ** Global CSS
       */
      css: [
        { src: '~assets/bulma-modifications.scss', lang: 'scss' },
        { src: 'font-awesome/scss/font-awesome.scss', lang: 'scss' },
        { src: '~/node_modules/ag-grid-community/dist/styles/ag-grid.css',  lang: 'css' },
        { src: '~/node_modules/ag-grid-community/dist/styles/ag-theme-dark.css',  lang: 'css' }
      ],
    
      /*
       ** Plugins to load before mounting the App
       */
      plugins: [
        {
          src: '~/plugins/plugin-ag-grid.js',
          ssr: false
        },
        {
          src: '~plugins/plugin-vue-chartjs.js',
          ssr: false
        }
      ],
    
      /*
       ** Nuxt.js modules
       */
      modules: [
        // Doc: https://axios.nuxtjs.org/usage
        '@nuxtjs/axios',
        // Doc: https://buefy.github.io/#/documentation
        'nuxt-buefy',
        '@nuxtjs/pwa',
        '@nuxtjs/dotenv'
      ],
      /*
       ** Axios module configuration
       */
      axios: {
        // See https://github.com/nuxt-community/axios-module#options
      },
    
      /*
       ** Build configuration
       */
      build: {
        /*
         ** You can extend webpack config here
         */
        extend(config, ctx) {
          config.resolve.alias['vue'] = 'vue/dist/vue.common'
          // Run ESLint on save
          if (ctx.isDev && ctx.isClient) {
            config.module.rules.push({
              enforce: 'pre',
              test: /\.(js|vue)$/,
              loader: 'eslint-loader',
              exclude: /(node_modules)/
            })
          }
          config.node = {
            fs: 'empty'
          }
        }
      },
      env: {
        baseUrl: process.env.BASE_URL || 'http://localhost:3000'
      }
    }

    My Plugin plugin-ag-grid.js:

    import * as agGridEnterpise from 'ag-grid-enterprise/main'
    require('dotenv').config()
    agGridEnterpise.LicenseManager.setLicenseKey([process.env.AG_LICENSE_KEY])

    My Component AgGridDemo.vue:

    <template>
      <ag-grid-vue
        style="width: 500px; height: 500px;"
        class="ag-theme-balham"
        :columnDefs="columnDefs"
        :rowData="rowData"
      ></ag-grid-vue>
    </template>
    <script>
    import { AgGridVue } from 'ag-grid-vue'
    
    export default {
      name: 'AgGridDemo',
      data() {
        return {
          columnDefs: null,
          rowData: null
        }
      },
      components: {
        AgGridVue
      },
      beforeMount() {
        this.columnDefs = [
          { headerName: 'Make', field: 'make' },
          { headerName: 'Model', field: 'model' },
          { headerName: 'Price', field: 'price' }
        ]
    
        this.rowData = [
          { make: 'Toyota', model: 'Celica', price: 35000 },
          { make: 'Ford', model: 'Mondeo', price: 32000 },
          { make: 'Porsche', model: 'Boxter', price: 72000 }
        ]
      }
    }
    </script>

    Finally My Page:

    <template>
      <section class="section">
        Welcome to test page
        <aggriddemo></aggriddemo>
      </section>
    </template>
    <script>
    
    import AgGridDemo from '~/components/AgGridDemo'
    export default {
      name: 'IndexPage',
      components: {
        AgGridDemo
      }
    }
    </script>

    I am getting Error on the Screen but not on my console, console says Compiled successfully but on screen I get:

    SyntaxError Missing

    stack frames

    enter image description here

    Any Ideas on why is this happening and how to fix this ?

  • nkostic
    nkostic almost 5 years
    Thanks for the response Andrew! I think this fixed it. I am not getting Syntax Error anymore now, however few other issues are still preventing me to render ag-grid. Looking into this and will mark your answer as correct as soon as I make sure this fixed it!
  • nkostic
    nkostic almost 5 years
    I am getting now [Vue warn]: Failed to mount component: template or render function not defined. found in ---> <AgGridDemo> If I replace back the line where we have is browser with import AgGridDemo from '~/components/AgGridDemo' and save, grid works when the dev auto reload occurs, but If I reload the page manually cntrl+f5 on pc I get again : Missing Stack Frames.
  • Andrew1325
    Andrew1325 almost 5 years
    @Nesha8x8 I've added an edit that might help. You're not using IE11 by any chance are you?
  • nkostic
    nkostic almost 5 years
    No, testing in chrome and brave (chromium)