所述基于 Vue-Router 0.7 的 Vue 1.0 项目.
Vue-Router
与 Webpack
的 Code-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))
}
}
}
蛤蛤蛤,竟然真的正常了!(=・ω・=)