目录
事件起因
蒽 , 起因是这样的 , 项目从最初的使用 vue-cli 脚手架搭建了一个初始化空架子之后就开始写项目了 ,也就是在刚开始的一段时间里偶尔有过几次打包查看 ,那时候还是能够顺利打包成功的 ,但随着代码越写越多 ,插件越来越多 ,项目也越来越大 ,但反而并没有再去尝试过打包了 ,就这样 ,项目在写到一半的时候 ,突然想起来要打包一下看看咋样 ,结果报错 ,报错 ,还是报错 ,不是说什么 .css 就是什么 .js 的文件提示没有啥的 ,这个问题组内的小伙伴解决了两天时间 ,最后还是在请教了一个大佬帮忙查看后才最终得以解决掉 ,所以这也算是个在项目中所遇到的技术问题难点了吧 ,哈哈 ,那就索性记录一下,也让自己以后好引以为戒啊。
最后呢小伙伴给出的解释就是说 :路由配置文件里面因为引用写了 webpack 的 魔法注释 而导致的打包失败 ,然后我就不是很理解 ,问了一下朋友 ,朋友说他们也用了 魔法注释 , 并没有不能打包的情况啊 , 所以百度了一下这个 webpack 所谓的 魔法注释 ,最后自己又在项目中一点点去调试 => 先是把所有的路由配置里面的 webpack 魔法注释 都删除掉,然后先加上其中一个魔法注释,再去打包,结果顺利打包成功了,并没有报错 ,心想那应该就不是因为写了 魔法注释 的问题吧,随后又给一个路由加上了魔法注释后打包 ,发现也还是成功打包了 ,最后在朋友的提示下,说是 “ chunkname 可以用 * 吗 ? ” ,然后就测试了一下把 ChunkName 起名为 * 号的那个加上后测试再打包就失败了,所以到最后发现影响打包失败的原因并不是人家 webpack 的魔法注释导致的 , 而是 “起名不规范” 的原因啊 。 。
( * 号是不能作为名字来起文件名的 )
好了 , 这下就是找到了打包问题的根本原因所在了 , webpack 的魔法注释 webpackChunkName 并不会影响打包 , 而是起的名字有问题 , 不规范导致的 ,
因为起的名字它好像是打包编译后会变成对应的文件名 , 而既然是文件名了 , 肯定就是不能够以 * 号进行命名滴 !文件或文件夹名以 * 命名 会报错提示你 :
名称 * 作为文件或文件夹名无效。请选择其他名称。
百度查阅
再下面的内容就是自己百度查阅的关于 webpack 魔法注释 的一些东西了 :
使用 Webpack 如何做按需加载
大家都知道 Webpack 是现在流行的前端打包编译工具,通过模块之间的依赖关系,
将代码打包组织到一起。
- webpack2.x 中提供了 import()
要注意的是 import() 函数不同于 import 命令,import 是 ECMAScript 6 Module 的语法,import 是静态执行,这里不多说,可以去看 import 命令。
import(specifier)
上面代码中,import 函数的参数 specifier ,指定所要加载的模块的位置,而且 specifier 可以是一个方法,动态的生成模块路径。import 命令能够接受什么参数,import() 函数就能接受什么参数,两者区别主要是后者为 动态加载 。
import() 函数是 ECMAScript Stage 3 草案阶段的语法;用于完成动态加载即运行时加载,可以用在任何地方。import() 函数 返回的是一个 Promise。类似于 CommonJs 的 require() ,区别主要是前者是 异步加载 ,后者是 同步加载。
import 的应用场景有以下三种 ( 参考自 ECMAScript 6 入门 ) :
- 按需加载。import() 可以在需要的时候,再加载某个模块
- 条件加载。import() 可以放在 if 代码块,根据不同的情况,加载不同的模块。
- 动态的模块路径。import() 允许模块路径动态生成。
用法大致如下:
import('./myModule.js')
.then(myModule => {
console.log(myModule.default);
});
小结
目前我们用的比较多的是 import 来做 按需加载 ,模块路径可以动态生成,更适合现在的应用场景。
如何命名 chunk 的名称
有 /* webpackChunkName: " " */,号称是 Magic Comments(魔术注释法)。
Webpack 通过增加 内联注释 来告诉 运行 时,该有怎样的 行为 。通过向 import 中添加 注释 ,我们可以执行诸如 命名 chunk 或 选择不同模式 之类的 操作。
这里着重讲一下 webpackChunkName ,它其实就是对 chunkFilename 定义时 [name] 值的改写 ,/* webpackChunkName: "hello" */,意味着 [name] 等于 hello 。
于是上面的代码就会按照下面的方式来写,打包 出来的 chunk文件 将会出现在 plugins文件夹下,名字叫 myModule.a2d1d5d8e7d5d4d4d4se.chunk.js 。
import(/* webpackChunkName: "plugins/myModule" */
'./myModule.js')
.then(myModule => {
console.log(myModule.default);
});
更多的 魔术注释 ,请参考 Webpack官方文档 。
webpackChunkName
之前在 vue 的路由配置文件中看到了 /* webpackChunkName:"lodash" */
这个注释
webpackChunkName 有什么用
在学习了 webpack
之后了解其做用,Webpack 通过增加 内联注释 来告诉运行时,该有怎样的行为。通过向 import 中添加注释,我们可以执行诸如 命名 chunk 或 选择不同模式之类的操作。webpack
在打包的时候,对异步引入的库代码(lodash
)进行代码分割时( 需要配置 webpack
的 SplitChunkPlugin
插件 ),为分割后的代码块取得名字
如何命名 chunk 的名称
/* webpackChunkName: "hello" */
,意味着 [name]
等于 hello。
import(/* webpackChunkName: "plugins/myModule" */
'./myModule.js')
.then(myModule => {
console.log(myModule.default);
});
路由懒加载 ( 动态 chunkName )
手写的规格
let router = new Router({
routes: [
{
path:'/login',
name:'login',
component: import(/* webpackChunkName: "login" */
`@/views/login.vue`)
},
{
path:'/index',
name:'index',
component: import(/* webpackChunkName: "index" */
`@/views/index.vue`)
},
{
path:'/detail',
name:'detail',
component: import(/* webpackChunkName: "detail" */
`@/views/detail.vue`)
}
]
})
上面这种写法没问题,但仔细一看它们结构都是相似的,其中唯一不同的就是部分的页面名称而已,作为一名出色的ctrl+c/ctrl+v
开发者,我们要做到可以偷懒的时候就尽量偷懒,我们可以使用 map 循环来解决这种重复性的工作。
const routeOptions = [
{
path:'/login',
name:'login',
},
{
path:'/index',
name:'index',
},
{
path:'/detail',
name:'detail',
},
]
const routes = routeOptions.map(route => {
if (!route.component) {
route = {
...route,
component: () => import(`@/views/${route.name}.vue`)
}
}
return route
})
let router = new Router({
routes
})
在书写更少代码的同时,我们也把“魔法注释”给牺牲掉了。总所周知,代码中没办法编写动态注释。这个问题很尴尬,难道就没有两全其美的办法了吗?
强大的 webpack
来救场了,从 webpack 2.6.0
开始,占位符 [index]
和 [request]
被支持为递增的数字或实际解析的文件名。我们可以这样使用“魔法注释”:
const routes = routeOptions.map(route => {
if (!route.component) {
route = {
...route,
component: () => import(/* webpackChunkName: "[request]" */
`@/views/${route.name}.vue`)
}
}
return route
})
使用 [request]
来告诉 webpack
,这里的值是根据后面传入的字符串来决定,本例中就是变量 route.name
的值
结束了
到此为止,我们已经可以将代码打包到多个文件,每个 chunk 可以独立命名,是的就是这样。