处理 Vue-Router + Webpack 动态加载的一些小问题

所述基于 Vue-Router 0.7 的 Vue 1.0 项目.

Vue-RouterWebpackCode-Splitting 功能结合起来可以实现组件的动态加载:

router.map({
  '/account-info': {
    component: function (resolve) {
      require(['./views/AccountInfo/index.vue'], resolve)
    }
  },

  '/about': {
      component (resolve) {
        require(['./views/About/index.vue'], resolve)          
      }
  },

  ...
})

只有当访问到两个路由时组件才会被加载进来,节约资源。

不过当项目组件数量偏多的时候手工注册总归不是好办法,不如写成配置动态处理:

// 组件配置信息.
const viewConfig = {
    "account-info": {
        name: "account-info",
        link: "/account-info",
        view: "views/AccountInfo/index.vue"
    },

    "about": {
        name: "about",
        link: "/about",
        view: "views/About/index.vue"
    },

    ...
}

// 路由配置对象, 将交给 Vue-Router 处理.
const routeConfig = {}

viewConfig.forEach(config => {
    routeConfig[config.link] = createRouteConfig(config.name, config.view)
})

routerInstance.map(routeConfig)

/**
 *  创建路由配置对象.
 *
 *  @param { string } name 具名路由名称.
 *  @param { string } view 组件文件所在路径.
 *  @return { object }  
 */
function createRouteConfig (name, view) {
    return {
        name,
        component (resolve) {
            require(['./' + view], resolve)
        }
    }
}

完美的出事了!Σ(゚д゚;)

只生成了一个超大的 JS 分片?!

只生成一个超大的 JS 分片,这不是我们要的嘛!

这时要请出 Webpack 的 bundle-loader,Webpack 的代码分片功能会将所有动态切分的模块打包到一起保证执行正确,而 bundle-loader 会将每一个动态切分的模块打包为独立文件.

因此改一下配置:

function createRouteConfig (name, view) {
    return {
        name,
        component (resolve) {
            // require(['./' + view], resolve)
            const handler = require('bundle!./' + view)
            handler(module => resolve(module))
        }
    }
}

完美地第二次出事!(゚Д゚≡゚д゚)!?

build 时出现 “Module not found: Error: a dependency to an entry point is not allowed” 报错?!

明明 dev 的时候是正确的,build 时就错了?

经过一番尝试,发现手工指定 babel-loader 可以解决问题,那么:

function createRouteConfig (name, view) {
    return {
        name,
        component (resolve) {
            // require(['./' + view], resolve)
            // const handler = require('bundle!./' + view)
            const handler = require('bundle!babel!./' + view)
            handler(module => resolve(module))
        }
    }
}

蛤蛤蛤,正常工作了!

但好像生成的分片文件数量却不得了?!

没多大的项目,竟然生成了快 100 个分片?ヽ(`Д´)ノ

出现这么多问题都是因为动态配置,因此是不是 Webpack 在分析词法的时候捉鸡了?

而且好像 handler 并没有过 vue-loader?(应该不会吧)那么就决定试试将 '.vue' 扩展名写死在代码中:

// 组件配置信息.
const viewConfig = {
    "account-info": {
        name: "account-info",
        link: "/account-info",
        // view: "views/AccountInfo/index.vue"
        view: "views/AccountInfo/index"
    },

    "about": {
        name: "about",
        link: "/about",
        // view: "views/About/index.vue"
        view: "views/About/index"
    },

    ...
}

// 路由配置对象, 将交给 Vue-Router 处理.
const routeConfig = {}

viewConfig.forEach(config => {
    routeConfig[config.link] = createRouteConfig(config.name, config.view)
})

routerInstance.map(routeConfig)

/**
 *  创建路由配置对象.
 *
 *  @param { string } name 具名路由名称.
 *  @param { string } view 组件文件所在路径.
 *  @return { object }  
 */
function createRouteConfig (name, view) {
    return {
        name,
        component (resolve) {
            // require(['./' + view], resolve)
            // const handler = require('bundle!./' + view)
            // const handler = require('bundle!babel!./' + view)
            const handler = require('bundle!babel!./' + view + '.vue')
            handler(module => resolve(module))
        }
    }
}

蛤蛤蛤,竟然真的正常了!(=・ω・=)

你可能感兴趣的:(webpack,vue.js,vue-router)