Search code examples
vue.jsvue-componentnuxt.jsvue-dynamic-components

Component dynamic import doesn't work from router.js


With Nuxt.js, in my router.js I'm trying to import my route component thus:

{
  path: '/',
  component: () => import(/* webpackChunkName: "index" */ '~/pages/index.vue')
}

I get this error:

render function or template not defined in component: anonymous

I came across someone else's Nuxt.js project where they add the following at the end, and with this it works:

{
  path: '/',
  component: () => import(/* webpackChunkName: "index" */ '~/pages/index.vue').then(m => m.default || m)
}

The returned object of my import() looks like this:

enter image description here

In a another Vue.js, non-Nuxt project, the same kind of import() looks like that:

enter image description here

In both cases, the component is nested in some "default" object. But with Nuxt.js it seems you must import that object explicitly, whereas with regular Vue.js you don't have to specify that.

Why?


Solution

  • Regarding why the module is nested inside a { default } object: it's because Nuxt uses ES6 style modules. ES6 style modules are written the following:

    export default {
      // some object
    };
    

    Default is not the only property you can have. More syntax.

    Regarding why vue-router are working without the .default, it's because the code is more versatile than the code used by Nuxt. Nuxt already ships it's own builder and always uses ES6 modules.

    On the other hand, vue-router does not know about how it will be built. So to be easier to use, vue-router automatically checks if the module is ES6 or not.

    const resolve = once(resolvedDef => {
      if (isESModule(resolvedDef)) {
        resolvedDef = resolvedDef.default
      }
      // ...
    }
    

    Source: code of vue-router.

    As you may already know, it's very uncommon to use a router.js file in a Nuxt project, because Nuxt already has its own routing system which splits your code into chunks for each page. Documentation here.