vue.jswebpackvue-cli

How to include all "vue" files from directory into the build without explicitly importing them


is there a way to build all .vue files in my views/ folder without importing them into my vue application directly? What I want to achieve is a Router with dynamic route definitions which will be filled from a configuration which is a json filled with name, router path and the component name which should be lazy loaded. My issue right now: The application does only build the files which are imported somewhere in my application. What I need: Build all files in views/ as chunk in order to be able to have a dynamic Router definition.

Thank you for your help :)


Solution

  • It's hard to give proper solution without any code provided, but I'll try

    With code like this:

    // route definition loaded from json
    const routeDef = [
      { name: 'about', path: '/about', componentName: 'about' },
      { name: 'profile', path: '/profile', componentName: 'profile' }
    ]
    
    // we can create routes like this
    const routes = routeDef.map(function(def) {
      return {
        name: def.name,
        path: def.path,
        component: () => import('@/views/' + def.componentName + '.vue')
      }
    })
    
    const router = new VueRouter({
      routes: routes
    })
    

    By using import('@/views/' + def.componentName + '.vue') you are telling Webpack I want to import one of the .vue files in the views directory but which one will be known at runtime. So Webpack will bundle all file in that directory and make it available for import at runtime....

    Note that what you pass into import() is really important - part of the argument must always be a static string so Webpack have at least some clue about the directory (import(def.componentName) wont work) - see the docs

    Additional example - loading route definitions from server at runtime

    router.js

    export default createRouter() {
      return axios.get('/getRouteDefinitions').then(function(data) {
        
        const routes = data.routeDef.map(function(def) {
          return {
            name: def.name,
            path: def.path,
            component: () => import('@/views/' + def.componentName + '.vue')
          }
        })
    
        return new VueRouter({
          routes: routes
        })
      })
    }
    

    main.js

    import VueRouter from `VueRouter`
    import createRouter from `router.js`
    
    Vue.use(VueRouter)
    
    createRouter().then(function(router) {
      const app = new Vue({
        router
      })
      app.$mount("#app")
    })