Webpack打包之坑 _ webpackChunkName【魔法注释】

目录

事件起因 

百度查阅

webpackChunkName

结束了


事件起因 

蒽 , 起因是这样的 , 项目从最初的使用 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 入门 ) :

  1. 按需加载。import() 可以在需要的时候,再加载某个模块
  2. 条件加载。import() 可以放在 if 代码块,根据不同的情况,加载不同的模块。
  3. 动态的模块路径。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 可以独立命名,是的就是这样。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值