Search code examples
javascriptecmascript-6promisees6-promisearrow-functions

Difference between two promise functions in javascript


So with Vue and Nuxt to import a route lazily you can do

() => import('~/layouts/Container.vue').then(m => m.default || m)

But I don't want to type .then(m => m.default || m) each time I add a route. So I created a function that would do this called routeImport. Route import is really simple. It looks like this:

const routeImport = file => import(file).then(m => m.default || m)

So now I can add my route like

() => routeImport('~/layouts/Container.vue')

But this does not give the same result. The first function returns a component whilst the other one throws the error:

Error: Cannot find module '~/layouts/Container.vue'

Does anybody know how I can replace this function?


Solution

  • Sounds like the issue is that you are using a fully dynamic variable as the query string for your import() function, which webpack cannot statically analyze, so it isn't including the desired module in your bundle.

    You might want to consider giving webpack a hint as to what you are loading. For example:

    const layoutImport = layout => import(`~/layouts/${layout}.vue`).then(m => m.default || m)
    

    Or:

    const routeImport = file =>
      import(
        /* webpackInclude: /layouts/(Container|OtherView|Etc).vue$/ */
        file
      ).then(m => m.default || m)
    

    This will cause webpack to include all layouts in your bundle (or the specific layouts included in your regex) but still allow you dynamically import them. Note that import() is treated as a split point, so while the files are included in your bundle, they'll typically be grouped into a separate "chunk".

    You can control some aspects of the chunk (such as its name) with magic comments. If you want to group layouts into different chunks, then you may need more than one import function:

    const groupAImport = file =>
      import(
        /* webpackInclude: /layouts/(Container1|Container2).vue$/ */
        file
      ).then(m => m.default || m)
    
    const groupBImport = file =>
      import(
        /* webpackInclude: /layouts/(Container1|Container3|Etc).vue$/ */
        file
      ).then(m => m.default || m)