vue饿了么实战视频吗实战问题

在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
在vue实战练习中 ; 跟到购物车点击弹出已购买的商品数据蒙层时 ; 操作蒙层内的+- ; 蒙层也跟着消失了
&template&
&div class="shopcart"&
&div class="content" @click="toggleList"&
&!-- 内容左 --&
&div class="content-left"&
&!-- 内容右 --&
&div class="content-right"&
&!-- 小球的容器 --&
&div class="ball-container"&
&!-- 点击购物车弹出浮层 --&
&transition name="fold"&
&div class="shopcart-list" v-show="listShow"&
&div class="list-header"&
&h1 class="title"&购物车&/h1&
&span class="empty"&清空&/span&
&div class="list-content" ref="listContent"&
&li class="food" v-for="food in selectFoods"&
&span class="name"&{{food.name}}&/span&
&div class="price"&
&span&¥{{food.price*food.count}}&/span&
&div class="cartcontrol-wrapper"&
&cartcontrol :food="food"&&/cartcontrol&
&/transition&
&/template&
&script type="text/ecmascript-6"&
import BScroll from 'better-scroll';
import cartcontrol from '../cartcontrol/cartcontrol';
export default {
selectFoods: {
type: Array,
default() {
return [];
deliveryPrice: {
type: Number,
default: 0
minPrice: {
type: Number,
default: 0
{ show: false },
{ show: false },
{ show: false },
{ show: false },
{ show: false }
dropBalls: [],
fold: true
computed: {
// 数量计算
totalCount() {
let count = 0;
this.selectFoods.forEach((food) =& {
count += food.
// 计算购物车点击弹层显示属性
listShow() {
if (!this.totalCount) {
this.fold =
let show = !this.
if (show) {
this.$nextTick(() =& {
if (!this.scroll) {
this.scroll = new BScroll(this.$refs.listContent, {
click: true
this.scroll.refresh();
methods: {
// 控制购物车弹层是否显示
toggleList() {
if (!this.totalCount) {
this.fold = !this.
components: {
cartcontrol
&style lang="stylus" rel="stylesheet/stylus"&
@import '../../common/stylus/mixin';
.shopcart {
bottom: 0;
z-index: 50;
width: 100%;
height: 48
.content {
background: #141d27;
color: rgba(255, 255, 255, 0.4);
.content-left {
font-size: 0;
.logo-wrapper {
display: inline-
margin: 0 12
padding: 6
height: 56
box-sizing: border-
vertical-align:
border-radius: 50%;
background: #141d27;
width: 100%;
height: 100%;
border-radius: 50%;
background: #2b343c;
text-align:
&.highlight {
background: rgb(0, 160, 220);
.icon-shopping_cart {
line-height: 44
font-size: 24
color: #80858a;
&.highlight {
height: 16
line-height: 16
text-align:
border-radius: 16
font-size: 9
font-weight: 700;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4);
background: rgb(249, 20, 20);
display: inline-
vertical-align:
line-height: 24
margin-top: 12
padding-right: 12
border-right: 1px solid rgba(255, 255, 255, 0.1);
box-sizing: border-
font-size: 16
font-weight: 700;
&.highlight {
display: inline-
margin: 12px 0 0 12
vertical-align:
line-height: 24
font-size: 10
.content-right {
flex: 0 0 105
width: 105
height: 48
line-height: 48
text-align:
font-size: 12
font-weight: 700;
background: #2b333b;
&.not-enough {
background: #2b333b;
&.enough {
background: #00b43c;
.ball-container {
bottom: 22
z-index: 200;
transition: all 0.4s cubic-bezier(0.49, -0.29, 0.75, 0.41);
height: 16
border-radius: 50%;
background: rgb(0, 160, 220);
transition: all 0.4
.shopcart-list {
z-index: -1;
width: 100%;
transform: translate3d(0, -100%, 0);
&.fold-enter-active, &.fold-leave-active {
transition: all 0.5s;
&.fold-enter, &.fold-leave-active {
transform: translate3d(0, 0, 0);
.list-header {
height: 40
line-height: 40
padding: 0 18
background: #f3f5f7;
border-bottom: 1px solid rgba(7, 17, 27, 0.1);
font-size: 14
color: rgb(7, 17, 27);
font-size: 12
color: rgb(0, 160, 220);
.list-content {
padding: 0 18
max-height: 217
background: #
padding: 12px 0;
box-sizing: border-
border-1px(rgba(7, 17, 27, 0.1));
line-height: 24
font-size: 14
color: rgb(7, 17, 27);
bottom: 12
line-height: 24
font-weight: 700;
font-size: 14
color: rgb(240, 20, 20);
.cartcontrol-wrapper {
第三行'toggleList'为点击事件 绑定在了整个组件上 ; 当购物车被点击时 ; 蒙层显示 ; 点击蒙层内元素时 ; 蒙层跟着消失了
点击蒙层内元素 ;不想让蒙层消失 ; 试了@click.stop没有效果
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
层级出现了问题~
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
你蒙层是不是也添加事件了?
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:主题帖子积分
QQ截图41.png (226.58 KB, 下载次数: 3)
16:11 上传
vue.js 是 2016 最火的前端框架,资深程序员这样评价它:“vue.js 兼具 angular.js 和 react.js 的优点,并剔除它们的缺点”
慕课网收费课程,链接:
QQ截图20.png (55.99 KB, 下载次数: 1)
16:14 上传
课程截图:
QQ截图10.png (262.92 KB, 下载次数: 2)
16:15 上传
QQ截图58.png (340.09 KB, 下载次数: 1)
16:17 上传
声明:此资源由微夏博客收集整理于网络,如有侵权,请联微夏博客[Q:]删除处理。
此资源在网络中能找到,但是在第9章后都是被加密的,微夏博客分享的这份资源是已解密版的,可能解密后的视频有些不清楚。
下载地址:
版权原因,不再分享!请支持正版!
主题帖子积分
正式会员, 积分 5, 距离下一级还需 45 积分
正式会员, 积分 5, 距离下一级还需 45 积分
支持楼主!支持微夏论坛!
主题帖子积分
初级会员, 积分 91, 距离下一级还需 9 积分
初级会员, 积分 91, 距离下一级还需 9 积分
谢谢楼主的无私奉献!!!!!!
主题帖子积分
中级会员, 积分 191, 距离下一级还需 9 积分
中级会员, 积分 191, 距离下一级还需 9 积分
谢谢楼主的无私奉献!!!!!!
主题帖子积分
正式会员, 积分 15, 距离下一级还需 35 积分
正式会员, 积分 15, 距离下一级还需 35 积分
谢谢楼主的无私奉献!!!!!!
主题帖子积分
初级会员, 积分 93, 距离下一级还需 7 积分
初级会员, 积分 93, 距离下一级还需 7 积分
谢谢楼主的无私奉献!!!!!!
主题帖子积分
正式会员, 积分 37, 距离下一级还需 13 积分
正式会员, 积分 37, 距离下一级还需 13 积分
确实是难得好帖啊,顶先
主题帖子积分
中级会员, 积分 142, 距离下一级还需 58 积分
中级会员, 积分 142, 距离下一级还需 58 积分
谢谢楼主的无私奉献!!!!!!
主题帖子积分
初级会员, 积分 85, 距离下一级还需 15 积分
初级会员, 积分 85, 距离下一级还需 15 积分
谢谢楼主的无私奉献!!!!!!
主题帖子积分
初级会员, 积分 70, 距离下一级还需 30 积分
初级会员, 积分 70, 距离下一级还需 30 积分
厉害了 下载咯用vue2 +vue-router2 + es6 +webpack 高仿饿了么app(干货满满) - CNode技术社区
这家伙很懒,什么个性签名都没有留下。
本项目是基于vue2最新实战项目,vue2 +vue-router2 + es6 +webpack 高仿饿了么app,是适合新手进阶的绝佳教程。
喜欢的请点心,关注,star ,fork,这些是我坚持下去的动力
(请用chrome的手机模式预览)
*本项目地址
我的另外一个vue开源项目
用了vuex,和其他比较火的包,才刚刚上传,代码更加简单,设计更加简洁,注释更加多!喜欢vue的朋友赶紧去看看。
手机扫一扫
项目技术架构
vue-resource
vue-router
vue-infinite-scroll
加入购物车动画
弹出购物车 商品详情页
分类切换 图片左右滑动
项目地址:(git clone)
git clone https:/&#/liangxiaojuan/eleme.git
通过npm安装本地服务第三方依赖模块(需要已安装)
npm install
启动服务()
npm run dev
npm run build
安装 vue-cli
npm install -g vue-cli
安装 vue-cli eslint
npm install -g eslint
安装依赖 friendly-errors-webpack-plugin
npm install friendly-errors-webpack-plugin --save-dev
###目录结构
├── build
// 构建服务和webpack配置
├── config
// 项目不同环境的配置
├── dist
// 项目build目录
├── index.html
// 项目入口文件
├── package.json
// 项目配置文件
├── src
// 生产目录
├── assets
// 图片资源
├── common
// 公共的css js 资源
├── components
// 各种组件
├── App.vue
└── main.js
// Webpack 预编译入口
###实现的功能
商品滚动 ,商品滚轮滚动
加入购物车,移除购物车
显示评论 评论筛选
图片左右滑动
父子组件的通信
正在实现的功能
更多更精彩的内容
我的另外一个vue开源项目
用了vuex,和其他比较火的包,才刚刚上传,代码更加简单,设计更加简洁,注释更加多!喜欢vue的朋友赶紧去看看。
如果喜欢一定要 star哈!!!(谢谢!!)
如果有意见和问题 请在 lssues提出,我会在线解答。
顶 我记得 饿了么有个 mint-ui 也有2.0的版本,我也不太习惯在项目里引入vuex,感觉,完成一个请求绕来绕去,很麻烦
上面github地址错了,正确的是地址是:
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的[!!! 原版课程在此]Vue.js 高仿饿了么外卖 App 课程源码a year ago赞赏2 人赞赏75收藏分享举报文章被以下专栏收录每周一期,为你带来最干的前端技术文章推荐阅读{&debug&:false,&apiRoot&:&&,&paySDK&:&https:\u002F\\u002Fapi\u002Fjs&,&wechatConfigAPI&:&\u002Fapi\u002Fwechat\u002Fjssdkconfig&,&name&:&production&,&instance&:&column&,&tokens&:{&X-XSRF-TOKEN&:null,&X-UDID&:null,&Authorization&:&oauth c3cef7c66aa9e6a1e3160e20&}}{&database&:{&Post&:{&&:{&isPending&:false,&contributes&:[{&sourceColumn&:{&lastUpdated&:,&description&:&来自滴滴前端团队的周刊&,&permission&:&COLUMN_PUBLIC&,&memberId&:,&contributePermission&:&COLUMN_PUBLIC&,&translatedCommentPermission&:&all&,&canManage&:true,&intro&:&每周一期,为你带来最干的前端技术文章&,&urlToken&:&ddfe-weekly&,&id&:22906,&imagePath&:&v2-b530c79b70cc82bd1c443ae.jpg&,&slug&:&ddfe-weekly&,&applyReason&:&0&,&name&:&DDFE 技术周刊&,&title&:&DDFE 技术周刊&,&url&:&https:\u002F\\u002Fddfe-weekly&,&commentPermission&:&COLUMN_ALL_CAN_COMMENT&,&canPost&:true,&created&:,&state&:&COLUMN_NORMAL&,&followers&:2754,&avatar&:{&id&:&v2-b530c79b70cc82bd1c443ae&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&activateAuthorRequested&:false,&following&:false,&imageUrl&:&https:\u002F\\u002Fv2-b530c79b70cc82bd1c443ae_l.jpg&,&articlesCount&:43},&state&:&accepted&,&targetPost&:{&titleImage&:&https:\u002F\\u002Fv2-d5a721a128cb352cf20eadcc7ff7108f_r.jpg&,&lastUpdated&:,&imagePath&:&v2-d5a721a128cb352cf20eadcc7ff7108f.jpg&,&permission&:&ARTICLE_PUBLIC&,&topics&:[159435],&summary&:&&,&copyPermission&:&ARTICLE_COPYABLE&,&translatedCommentPermission&:&all&,&likes&:0,&origAuthorId&:0,&publishedTime&:&T11:02:16+08:00&,&sourceUrl&:&&,&urlToken&:,&id&:2076679,&withContent&:false,&slug&:,&bigTitleImage&:false,&title&:&[!!! 原版课程在此]Vue.js 高仿饿了么外卖 App 课程源码&,&url&:&\u002Fp\u002F&,&commentPermission&:&ARTICLE_ALL_CAN_COMMENT&,&snapshotUrl&:&&,&created&:,&comments&:0,&columnId&:22906,&content&:&&,&parentId&:0,&state&:&ARTICLE_PUBLISHED&,&imageUrl&:&https:\u002F\\u002Fv2-d5a721a128cb352cf20eadcc7ff7108f_r.jpg&,&author&:{&bio&:&前端架构师&,&isFollowing&:false,&hash&:&7ca07f92642&,&uid&:922700,&isOrg&:false,&slug&:&ddfe&,&isFollowed&:false,&description&:&我们是 DDFE 前端技术团队,负责滴滴出行公共前端技术方向,目前已出版《Vue.js权威指南》等著作。我们热爱技术,喜欢分享,希望对前端技术发展贡献绵薄之力。&,&name&:&DDFE&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fddfe&,&avatar&:{&id&:&v2-29fdf7c4d03&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&memberId&:,&excerptTitle&:&&,&voteType&:&ARTICLE_VOTE_CLEAR&},&id&:514852}],&title&:&[!!! 原版课程在此]Vue.js 高仿饿了么外卖 App 课程源码&,&author&:&ddfe&,&content&:&由 DDFE 的黄轶带来的原创课程在慕课网关注颇高,使用 Vue.js+es6+webpack 等前端最新最热的技术,采用组件化、模块化的开发方式,让你用更少的代码做更快速的开发,我们把源码分享出来供大家阅读。欢迎收藏,谢绝转载!!!\u003Cp\u003E源码地址:\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fustbhuangyi\u002Fvue-sell\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003Eustbhuangyi\u002Fvue-sell\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E&,&updated&:new Date(&T03:02:16.000Z&),&canComment&:false,&commentPermission&:&anyone&,&commentCount&:28,&collapsedCount&:0,&likeCount&:75,&state&:&published&,&isLiked&:false,&slug&:&&,&lastestTipjarors&:[{&isFollowed&:false,&name&:&咫尺天涯&,&headline&:&&,&avatarUrl&:&https:\u002F\\u002Fda8e974dc_s.jpg&,&isFollowing&:false,&type&:&people&,&slug&:&zhi-chi-tian-ya-57-73&,&bio&:&前端开发\u002F知乎是我见过最垃圾的APP&,&hash&:&2c4a28fa68fbd0e6849eb&,&uid&:013000,&isOrg&:false,&description&:&&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fzhi-chi-tian-ya-57-73&,&avatar&:{&id&:&da8e974dc&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&isFollowed&:false,&name&:&Reckless&,&headline&:&猫奴,家有主子一只&,&avatarUrl&:&https:\u002F\\u002F50\u002Fv2-2ba1e67ff8ee_s.jpg&,&isFollowing&:false,&type&:&people&,&slug&:&li-mu-zi-55-79&,&bio&:&一只安静的小猿猿&,&hash&:&c5cdad0cca1a87e1cef905&,&uid&:989900,&isOrg&:false,&description&:&猫奴,家有主子一只&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fli-mu-zi-55-79&,&avatar&:{&id&:&v2-2ba1e67ff8ee&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}],&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\\u002Fv2-d5a721a128cb352cf20eadcc7ff7108f_r.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&reviewers&:[],&topics&:[{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&Vue.js&}],&adminClosedComment&:false,&titleImageSize&:{&width&:1920,&height&:499},&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&column&:{&slug&:&ddfe-weekly&,&name&:&DDFE 技术周刊&},&tipjarState&:&activated&,&tipjarTagLine&:&真诚赞赏,手留余香&,&sourceUrl&:&&,&pageCommentsCount&:28,&tipjarorCount&:2,&annotationAction&:[],&hasPublishingDraft&:false,&snapshotUrl&:&&,&publishedTime&:&T11:02:16+08:00&,&url&:&\u002Fp\u002F&,&lastestLikers&:[{&bio&:&前端&,&isFollowing&:false,&hash&:&a12134bbab17ab5a402cb11a0e59c8d6&,&uid&:258000,&isOrg&:false,&slug&:&mi-fan-79-34&,&isFollowed&:false,&description&:&&,&name&:&米饭&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fmi-fan-79-34&,&avatar&:{&id&:&da8e974dc&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&挨踢渣,厚着脸关注认知神经科学...&,&isFollowing&:false,&hash&:&ac9d1f3eea14b9b3ba76a290eee5af61&,&uid&:36,&isOrg&:false,&slug&:&yi-feng-fly&,&isFollowed&:false,&description&:&INTP(但不太信);自从了解了神经学,整个人神经多啦~ (?o??o?) ?\n民科时间:\n1、挨踢+量子计算+神经科学+混沌=?希望有生之年能够看到...但是不希望被这样的世界洗礼....\n2、量子力学(不确定原理)+ 混沌(非线性) 排除:决定论(确定性+线性 的猜想);\n3、认知神经科学 + 量子力学 + 混沌:排除自由意志(Free Will)、二元论。\n我还有救吗?\n\n还记得当时的知乎吗?\n欢迎你来到知乎。 这是一个能真正体现你价值的地方。\n我们相信,娱乐至上的中国互联网,需要一个与众不同的新世界。\n在这里,认真、求知、信任与相互尊重,比肤浅的趣味更有意义;\n在这里,真正有价值的信息是绝对的稀缺品,远未得到有效的挖掘和利用;\n在这里,人与人之间,可以通过言之有物的分享,建立起真诚而友善的关系。\n建立这个新世界并不容易,但你会发现,这也不难,只需要你和我们一样:\n认真、专业:言之有物,不灌水,为自己的话负责\n友善、互助:感谢每一个用心的回答,同时尊重与你观点不同的人\n独一无二的你,总有见解值得分享;世界那么大,也有等待着你的未知。\n欢迎你加入我们,一起创造知乎,发现更大的世界。&,&name&:&翼·风&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fyi-feng-fly&,&avatar&:{&id&:&v2-c8f8ac7cb3fc1a931f5b&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&前端工程师&,&isFollowing&:false,&hash&:&af8d4c8c3e&,&uid&:125400,&isOrg&:false,&slug&:&wangshuxian6&,&isFollowed&:false,&description&:&&,&name&:&王树贤&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fwangshuxian6&,&avatar&:{&id&:&v2-53ce24dd211fb59113f6c&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&前端小白&,&isFollowing&:false,&hash&:&aefc66b15ae85b8fc3e486ce90a4e7d7&,&uid&:592800,&isOrg&:false,&slug&:&chen-cong-8-4&,&isFollowed&:false,&description&:&&,&name&:&红眼嫉世&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fchen-cong-8-4&,&avatar&:{&id&:&v2-d4ece4fabe6fe6fcd60b0d0&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:& &,&isFollowing&:false,&hash&:&da37fabb7367&,&uid&:48,&isOrg&:false,&slug&:&chen-gou-wan&,&isFollowed&:false,&description&:&&,&name&:&陈勾丸&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fchen-gou-wan&,&avatar&:{&id&:&411c783e6&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}],&summary&:&&,&reviewingCommentsCount&:0,&meta&:{&previous&:{&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&topics&:[{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&前端工程化&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&webpack&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&源码阅读&}],&adminClosedComment&:false,&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&author&:{&bio&:&前端架构师&,&isFollowing&:false,&hash&:&7ca07f92642&,&uid&:922700,&isOrg&:false,&slug&:&ddfe&,&isFollowed&:false,&description&:&我们是 DDFE 前端技术团队,负责滴滴出行公共前端技术方向,目前已出版《Vue.js权威指南》等著作。我们热爱技术,喜欢分享,希望对前端技术发展贡献绵薄之力。&,&name&:&DDFE&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fddfe&,&avatar&:{&id&:&v2-29fdf7c4d03&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&column&:{&slug&:&ddfe-weekly&,&name&:&DDFE 技术周刊&},&content&:&\u003Cblockquote\u003E作者:滴滴前端公共团队——钟宇飞\u003Cbr\u003E个人知乎链接:\u003Ca href=\&https:\u002F\\u002Fpeople\u002Fzhong-yu-fei-86\u002Fanswers\& class=\&internal\&\u003E水乙 - 知乎\u003C\u002Fa\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E我们在使用 webpack 的时候可以通过 webpack 这个命令配合一些参数来执行我们打包编译的任务。我们想探究它的源码,从这个命令入手能够比较容易让我们了解整个代码的运行过程。那么在执行这个命令的时候究竟发生了什么呢?\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cblockquote\u003E\u003Cp\u003E注:本文中的 webpack 源码版本为1.13.3。本文中的源码分析主要关注的是代码的整体流程,因此一些我认为不是很重要的细节都会省略,以使得读者不要陷入到细节中而 get 不到整体。按照官方文档,webpack.config.js 会通过 module.exports 暴露一个对象,下文中我们统一把这个对象称为 webpack 编译对象(Webpack compiler object)。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Ch2\u003EStep1:执行脚本 bin\u002Fwebpack.js\u003C\u002Fh2\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F bin\u002Fwebpack.js\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 引入 nodejs 的 path 模块\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Epath\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&path\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 获取 \u002Fbin\u002Fwebpack.js 的绝对路径\u003C\u002Fspan\u003E\n\u003Cspan class=\&k\&\u003Etry\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003ElocalWebpack\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eresolve\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Epath\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ejoin\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eprocess\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ecwd\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(),\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&node_modules\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&webpack\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&bin\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&webpack.js\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E))\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003E__filename\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E!==\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003ElocalWebpack\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{}\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Ecatch\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ee\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{}\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 引入第三方命令行解析库 optimist\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 解析 webpack 指令后面追加的与输出显示相关的参数(Display options)\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptimist\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&optimist\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E).\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eusage\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(((\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&webpack \&\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E+\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&..\u002Fpackage.json\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E).\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eversion\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E+\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&\\n\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E+\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&Usage: https:\u002F\u002Fwebpack.github.io\u002Fdocs\u002Fcli.html\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&.\u002Fconfig-optimist\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptimist\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Eoptimist\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&kr\&\u003Eboolean\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&json\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E).\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ealias\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&json\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&j\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E).\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Edescribe\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&json\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&kr\&\u003Eboolean\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&colors\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E).\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ealias\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&colors\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&c\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)...\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 获取解析后的参数并转换格式\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eargv\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptimist\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eargv\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&.\u002Fconvert-argv\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptimist\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eargv\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 判断是否符合 argv 里的参数,并执行该参数的回调\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EifArg\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ename\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Efn\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Einit\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 处理输出相关(output)的配置参数,并执行编译函数\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EprocessOptions\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 执行\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003EprocessOptions\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cblockquote\u003E\u003Cp\u003E\u003Cstrong\u003E小结1.1\u003C\u002Fstrong\u003E:从上面的分析中我们可以比较清晰地看到执行 webpack 命令时会做什么处理,主要就是解析命令行参数以及执行编译。其中 processOptions 这个函数是整个 \u002Fbin\u002Fwebpack.js 里的核心函数。下面我们来仔细看一下这个函数:\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EprocessOptions\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n \u003Cspan class=\&c1\&\u003E\u002F\u002F 支持 Promise 风格的异步回调\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E((\u003C\u002Fspan\u003E\u003Cspan class=\&k\&\u003Etypeof\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ethen\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E===\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&function\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n\n \u003Cspan class=\&c1\&\u003E\u002F\u002F 处理传入一个 webpack 编译对象是数组时的情况\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EfirstOptions\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nb\&\u003EArray\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EisArray\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E))\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E?\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\&mi\&\u003E0\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E]\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n \u003Cspan class=\&c1\&\u003E\u002F\u002F 设置输出 options\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EoutputOptions\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nb\&\u003EObject\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ecreate\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E((\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Estats\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E||\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EfirstOptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Estats\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E||\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E({}));\u003C\u002Fspan\u003E\n\n \u003Cspan class=\&c1\&\u003E\u002F\u002F 设置输出的上下文 context\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E((\u003C\u002Fspan\u003E\u003Cspan class=\&k\&\u003Etypeof\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EoutputOptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Econtext\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E===\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&undefined\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EoutputOptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Econtext\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EfirstOptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Econtext\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F 处理各种显示相关的参数,从略\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003EifArg\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&json\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \n
\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ebool\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E){...}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E...\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F 引入主入口模块 lib\u002Fwebpack.js\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ewebpack\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&..\u002Flib\u002Fwebpack.js\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F 设置错误堆栈追踪上限\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nb\&\u003EError\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EstackTraceLimit\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&mi\&\u003E30\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003ElastHash\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Enull\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n \u003Cspan class=\&c1\&\u003E\u002F\u002F 执行编译\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ewebpack\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n \u003Cspan class=\&c1\&\u003E\u002F\u002F 编译结束后的回调函数\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EcompilerCallback\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eerr\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Estats\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n\n \u003Cspan class=\&c1\&\u003E\u002F\u002F 是否在编译完成后继续 watch 文件变更\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ewatch\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eelse\u003C\u002Fspan\u003E \n \u003Cspan class=\&c1\&\u003E\u002F\u002F 执行编译后的回调函数\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Erun\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EcompilerCallback\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cblockquote\u003E\u003Cp\u003E\u003Cstrong\u003E小结1.2\u003C\u002Fstrong\u003E:从 processOptions 中我们看到,最核心的编译一步,是使用的入口模块 lib\u002Fwebpack.js 暴露处理的方法,所以我们的数据流接下来要从 bin\u002Fwebpack.js 来到 lib\u002Fwebpack.js 了,接下来我们看看 lib\u002Fwebpack.js 里将会发生什么。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Ch2\u003Estep2:执行 lib\u002Fwebpack.js 中的方法开始编译\u003C\u002Fh2\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F lib\u002Fwebpack.js\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 引入 Compiler 模块\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003ECompiler\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&.\u002FCompiler\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 引入 MultiCompiler 模块,处理多个 webpack 配置文件的情况\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EMultiCompiler\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&.\u002FMultiCompiler\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 引入 node 环境插件\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003ENodeEnvironmentPlugin\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&.\u002Fnode\u002FNodeEnvironmentPlugin\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 引入 WebpackOptionsApply 模块,应用 webpack 配置文件\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EWebpackOptionsApply\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&.\u002FWebpackOptionsApply\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 引入 WebpackOptionsDefaulter 模块,应用 webpack 默认配置\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EWebpackOptionsDefaulter\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&.\u002FWebpackOptionsDefaulter\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 核心函数,也是 .\u002Fbin\u002Fwebpack.js 中引用的核心方法\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ewebpack\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ecallback\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Eexports\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Emodule\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eexports\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ewebpack\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 在 webpack 对象上设置一些常用属性\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Ewebpack\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EWebpackOptionsDefaulter\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EWebpackOptionsDefaulter\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Ewebpack\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EWebpackOptionsApply\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EWebpackOptionsApply\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Ewebpack\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003ECompiler\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003ECompiler\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Ewebpack\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EMultiCompiler\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EMultiCompiler\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Ewebpack\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003ENodeEnvironmentPlugin\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003ENodeEnvironmentPlugin\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 暴露一些插件\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EexportPlugins\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eexports\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Epath\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eplugins\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003EexportPlugins\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eexports\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&.\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&DefinePlugin\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&NormalModuleReplacementPlugin\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E...])\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cblockquote\u003E\u003Cp\u003E\u003Cstrong\u003E小结2.1\u003C\u002Fstrong\u003E:lib\u002Fwebpack.js 文件里的代码比较清晰,核心函数就是我们期待已久的 webpack,我们在 webpack.config.js 里面引入的 webpack 模块就是这个文件,下面我们再来仔细看看这个函数。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ewebpack\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ecallback\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nb\&\u003EArray\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EisArray\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E))\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F 如果传入了数组类型的 webpack 编译对象,则实例化一个 MultiCompiler 来处理\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Enew\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EMultiCompiler\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Emap\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ewebpack\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E \u003Cspan class=\&c1\&\u003E\u002F\u002F 递归调用 webpack 函数\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}))\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Eelse\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E((\u003C\u002Fspan\u003E\u003Cspan class=\&k\&\u003Etypeof\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E===\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&object\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F 如果传入了一个对象类型的 webpack 编译对象\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F 实例化一个 WebpackOptionsDefaulter 来处理默认配置项\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Enew\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EWebpackOptionsDefaulter\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E().\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eprocess\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F 实例化一个 Compiler,Compiler 会继承一个 Tapable 插件框架\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F Compiler 实例化后会继承到 apply、plugin 等调用和绑定插件的方法\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Enew\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003ECompiler\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E()\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F 实例化一个 WebpackOptionsApply 来编译处理 webpack 编译对象\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E \u003Cspan class=\&c1\&\u003E\u002F\u002F 疑惑:为何两次赋值 compiler.options?\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Enew\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EWebpackOptionsApply\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E().\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eprocess\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F 应用 node 环境插件\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Enew\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003ENodeEnvironmentPlugin\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E().\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eapply\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EapplyPlugins\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&environment\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EapplyPlugins\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&after-environment\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Eelse\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&c1\&\u003E\u002F\u002F 抛出错误\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Ethrow\u003C\u002Fspan\u003E \u003Cspan class=\&k\&\u003Enew\u003C\u002Fspan\u003E \u003Cspan class=\&nb\&\u003EError\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&Invalid argument: options\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cblockquote\u003E\u003Cp\u003E\u003Cstrong\u003E小结2.2\u003C\u002Fstrong\u003E:webpack 函数里面有两个地方值得关注一下。\u003C\u002Fp\u003E\u003Cp\u003E一是 Compiler,实例化它会继承 \u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fwebpack\u002Ftapable\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ETapable\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E ,这个 Tapable 是一个插件框架,通过继承它的一系列方法来实现注册和调用插件,我们可以看到在 webpack 的源码中,存在大量的 compiler.apply、compiler.applyPlugins、compiler.plugin 等Tapable方法的调用。Webpack 的 \u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\u002Fwebpack.github.io\u002Fdocs\u002Fplugins.html\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003Eplugin\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E 注册和调用方式,都是源自 Tapable 。Webpack 通过 plugin 的 apply 方法安装该 plugin,同时传入一个 webpack 编译对象(Webpack compiler object)。\u003C\u002Fp\u003E\u003Cp\u003E二是 WebpackOptionsApply 的实例方法 process (options, compiler),这个方法将会针对我们传进去的webpack 编译对象进行逐一编译,接下来我们再来仔细看看这个模块。\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Ch2\u003Estep3:调用 lib\u002FWebpackOptionsApply.js 模块的 process 方法来逐一编译 webpack 编译对象的各项。\u003C\u002Fh2\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F lib\u002FWebpackOptionsApply.js\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F ...此处省略一堆依赖引入\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 创建构造器函数 WebpackOptionsApply\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EWebpackOptionsApply\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E()\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003EOptionsApply\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ecall\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&k\&\u003Ethis\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 将构造器暴露\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Emodule\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eexports\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EWebpackOptionsApply\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 修改构造器的原型属性指向\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003EWebpackOptionsApply\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eprototype\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nb\&\u003EObject\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ecreate\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EOptionsApply\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eprototype\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 创建 WebpackOptionsApply 的实例方法 process\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003EWebpackOptionsApply\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eprototype\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eprocess\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n \u003Cspan class=\&c1\&\u003E\u002F\u002F 处理 context 属性,根目录\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Econtext\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Econtext\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n \u003Cspan class=\&c1\&\u003E\u002F\u002F 处理 plugins 属性\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eplugins\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E&&\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nb\&\u003EArray\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EisArray\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eplugins\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)))\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 缓存输入输出的目录地址等\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EoutputPath\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoutput\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Epath\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003ErecordsInputPath\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003ErecordsInputPath\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E||\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003ErecordsPath\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003ErecordsOutputPath\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003ErecordsOutputPath\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E||\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003ErecordsPath\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Ecompiler\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ename\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ename\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 处理 target 属性,该属性决定包 (bundle) 应该运行的环境\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E((\u003C\u002Fspan\u003E\u003Cspan class=\&k\&\u003Etypeof\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Etarget\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E===\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&string\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eelse\u003C\u002Fspan\u003E
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Etarget\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E!==\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Efalse\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eelse\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n \u003Cspan class=\&c1\&\u003E\u002F\u002F 处理 output.library 属性,该属性决定导出库 (exported library) 的名称\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoutput\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Elibrary\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E||\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoutput\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003ElibraryTarget\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E!==\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&var\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E))\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n \u003Cspan class=\&c1\&\u003E\u002F\u002F 处理 externals 属性,告诉 webpack 不要遵循\u002F打包这些模块,而是在运行时从环境中请求他们\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eexternals\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n \u003Cspan class=\&c1\&\u003E\u002F\u002F 处理 hot 属性,它决定 webpack 了如何使用热替换\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Ehot\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{...}\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F 处理 devtool 属性,它决定了 webpack 的 sourceMap 模式\u003C\u002Fspan\u003E\n
\u003Cspan class=\&k\&\u003Eif\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Edevtool\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E&&\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(((\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eoptions\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Edevtool\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EindexOf\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003

我要回帖

更多关于 vue实战饿了么 的文章

 

随机推荐