会js的大神

购买商品:
商品价格:
价格读取中
支付方式:
请扫码进行支付
请扫码进行支付
JavaScript大神之路
包含课程:
总课时数:
从0开始学习JavaScript,从入门到进阶高级编程,掌握js开发技能,轻松应对web开发、微信小程序开发。
模式:案例讲解+实战+深层次原理绘图讲解
附带价值:讲解编程语言背后的内存原理及逻辑,理解之后其他编程语言通用
从0开始学习JavaScript,从入门到进阶高级编程
23课时(已更新至23)
06小时49分10秒
促销¥19.00
从0开始学习JavaScript,从入门到进阶高级编程
20课时(已更新至20)
05小时14分44秒
促销¥9.00
10个课程158477学员22:50 提问
小白一枚,javascript大神过来求助.
我技能节参赛,纯javascript做了一个推箱子类型的游戏。 而我参赛打算就做一个推箱子改版的剧情型密室逃脱rpg游戏。 由于了解不多且技术有限,现在我就做好了对话框,人物移动,和连接地图等功能。 地图就是个三维数组,然后我触发数组的一些值会获取物品。
现在竟然进了决赛,15名 我们第14名::&&::
然后为了不想成为一条闲鱼 我想问问只靠JavaScript能不能实现 账户登陆 然后存档当前剧情内容给账号所对应的数据库呢。 虽然有点幼稚,但是还是想问问各位大神能否实现吗O(∩∩)O~~
按时间排序
可以实现,你自己研究下NodeJS.
其他相关推荐在 SegmentFault,解决技术问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
一线的工程师、著名开源项目的作者们,都在这里:
获取验证码
已有账号?
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
其实也算是一个听常见的效果,很多响应式的网站都会使用。就是在页面滚动的时候,元素会有从左边或者上面,滑下来的效果是怎么实现的。就CSS动画做的话,是可以做到动画,但是如何鉴别元素正好进去可视区,然后才会添加class去执行动画?大神求教
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
1个css库(animate.css), 1个js的插件(waypoints.js)
animate.css
waypoints.js:
简单的说就是, 用waypoints监听dom是否在当前屏幕, 然后给dom添加或者删除animate动画
$('#fh5co-features').waypoint( function( direction ) {
if( direction === 'down' && !$(this).hasClass('animated') ) {
$(this).addClass('animated');
} , { offset: '70%' } );
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
大神在哪呢? 坐等啊
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
这个更好用,用法还很简单
同步到新浪微博
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:大神面对面:Vue.js 作者尤雨溪专访6 months ago赞赏1 人赞赏487收藏分享举报文章被以下专栏收录关注前端技术,探寻深邃思想,https://qianduan.group推荐阅读{&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&:&关注前端前沿技术,探寻业界深邃思想。https:\u002F\u002Fqianduan.group 欢迎微信\u002F微博搜索『前端外刊评论』,关注我们。欢迎给本专栏投稿,原作译作不限,要求:质量高!如果愿意尝试从事前端技术相关的书籍的编写或翻译工作,请私信外刊君。&,&permission&:&COLUMN_PUBLIC&,&memberId&:3313,&contributePermission&:&COLUMN_PUBLIC&,&translatedCommentPermission&:&all&,&canManage&:true,&intro&:&关注前端技术,探寻深邃思想,https:\u002F\u002Fqianduan.group&,&urlToken&:&FrontendMagazine&,&id&:699,&imagePath&:&bd21f286e6aa5e210b60e2e257ce890b.jpeg&,&slug&:&FrontendMagazine&,&applyReason&:&&,&name&:&前端外刊评论&,&title&:&前端外刊评论&,&url&:&https:\u002F\\u002FFrontendMagazine&,&commentPermission&:&COLUMN_ALL_CAN_COMMENT&,&canPost&:true,&created&:,&state&:&COLUMN_NORMAL&,&followers&:41957,&avatar&:{&id&:&bd21f286e6aa5e210b60e2e257ce890b&,&template&:&https:\u002F\\u002F{id}_{size}.jpeg&},&activateAuthorRequested&:false,&following&:false,&imageUrl&:&https:\u002F\\u002Fbd21f286e6aa5e210b60e2e257ce890b_l.jpeg&,&articlesCount&:184},&state&:&accepted&,&targetPost&:{&titleImage&:&https:\u002F\\u002Fv2-85f9eb76d9f4eb851a9c21_r.png&,&lastUpdated&:,&imagePath&:&v2-85f9eb76d9f4eb851a9c21.png&,&permission&:&ARTICLE_PUBLIC&,&topics&:[225,769,159435],&summary&:&今天,外刊君有幸邀请到了我们的尤大,尤神,也就是目前非常流行的\u003Ca href=\&https:\u002F\u002Fvuejs.org\u002F\&\u003E前端框架 Vue.js\u003C\u002Fa\u003E 的作者,尤雨溪,接受我们的专访。 5月20日,\u003Ca href=\&https:\u002F\\u002F\& data-title=\&全球首届 Vue Conf 大会\& class=\&\& data-editable=\&true\&\u003E全球首届 Vue Conf 大会\u003C\u002Fa\u003E在北京成功举行。大家一定有很多问题想问尤大,外刊君自己想了一些问题,也从社区中收集了一些。我们来…&,&copyPermission&:&ARTICLE_COPYABLE&,&translatedCommentPermission&:&all&,&likes&:0,&origAuthorId&:0,&publishedTime&:&T08:05:42+08:00&,&sourceUrl&:&&,&urlToken&:,&id&:3069327,&withContent&:false,&slug&:,&bigTitleImage&:false,&title&:&大神面对面:Vue.js 作者尤雨溪专访&,&url&:&\u002Fp\u002F&,&commentPermission&:&ARTICLE_ALL_CAN_COMMENT&,&snapshotUrl&:&&,&created&:,&comments&:0,&columnId&:699,&content&:&&,&parentId&:0,&state&:&ARTICLE_PUBLISHED&,&imageUrl&:&https:\u002F\\u002Fv2-85f9eb76d9f4eb851a9c21_r.png&,&author&:{&bio&:&不同凡想,心成伟事。&,&isFollowing&:false,&hash&:&0d9b98af12015c94cff646a6fc0773b5&,&uid&:52,&isOrg&:false,&slug&:&stein.cun&,&isFollowed&:false,&description&:&https:\u002F\u002Fqianduan.group,JavaScript、Node.js、CoffeeScript,欢迎微信搜索「前端外刊评论」关注我们用心打造的公众号,每周推送高质量前端资讯!&,&name&:&寸志&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fstein.cun&,&avatar&:{&id&:&369e5e380&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&memberId&:3313,&excerptTitle&:&&,&voteType&:&ARTICLE_VOTE_CLEAR&},&id&:667747}],&title&:&大神面对面:Vue.js 作者尤雨溪专访&,&author&:&stein.cun&,&content&:&今天,外刊君有幸邀请到了我们的尤大,尤神,也就是目前非常流行的\u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\u002Fvuejs.org\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E前端框架 Vue.js\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E 的作者,尤雨溪,接受我们的专访。\u003Cbr\u003E\u003Cbr\u003E5月20日,\u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E全球首届 Vue Conf 大会\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E在北京成功举行。大家一定有很多问题想问尤大,外刊君自己想了一些问题,也从社区中收集了一些。我们来看看尤大是怎么回答的,与大神做一次近距离的接触。\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E外:国内第一届 Vue Conf 于5月20日在北京成功举办,作为开场演讲嘉宾,是否可以谈谈您的参会感受?\u003C\u002Fb\u003E\u003Cbr\u003E\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cb\u003E尤\u003C\u002Fb\u003E:在现场可以很直接地感受到社区的热情,当然非常高兴。对于 Vue 在国内能发展到今天这样的地步,其实也有些受宠若惊。第一次办大会,难免还是有些地方做的不够完善,以后再办会对听众的需求和讲题的选择下更大的功夫。这里特别要感谢裕波,因为大会的具体事宜都是由他操办的,非常辛苦。\u003C\u002Fblockquote\u003E\n\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E外:最新版的 Vue 里会加什么新的功能?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cb\u003E尤\u003C\u002Fb\u003E:对新版本比较关注的同学应该会发现最近几个 minor 版本对于服务端渲染 (SSR) 的功能添加比较多。主要原因是 SSR 是我觉得目前还比较有可挖掘空间的一块。2.3 对开发模式做了一个沉淀,2.4 进一步优化性能,并且彻底解决了 SSR 和 code split 的配合问题。另外 2.4 会有 TypeScript 团队合作贡献的更强大的类型声明。在这之后 Vue 核心会进入一段相对稳定的时间,当然会继续有小的 API 改进,但精力会放到生态圈的其他部分中。首先是团队和社区已经开始开发一个官方的单元测试辅助工具,然后 vue-cli 将会进行一次比较大的重构,让上手和开发体验更加顺滑。\u003C\u002Fblockquote\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E外:Vue 这个开源项目是怎么维护的,有多少人一起维护?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cb\u003E尤\u003C\u002Fb\u003E:Vue 有一个所谓的『核心团队』,但组织上是比较松散的,没有强制的任务分配。一般如果社区成员经常发送 PR 或是参与维护的话,我会邀请 ta 加入 Github 上的 vuejs orgnization 和我们的团队 Slack。常驻比较活跃的大概有十来个人,这些成员会帮我分担许多日常维护的工作,比如 review PR,对 issue 进行定位和修复等等。当然也有来自团队外的开源贡献者的 PR。\u003C\u002Fblockquote\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E外:Vue 会考虑支持 TypeScript 或者用 TS 实现么?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cb\u003E尤\u003C\u002Fb\u003E:TypeScript 其实 2.0 已经支持很久了,vue, vue-router 和 vuex 都有官方的类型声明。之前的一个问题是由于 Vue 的默认 API 不是基于 class 的,所以类型推断比较困难,用户得用类似 vue-class-component 这样的库去进行一层封装才能获得比较良好的类型推导。2.4 的新类型声明基于 TS 2.3 的 contextual typing 功能,可以让 Vue 的默认 API 也获得良好的类型推导,会进一步改善 Vue 和 TS 的整合。结合 VSCode 的 vetur 插件,使用 *.vue 文件时的开发体验也会好很多。另外新的 vue-cli 也打算包含官方的 TS 脚手架。\u003Cbr\u003E\u003Cbr\u003E至于 Vue 的内部实现,短期内不会考虑改用 TS,因为现在 Flow 用着也没有什么大问题,切换到 TS 有较大的成本但没有太明显的好处。如果要开新坑的话可能还会考虑一下。\u003C\u002Fblockquote\u003E\n\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E外:可以聊聊 Vue 的短期目标和长期目标吗?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cb\u003E尤\u003C\u002Fb\u003E:其实核心目标永远只有一个,那就是为前端开发者提供一套良好的工具,让更多的开发者可以多快好省地开发前端应用。短期目标都是由这个核心目标衍生出来的,简言之就是不停地去改进整个生态里还不完善或是变得落后的部分。\u003C\u002Fblockquote\u003E\n\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E外:有没有想过自己主导开发一个 “Weex”?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cb\u003E尤\u003C\u002Fb\u003E:并没有。我对于 Android\u002FiOS 原生开发并不像我对前端这样熟悉,而且一个像 Weex 或是 ReactNative 这样的项目的工作量非常庞大,需要有相当数量的专职开发投入才行,更何况我还要继续兼顾 Vue 本身的维护和开发,即使想也做不了。\u003C\u002Fblockquote\u003E\n\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E外:React 有自己的 React Native、React VR 等等,Vue 的生态链是什么样的,Vue 的生态将会如何发展?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cb\u003E尤\u003C\u002Fb\u003E:Vue 作为独立项目,会更专注于 web 端。当然这不妨碍我们提供足够的灵活度来让 Vue 和社区或是外部生态进行整合。比如 Weex 和 Vue 能够整合就是因为 Vue 的核心逻辑和 DOM 是解耦的。VR 可以用 Vue 结合 AFrame 来开发,社区里也有 blessed-vue (用 Vue 写命令行图形界面),Vue + NativeScript 这样的项目。\u003C\u002Fblockquote\u003E\n\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E外:Vue.js 和 React 都是目前社区里最流行的框架,React 很强大,也有自己完善的生态圈,是什么原因或者动力支持您持续开发 Vue.js?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cb\u003E尤\u003C\u002Fb\u003E:一年多以前我也问过自己这样的问题,但让我坚持开发 Vue 的原因其实很简单:因为 Vue 的用户一直在增长,这说明 Vue 确实契合了相当一部分开发者的需求,那么这个事情就是有价值的。前端是一个产品形态差异很大的平台,所以不同的场景需求会有很大区别。其次,我个人觉得,开发者群体是很多样化的,出于学习背景、习惯、思维模式的差异,不同的开发者会偏好不同的语言、框架和工具。这些区别是没有办法抹平的,所以与其去浪费时间争论哪个框架更好,不如让不同场景、不同偏好的群体都变得更有效率,这样开发者们作为一个整体为世界创造的实际价值就更多。从这个角度来看,多种方案的并存是必然的,甚至是有益的。另外,一个领域如果没有竞争了,那么这个领域也就走到头了。\u003C\u002Fblockquote\u003E\n\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E外:如果 Vue.js 发布 3.0,会是什么样子?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cb\u003E尤\u003C\u002Fb\u003E:版本号其实是个比较容易误会的东西。从 semver (语义化版本号)的角度看,3.0 意味着 breaking change,但未必意味着有什么翻天覆地的改动。考虑到兼容性、稳定性、升级的可行性,真正的 3.0 在 API 上不会有什么太大的变化,最有可能的就是内部的响应式机制用 Proxy 重写带来一些微小的 breaking change,同时不再支持 IE9~11。大部分情况下应该和 2.x 会无缝兼容。\u003Cbr\u003E\u003Cbr\u003E如果要大改 API 的话,可能会把 API 设计得稍稍函数式一些,对 this 的依赖少一些吧。但这个其实通过一些上层的封装就可以做到了。\u003C\u002Fblockquote\u003E\n\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E外:听说您已经成为独立开发者(开公司),现在怎么平衡开源和生活?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cb\u003E尤\u003C\u002Fb\u003E:公司只是出于税务\u002F签证什么的需求注册了一下而已,其实就是独立开发者。现在 Patreon 的赞助以及一些其他渠道的被动收入足够维持正常的收入水平,所以跟原来的区别就是开源变成了工作,工作和生活的平衡反而好了很多。以前上班之余做开源,占用的是家庭时间,现在不需要了,可以多陪老婆带孩子。\u003C\u002Fblockquote\u003E\n\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E外:您觉得前端行业,或者作为一个前端工程师有前途么?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\n\u003Cblockquote\u003E\u003Cb\u003E尤\u003C\u002Fb\u003E:我对前端的理解是这样的:依托于 Web 平台的 GUI 开发。这个行业的『前途』很显然跟 Web 这个平台的走势是密切相关的,虽然 Web 这几年受到不少来自移动端的挑战,但整体来说,我个人认为还是有比较稳定的生存空间。其次,前端这块有很多重复性质的体力活,如果只是忙于应付这样的工作,个人的成长就会比较受限。想要有前途还是得思考如何更有效率地创造价值。最后,前端开发里面也有很多可以跨越平台的技能,比如 GUI 开发的很多思想、模式、前端运维中的工程化、自动化等等,这些即使你以后不做前端,也依然会是有价值的东西 —— 本质上,有些东西是所有的『工程师』都需要的,对这些技能的沉淀或许可以帮助你缓解那种『这个方向有没有前途』的焦虑。\u003C\u002Fblockquote\u003E\n\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E外:\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E2017 年 JavaScript 中国开发者大会\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E 于7月15 - 16日在上海召开,您作为去年的讲师,这次还会作为嘉宾给我们带来新的分享么?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cblockquote\u003E\u003Cb\u003E尤\u003C\u002Fb\u003E:会的。这两年随着前端的工程化,编译几乎成为了一道必不可少的步骤,这同时也带来了很多优化的可能性。这次会结合社区的发展谈谈前端的编译时优化。\u003C\u002Fblockquote\u003E\u003Cbr\u003E\u003Cbr\u003E\u003Cp\u003E感谢尤大百忙之中接受我们的采访,我们对尤大的专访就到这里,是不是也回答了一些你的疑问呢?\u003C\u002Fp\u003E\n看着 Vue.js 一路走来,不断积累与沉淀,取得如今的成就,由衷地为尤大感到高兴。\u003Cb\u003E感谢尤大的努力和付出,真心祝愿 Vue.js,Vue 社区越来越好!\u003C\u002Fb\u003E&,&updated&:new Date(&T00:05:42.000Z&),&canComment&:false,&commentPermission&:&anyone&,&commentCount&:50,&collapsedCount&:0,&likeCount&:487,&state&:&published&,&isLiked&:false,&slug&:&&,&lastestTipjarors&:[{&isFollowed&:false,&name&:&牧原&,&headline&:&&,&avatarUrl&:&https:\u002F\\u002F50\u002Fv2-47c8ec6d8aa7fc2565c73_s.jpg&,&isFollowing&:false,&type&:&people&,&slug&:&a-k-123&,&bio&:&装逼爱好者&,&hash&:&ecb242afcf932&,&uid&:570240,&isOrg&:false,&description&:&&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fa-k-123&,&avatar&:{&id&:&v2-47c8ec6d8aa7fc2565c73&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}],&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\\u002Fv2-85f9eb76d9f4eb851a9c21_r.png&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&reviewers&:[],&topics&:[{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&前端开发&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&JavaScript&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&Vue.js&}],&adminClosedComment&:false,&titleImageSize&:{&width&:600,&height&:400},&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&column&:{&slug&:&FrontendMagazine&,&name&:&前端外刊评论&},&tipjarState&:&activated&,&tipjarTagLine&:&支持雨溪,支持 Vue.js&,&sourceUrl&:&&,&pageCommentsCount&:50,&tipjarorCount&:1,&annotationAction&:[],&hasPublishingDraft&:false,&snapshotUrl&:&&,&publishedTime&:&T08:05:42+08:00&,&url&:&\u002Fp\u002F&,&lastestLikers&:[{&bio&:null,&isFollowing&:false,&hash&:&f467d370c42ca3d6ddb9cccbad834501&,&uid&:933500,&isOrg&:false,&slug&:&yibian-zou-lu&,&isFollowed&:false,&description&:&&,&name&:&一边走路&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fyibian-zou-lu&,&avatar&:{&id&:&da8e974dc&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:null,&isFollowing&:false,&hash&:&9668bfb5cdd6f20b0263&,&uid&:054100,&isOrg&:false,&slug&:&sxf-30-2&,&isFollowed&:false,&description&:&&,&name&:&sxf&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fsxf-30-2&,&avatar&:{&id&:&da8e974dc&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:null,&isFollowing&:false,&hash&:&fb6ff599fb60&,&uid&:867100,&isOrg&:false,&slug&:&fang-fang-jie-77&,&isFollowed&:false,&description&:&&,&name&:&芳芳姐&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Ffang-fang-jie-77&,&avatar&:{&id&:&da8e974dc&,&template&:&https:\u002F\\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&互联网从业人员&,&isFollowing&:false,&hash&:&3b5e58a5f9&,&uid&:48,&isOrg&:false,&slug&:&li-ji-35&,&isFollowed&:false,&description&:&&,&name&:&女王大人&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fli-ji-35&,&avatar&:{&id&:&f777e811abd43e&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.png&},&isOrgWhiteList&:false,&isBanned&:false},{&bio&:&IT开发&,&isFollowing&:false,&hash&:&9602dbf7b15f2e4bbc7db2&,&uid&:334500,&isOrg&:false,&slug&:&ting-yu-xuan-yue-guang-ji-feng&,&isFollowed&:false,&description&:&&,&name&:&听雨轩月光疾风&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fting-yu-xuan-yue-guang-ji-feng&,&avatar&:{&id&:&cd3478872efc00fd2826&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false}],&summary&:&今天,外刊君有幸邀请到了我们的尤大,尤神,也就是目前非常流行的\u003Ca href=\&https:\u002F\u002Fvuejs.org\u002F\&\u003E前端框架 Vue.js\u003C\u002Fa\u003E 的作者,尤雨溪,接受我们的专访。 5月20日,\u003Ca href=\&https:\u002F\\u002F\& data-title=\&全球首届 Vue Conf 大会\& class=\&\& data-editable=\&true\&\u003E全球首届 Vue Conf 大会\u003C\u002Fa\u003E在北京成功举行。大家一定有很多问题想问尤大,外刊君自己想了一些问题,也从社区中收集了一些。我们来…&,&reviewingCommentsCount&:0,&meta&:{&previous&:{&isTitleImageFullScreen&:true,&rating&:&none&,&titleImage&:&https:\u002F\\u002F50\u002Fv2-9516ac4efdd41dafcc760_xl.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&topics&:[{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&JavaScript&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&Node.js&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&ECMAScript 2015&}],&adminClosedComment&:false,&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&author&:{&bio&:&不攻城&,&isFollowing&:false,&hash&:&b3fc4cee8c669c4b2c6f05e&,&uid&:00,&isOrg&:false,&slug&:&ran-yu&,&isFollowed&:false,&description&:&不想腐朽,冷眼这华丽残酷的世界&,&name&:&冉余&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fran-yu&,&avatar&:{&id&:&v2-cbb43b05c31abd5c7ac2d&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&column&:{&slug&:&mirreal&,&name&:&秘锐笔记&},&content&:&\u003Cp\u003EESM, CJS, UMD, AMD — 到底应该选择哪一个?\u003C\u002Fp\u003E\u003Cblockquote\u003E\u003Cp\u003E原文作者:Johannes Ewald \u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002FJhnnns\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E@Jhnnns\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cp\u003E原文链接:\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fwebpack\u002Fthe-state-of-javascript-modules-\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EThe state of JavaScript modules\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003C\u002Fp\u003E\u003Cp\u003E已获原作者授权翻译及发布\u003C\u002Fp\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E最近 \u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Faddyosmani\u002Fstatus\u002F597313\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E在 twitter\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E 上有很多关于 \u003Ca href=\&http:\u002F\\u002F?target=http%3A\\u002F\u002Fes6-modules-final.html\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EES Module\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E 现状的讨论,\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fbradleymeck\u002Fstatus\u002F650944\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E尤其是在 Node.js 上\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E,他们计划引入新的文件扩展名 *.mjs。人们有足够理由对此感到 \u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Ftankredhase\u002Fstatus\u002F907136\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E担忧和不确定\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E,因为这个话题异常复杂,接下来会尽力阐述清楚问题。\u003C\u002Fp\u003E\u003Ch2\u003E来自远古的恐惧\u003C\u002Fh2\u003E\u003Cp\u003E大多数前端开发者应该还记得 \u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002F%40trek\u002Flast-week-i-had-a-small-meltdown-on-twitter-about-npms-future-plans-around-front-end-packaging-b424dd8d367a\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EJavascript 依赖管理的黑暗时期\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E。那个时候,你需要把一个库复制粘贴到 vendor 文件夹,然后作为一个全局变量引入,要自己去按次序组合所有东西,可能还要管理命名空间。\u003C\u002Fp\u003E\u003Cp\u003E在过去的那些年,我们能深刻体会到公共模块格式化和中央模块管理的价值。\u003C\u002Fp\u003E\u003Cp\u003E在今天,不管是发布还是使用一个库都要容易得多,只需要使用 npm publish 和 npm install 命令就行。这就是人们会那么紧张两种模块系统兼容性问题的原因:\u003Ci\u003E他们不想失去已有的舒适区\u003C\u002Fi\u003E。\u003C\u002Fp\u003E\u003Cp\u003E接下来我会解释和总结现有实现的情况,以及为什么 Node 生态迁移到 ES Module(ESM)会那么难。在最后,总结这些变化对 webpack 使用者和模块作者有什么影响。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Ch3\u003E现有实现\u003C\u002Fh3\u003E\u003Cp\u003E目前,ESM 有三种方式的实现:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E浏览器\u003C\u002Fli\u003E\u003Cli\u003Ewebpack 以及类似的构建工具\u003C\u002Fli\u003E\u003Cli\u003ENode(未完成,\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Frauschma\u002Fstatus\u002F095617\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E但可能在年底作为一个实验功能\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E)\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E为了更好地理解现在的讨论,首先要知道 ES2015 包含两种模式:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003Escript 用于具有全局命名空间的常规脚本\u003C\u002Fli\u003E\u003Cli\u003Emodule 用于具有明确导入和导出的模块化代码\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E如果你试图在 script 标签使用 import 或者 export 语句,会抛出一个 SyntaxError。这种语句在全局环境下没有任何意义。另一方面,module 模式即意味着\u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\u002Fdeveloper.mozilla.org\u002Fen\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FStrict_mode\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E严格模式\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E,禁止使用某些语言特性,比如 with 语句。因此,需要在脚本被解析和执行之前定义模式。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Ch3\u003E浏览器中的 ESM\u003C\u002Fh3\u003E\u003Cp\u003E截至到 2017 年 5 月,所有主流浏览器都开始做了 ESM 的实现工作。不过,大部分仍处于在实验性质。这里不会做详细介绍,因为 \u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002FFes-modules-in-browsers\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EJake Archibald 已经写了一篇很厉害的文章\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E。\u003C\u002Fp\u003E\u003Cp\u003E除了一些小的困难,在浏览器中实现起来非常容易,因为以前并没有模块系统。想要指定 module 模式,需要在 script 标签添加 type=\&module\& 属性,如下所示:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-html\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E&\u003C\u002Fspan\u003E\u003Cspan class=\&nt\&\u003Escript\u003C\u002Fspan\u003E \u003Cspan class=\&na\&\u003Etype\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E\u003Cspan class=\&s\&\u003E\&module\&\u003C\u002Fspan\u003E \u003Cspan class=\&na\&\u003Esrc\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E\u003Cspan class=\&s\&\u003E\&main.js\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E&&\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&nt\&\u003Escript\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E&\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E在一个模块中,当前只能使用有效的 URL 作为模块标识符。模块标识符是用于 require 或 import 其他模块的字符串。为了确保未来兼容 CJS 模块标识符,“bare” 导入标识符(如 import \&lodash\&)现在还不支持。模块标识符必须是绝对 URL 或者是以 \u002F, .\u002F, ..\u002F开头:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F Supported:\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Efoo\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'https:\\u002Futils\u002Fbar.js'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Efoo\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'\u002Futils\u002Fbar.js'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Efoo\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'.\u002Fbar.js'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Efoo\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'..\u002Fbar.js'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F Not supported:\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Efoo\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'bar.js'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Efoo\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&s1\&\u003E'utils\u002Fbar.js'\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F Example from https:\\u002FFes-modules-in-browsers\u002F\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E同样需要注意的是,一旦处在一个模块中,每个导入也将被解析为 module,而且没有办法 import 一个 script。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Ch3\u003EESM 与 webpack\u003C\u002Fh3\u003E\u003Cp\u003E类似 webpack 这样的构建工具通常会尝试用 module 模式解析代码,有问题再切回到 script 模式。这些工具最终会生成一段 script,通常是在一定程度上模拟 CJS 和 ESM 行为的模块运行时。\u003C\u002Fp\u003E\u003Cp\u003E我们以这两个简单的 ESM 为例:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F a.js\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Eexport\u003C\u002Fspan\u003E \u003Cspan class=\&kd\&\u003Elet\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enumber\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&mi\&\u003E42\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Eexport\u003C\u002Fspan\u003E \u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eincr\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E()\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Enumber\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\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\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F test.js\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enumber\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&.\u002Fa\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&nx\&\u003Econsole\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Elog\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Enumber\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003Ewebpack 使用函数包装器封装模块范围和对象引用来模拟 \u003Ca href=\&http:\u002F\\u002F?target=http%3A\\u002F\u002Fes6-module-exports.html\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EESM 实时绑定\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E。每次编译,还包括一个模块运行时,负责引导和缓存模块。此外,将模块标识转换为数字模块 ID。这样可以减少打包的大小和引导时间。\u003C\u002Fp\u003E\u003Cp\u003E这是什么意思呢?我们来看看编译输出:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\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\&\u003Emodules\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F This is the module runtime.\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F It's only included once per compilation.\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F Other chunks share the same runtime.\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EinstalledModules\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{};\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F The require function\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003E__webpack_require__\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EmoduleId\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
\u003Cspan class=\&p\&\u003E...\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F Load entry module and return exports\u003C\u002Fspan\u003E\n\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003E__webpack_require__\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003E__webpack_require__\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Es\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&mi\&\u003E1\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 \u003Cspan class=\&c1\&\u003E\u002F\u002F An array that maps module ids to functions\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F a.js as module id 0\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Emodule\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003E__webpack_exports__\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003E__webpack_require__\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&s2\&\u003E\&use strict\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&nb\&\u003EObject\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EdefineProperty\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003E__webpack_exports__\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&a\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Econfigurable\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Efalse\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Eenumerable\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&kc\&\u003Etrue\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Eget\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\u003E:\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E()\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=&\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enumber\u003C\u002Fspan\u003E\n
\u003Cspan class=\&p\&\u003E});\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&kd\&\u003Elet\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Enumber\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&mi\&\u003E42\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eincr\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E()\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&nx\&\u003Enumber\u003C\u002Fspan\u003E\u003Cspan class=\&o\&\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\u003Cspan class=\&c1\&\u003E\u002F\u002F test.js as module id 1\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Efunction\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Emodule\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003E__webpack_exports__\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003E__webpack_require__\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n
\u003Cspan class=\&s2\&\u003E\&use strict\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&kd\&\u003Evar\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003E__WEBPACK_IMPORTED_MODULE_0__a__\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003E__webpack_require__\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&mi\&\u003E0\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&c1\&\u003E\u002F\u002F Object reference as \&live binding\&\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Econsole\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Elog\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003E__WEBPACK_IMPORTED_MODULE_0__a__\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E[\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&a\&\u003C\u002Fspan\u003E \u003Cspan class=\&cm\&\u003E\u002F* number *\u002F\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\u003Cp\u003E简化的 webpack 输出,模拟 ES Modules 行为\u003C\u002Fp\u003E\u003Cp\u003E结果已经简化并删除了一些与此示例无关的代码。你会发现,webpack 在 exports 对象上将所有 export 语句替换成 Object.defineProperty,并使用属性访问器替换对引入值的所有引用。还要注意每个 ESM 开始时的 \&use strict\& 指令,这是由 webpack 自动添加,在 ESM 中必须是严格模式。\u003C\u002Fp\u003E\u003Cp\u003E这种实现只是模拟,因为它试图模仿 ESM 和 CJS 的行为 – 但不是与其完全保持一致。比如,这种模拟并不符合某些边缘情况。看下面这个模块:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Econsole\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Elog\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&k\&\u003Ethis\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E如果你通过加上 babel-preset-es2015 的 Babel 来运行,结果是:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&use strict\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&nx\&\u003Econsole\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Elog\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&kc\&\u003Eundefined\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E从输出结果可以看出,Babel 假设默认是 ESM,因为 module 模式即代表严格模式,在严格模式下会将 this 初始化为 undefined。\u003C\u002Fp\u003E\u003Cp\u003E然而,使用 webpack,结果是:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\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\&\u003Emodule\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=\&p\&\u003E{\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&nx\&\u003Econsole\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Elog\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&k\&\u003Ethis\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&p\&\u003E})\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E在引导模块时,this 将指向 exports ,与 Node.js 使用的 CJS 行为一致。这是因为语法上不确定是 script 还是 module,解析器无法判断该模块是 ESM 还是 CJS。在不明确的时候,webpack 会模拟 CJS,因为它仍然是最受欢迎的模块风格。\u003C\u002Fp\u003E\u003Cp\u003E这种模拟其实已经包含了很多情况,因为模块作者通常会避免这种代码。然而,“很多情况”对于像 Node.js 这样的平台是不够的,因为它需要保证所有有效的 JavaScript 代码都能正常运行。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Ch3\u003ENode.js 中的 ESM\u003C\u002Fh3\u003E\u003Cp\u003ENode.js 在执行 ESM 时遇到了麻烦,因为仍然需要支持 CJS,语法看起来相似,但运行时行为完全不同。\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fnodejs\u002FCTC\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ENode.js 核心技术委员会\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E(CTC)成员 James M Snell 撰写了\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fnode-js-tc-39-and-modules-a1118aecf95e\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E一篇很好的文章来解释 CJS 与 ESM 之间的差异\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E。\u003C\u002Fp\u003E\u003Cp\u003E归结起来,CJS 是一个动态模块系统,ESM 是静态模块系统。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003ECJS\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E允许动态同步 require()\u003C\u002Fli\u003E\u003Cli\u003E导出仅在模块执行后才知道\u003C\u002Fli\u003E\u003Cli\u003E导出可以在模块初始化后添加,替换和删除\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cb\u003EESM\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E只允许静态同步 import\u003C\u002Fli\u003E\u003Cli\u003E在模块执行之前,导入和导出已经关联\u003C\u002Fli\u003E\u003Cli\u003E导入和导出是不可变的\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E由于 CJS 早于 ES2015,所以一直在 script 模式下解析,封装通过使用函数包装器实现。在 Node.js 中加载 CJS,实际上会执行与此类似的代码:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&kr\&\u003Econst\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Emodule\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\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=\&p\&\u003E{}\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E};\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Econst\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EmakeRequireFunction\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E();\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Econst\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Efilename\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&...\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Econst\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Edirname\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&...\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&kd\&\u003Efunction\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\&\u003Erequire\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Emodule\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003E__filename\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003E__dirname\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E)\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E\n\u003Cspan class=\&cm\&\u003E\u002F* YOUR CODE *\u002F\u003C\u002Fspan\u003E\n\u003Cspan class=\&p\&\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=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Erequire\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Emodule\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Efilename\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Edirname\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E对 Node.js 的 CommonJS 模块的简单函数包装\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cp\u003E问题出现了,将两个模块系统集成到同一个运行时时,ESM 和 CJS 之间的循环依赖可能会迅速导致类似死锁的情况。\u003C\u002Fp\u003E\u003Cp\u003E而且,由于现有 CJS 模块数量庞大,也不能直接放弃对 CJS 的支持。为了避免 Node.js 生态的中断,有两点已经很明显:\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E现有的 CJS 代码必须以相同的方式继续工作\u003C\u002Fli\u003E\u003Cli\u003E两个模块系统都必须同时且尽可能无缝地工作\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cb\u003E目前的权衡\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E2017 年 3 月,经过几个月的讨论,CTC 终于找到了一种解决问题的办法。由于在 ES 规范和引擎不改变的情况下无法进行无缝集成,\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fbmeck\u002Fnode-eps\u002Fblob\u002Fa1eab9bf023bbe13a79ddb18f15f9b\u002F002-es-modules.md\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ECTC 决定开始一些权衡之后的实现工作\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E:\u003C\u002Fp\u003E\u003Cbr\u003E1.ESM 必须是 *.mjs 文件扩展名\u003Cp\u003E这是由于上面提及的模糊语法问题,无法通过解析来确切知晓 JavaScript 代码是什么类型。为了 Node.js 向后兼容的目标,作者需要加入一种新模式。\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fnodejs\u002Fnode\u002Fwiki\u002FES6-Module-Detection-in-Node%23detection-problem\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E已经有关于各种替代品的讨论\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E,但使用不同文件扩展名是解决目前问题的最佳权衡。\u003C\u002Fp\u003E\u003Cbr\u003E2.CJS 只能异步导入 ESM import()\u003Cp\u003ENode.js 将异步加载 ESM,以便尽可能接近浏览器的行为。因此,同步的 require() 在 ESM 是不可能的,并且依赖于 ESM 的每个功能都需要异步:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&kr\&\u003Econst\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EdriverPromise\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&kr\&\u003Eimport\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&s2\&\u003E\&dbdriver\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n\n\u003Cspan class=\&nx\&\u003Eexports\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E.\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003EreadFromDb\u003C\u002Fspan\u003E \u003Cspan class=\&o\&\u003E=\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Easync\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Equery\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
\u003Cspan class=\&k\&\u003Ereturn\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eawait\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003EdriverPromise\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E).\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Eread\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E(\u003C\u002Fspan\u003E\u003Cspan class=\&nx\&\u003Equery\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\u003E3. CJS 向 ESM 暴露一个不可变的默认导出\u003Cp\u003E使用 Babel 或 Webpack,我们通常将 CJS 重构为 ESM,如下所示:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cdiv class=\&highlight\&\u003E\u003Cpre\u003E\u003Ccode class=\&language-js\&\u003E\u003Cspan\u003E\u003C\u002Fspan\u003E\u003Cspan class=\&c1\&\u003E\u002F\u002F CJS\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Econst\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ea\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eb\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E}\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\&c\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E);\u003C\u002Fspan\u003E\n\u003Cspan class=\&c1\&\u003E\u002F\u002F ESM\u003C\u002Fspan\u003E\n\u003Cspan class=\&kr\&\u003Eimport\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E{\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Ea\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E,\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Eb\u003C\u002Fspan\u003E \u003Cspan class=\&p\&\u003E}\u003C\u002Fspan\u003E \u003Cspan class=\&nx\&\u003Efrom\u003C\u002Fspan\u003E \u003Cspan class=\&s2\&\u003E\&c\&\u003C\u002Fspan\u003E\u003Cspan class=\&p\&\u003E;\u003C\u002Fspan\u003E\n\u003C\u002Fcode\u003E\u003C\u002Fpre\u003E\u003C\u002Fdiv\u003E\u003Cp\u003E再一次地,他们的语法看起来很相似,但忽略了 CJS 中没有命名导出的事实。只有一个叫做 default 的导出,等同于在 CJS 模块完成计算后一个不可变的 module.exports 。从技术上讲,有可能将 module.exports 解构成命名导入,但这需要对标准作更大的变更。\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fbmeck\u002Fnode-eps\u002Fblob\u002Fa1eab9bf023bbe13a79ddb18f15f9b\u002F002-es-modules.md%23461-default-imports\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E这就是现在 CTC 决定采取这种方式的原因\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E。\u003C\u002Fp\u003E\u003Cbr\u003E4.模块范围的变量类似 module,require 以及 __filename 在 ESM 不存在\u003Cp\u003ENode.js 和浏览器会实现一些 ESM 的特性,\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fwhatwg\u002Fhtml\u002Fissues\u002F1013\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E但标准化过程仍在进行中\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E。\u003C\u002Fp\u003E\u003Cp\u003E鉴于将 CJS 和 ESM 集成到一个运行时的工程挑战,CTC 在评估边缘情况和权衡方面做了非常好的工作。比如使用不同的文件扩展名是就是一个很简单的解决方案。\u003C\u002Fp\u003E\u003Cp\u003E实际上,一个文件扩展名可以认为是一个二进制文件如何解释的提示。如果一个 module 不是 script,我们应该使用不同的文件扩展名。其他工具(如 linter 或 IDE )也可以获取相同信息。\u003C\u002Fp\u003E\u003Cp\u003E当然,引入新的文件扩展名有成本,但是一旦服务器和其他应用程序确认 *.mjs 为JavaScript,我们很快就会忘记这个争议。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Ch3\u003E将 * .mjs 作为 Node.js 的 Python 3?\u003C\u002Fh3\u003E\u003Cp\u003E考虑到所有这些限制,人们可能会问,这种过渡将对现在的生态造成什么样的损害。虽然 CTC 会努力解决问题,但社区如何采用这一点仍然存在很大不确定性。这种不确定性 \u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fsindresorhus\u002Fstatus\u002F452545\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E被众多知名的 NPM 模块作者\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E 再次强调,他们声称将不会在模块中使用 *.mjs。\u003C\u002Fp\u003E\u003Cfigure\u003E\u003Cimg data-rawwidth=\&800\& data-rawheight=\&533\& src=\&http:\u002F\\u002Fv2-b30dd74cdd517b180b96578_b.jpg\& class=\&origin_image zh-lightbox-thumb\& width=\&800\& data-original=\&http:\u002F\\u002Fv2-b30dd74cdd517b180b96578_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002F\u002F25\u002Fpython-3-is-killing-python.html\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EPython 3 is killing Python\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E\u003Cp\u003E很难预测社区如何反应,但是应该不会对现在的生态造成大破坏,甚至能看到从 CJS 平稳过渡到 ESM。主要有两个原因:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E1.与 CJS 严格向后兼容\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E那些不喜欢 ESM 的模块作者可以继续使用 CJS,保证自己不被排挤出局。这样他们自己的代码不会受到采用 ESM 的影响,降低迁移到另一个运行时的可能性,让 NPM 迁移到新生态变得容易。从 CJS 到 ESM 的重构给包维护者带来额外工作,不能指望所有人都有时间。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E2. CJS 在 ESM 中的无缝整合\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E从 ESM 导入 CJS 模块非常简单。需要注意的是,CJS 仅导出一个默认值。一旦处于 ESM,甚至可能根本不会注意到依赖关系使用的模块风格,尤其是与在 CJS 中使用 await import() 相比。\u003C\u002Fp\u003E\u003Cp\u003E由于 ESM 的这个优点以及其他有点,比如开箱即用的 \u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\u002Fwebpack.js.org\u002Fguides\u002Ftree-shaking\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003Etree shaking\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E 和浏览器兼容性,预计在未来几年内,我们可以看到向 ESM 的缓慢而稳定的过渡。CJS 的特性,如动态 require() 和猴子补丁导出,在 Node.js 社区一直是有争议的,不比 ESM 带来的好处。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Ch3\u003E这些对我来说意味着什么?\u003C\u002Fh3\u003E\u003Cp\u003E因为最近这些事情,很容易对目前存在的所有选择和限制感到困惑。在接下来,整理了开发人员面临的典型问题以及我们的回答:\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E现在需要重构现有的代码吗?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E不需要\u003C\u002Fb\u003E。Node.js 才刚刚开始实现 ESM,仍然有大量的工作要做。\u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Fthe-node-js-collection\u002Fan-update-on-es6-modules-in-node-js-42c958b890c\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003EJames M Snell 预计至少还需要一年时间\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E,还有很多变化的余地,所以现在重构是不安全的。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E应该在新代码中使用 ESM 吗?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cul\u003E\u003Cli\u003E\u003Cb\u003E如果你已经有或者打算使用像 webpack 这样的构建工具,答案是肯定的\u003C\u002Fb\u003E。这将更容易完成代码库的过渡,并使 tree shaking 成为可能。但要小心:一旦 Node.js 支持原生 ESM,可能需要重构其中的一些部分。\u003C\u002Fli\u003E\u003Cli\u003E\u003Cb\u003E如果你正在编写一个库,答案是也肯定的\u003C\u002Fb\u003E,你的模块使用者将受益于 tree shaking。\u003C\u002Fli\u003E\u003Cli\u003E\u003Cb\u003E如果你不想进行构建操作,或者正在编写一个 Node.js 应用程序,还是用 CJS 吧\u003C\u002Fb\u003E。\u003C\u002Fli\u003E\u003C\u002Ful\u003E\u003Cp\u003E\u003Cb\u003E现在应该使用 .mjs 吗?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E不要这样做\u003C\u002Fb\u003E,目前没有什么好处,工具支持依然薄弱。建议一旦原生 ESM 支持登陆 Node.js,尽快开始迁移。记住,\u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FHTTP\u002FBasics_of_HTTP\u002FMIME_types\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E浏览器只关心 MIME 类型,而不是文件扩展名\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E应该关心浏览器兼容性吗?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E\u003Cb\u003E是的,需要在一定程度上关注这个问题\u003C\u002Fb\u003E。 不应该在导入语句中省略 .js 扩展名,因为浏览器需要完整的 URL,无法像 Node.js 这样执行路径查询。同样,应该避免 index.js 文件。不过,人们并不会很快在浏览器中使用 NPM 软件包,因为仍然不能 bare 导入。\u003C\u002Fp\u003E\u003Cbr\u003E\u003Cp\u003E\u003Cb\u003E作为库作者该怎么办?\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E用 ESM 编写代码,并使用 \u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\u002Frollupjs.org\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003ERollup\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E 或 Webpack 转换成单个 CJS 模块,然后在 package.json 将 main 字段指向此 CJS 包,并将 \u003Ca href=\&http:\u002F\\u002F?target=https%3A\\u002Frollup\u002Frollup\u002Fwiki\u002Fpkg.module\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003Emodule\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E 字段指向原始 ESM。如果还使用 ESM 之外的其他新语言功能,则应编译成 ES5,并提供 CJS 和 ESM 的打包。这样,你的库用户仍然可以从 tree shaking 获利而无需对代码进行转换。\u003C\u002Fp\u003E\u003Cfigure\u003E\u003Cimg data-rawwidth=\&1000\& data-rawheight=\&667\& src=\&http:\u002F\\u002Fv2-bd86bff6c8b698b829b7e_b.jpg\& class=\&origin_image zh-lightbox-thumb\& width=\&1000\& data-original=\&http:\u002F\\u002Fv2-bd86bff6c8b698b829b7e_r.jpg\&\u003E\u003C\u002Ffigure\u003E\u003Cp\u003E看一下这些完成 tree shaking 的模块\u003Cbr\u003E\u003C\u002Fp\u003E\u003Cbr\u003E\u003Ch3\u003E总结\u003C\u002Fh3\u003E\u003Cp\u003E关于 ES 模块有很多不确定性。由于目前 Node.js 在实现上的权衡,开发人员担心可能会破坏 Node.js 的生态。\u003C\u002Fp\u003E\u003Cp\u003E这些还不会发生,有两个原因:\u003Cb\u003ECJS 的严格的后向兼容和 CJS 在 ESM 中的无缝集成\u003C\u002Fb\u003E。\u003C\u002Fp\u003E\u003Cp\u003E在 Node.js 发布原生 ESM 支持之前,应该仍然使用 Rollup 和 Webpack 等工具。它们在一定程度上模拟了 ESM 环境,但要注意它们不完全符合规范。此外,使用打包仍然是个\u003Ca href=\&http:\u002F\\u002F?target=https%3A\u002F\u002Fpeerigon.github.io\u002Ftalks\u002F-jsconf-is-future-frontend-tooling\u002F%2336\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E很好的选择\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E,一旦可以在浏览器中使用 NPM 软件包。\u003C\u002Fp\u003E\u003Cp\u003E我们 webpack 团队正在努力做一些工作,帮助开发者平稳过渡。为了这个目标,我们计划在 Node.js 的 ESM 支持成熟后,模拟 Node.js 导入 CJS 的方式。\u003C\u002Fp\u003E&,&state&:&published&,&sourceUrl&:&&,&pageCommentsCount&:0,&canComment&:false,&snapshotUrl&:&&,&slug&:,&publishedTime&:&T22:04:58+08:00&,&url&:&\u002Fp\u002F&,&title&:&JavaScript 模块现状&,&summary&:&ESM, CJS, UMD, AMD — 到底应该选择哪一个?原文作者:Johannes Ewald \u003Ca href=\&https:\\u002FJhnnns\& data-editable=\&true\& data-title=\&@Jhnnns\&\u003E@Jhnnns\u003C\u002Fa\u003E原文链接:\u003Ca href=\&https:\\u002Fwebpack\u002Fthe-state-of-javascript-modules-\& data-editable=\&true\& data-title=\&The state of JavaScript modules\& class=\&\&\u003EThe state of JavaScript modules\u003C\u002Fa\u003E已获原作者授权翻译及发布最近 \u003Ca href=\&https:\\u002Faddyosmani\u002Fstatus\u002F597313\& data-editable=\&true\& data-title=\&在 twitter\&\u003E在 twitter\u003C\u002Fa\u003E 上有很多关于 \u003Ca href=\&http:\\u002F\u002Fes6-modules-final.html\& data-editable=\&true\& data-title=\&ES Module\&\u003EES Module\u003C\u002Fa\u003E 现状的讨论,\u003Ca href=\&https:\\u002Fbradleymeck\u002Fstatus\u002F650944\& data-editable=\&true\& data-title=\&尤其是在 Node.js 上\&\u003E尤其是在 Node.js 上\u003C\u002Fa\u003E,他们计划引入新的文件扩展名 …&,&reviewingCommentsCount&:0,&meta&:{&previous&:null,&next&:null},&commentPermission&:&anyone&,&commentsCount&:10,&likesCount&:81},&next&:{&isTitleImageFullScreen&:false,&rating&:&none&,&titleImage&:&https:\u002F\\u002F50\u002Fv2-753c7bc89438_xl.jpg&,&links&:{&comments&:&\u002Fapi\u002Fposts\u002F2Fcomments&},&topics&:[{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&JavaScript&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&上海&},{&url&:&https:\u002F\\u002Ftopic\u002F&,&id&:&&,&name&:&Node.js&}],&adminClosedComment&:false,&href&:&\u002Fapi\u002Fposts\u002F&,&excerptTitle&:&&,&author&:{&bio&:&不同凡想,心成伟事。&,&isFollowing&:false,&hash&:&0d9b98af12015c94cff646a6fc0773b5&,&uid&:52,&isOrg&:false,&slug&:&stein.cun&,&isFollowed&:false,&description&:&https:\u002F\u002Fqianduan.group,JavaScript、Node.js、CoffeeScript,欢迎微信搜索「前端外刊评论」关注我们用心打造的公众号,每周推送高质量前端资讯!&,&name&:&寸志&,&profileUrl&:&https:\u002F\\u002Fpeople\u002Fstein.cun&,&avatar&:{&id&:&369e5e380&,&template&:&https:\u002F\\u002F50\u002F{id}_{size}.jpg&},&isOrgWhiteList&:false,&isBanned&:false},&column&:{&slug&:&FrontendMagazine&,&name&:&前端外刊评论&},&content&:&不知不觉,又到了每年一度的JavaScript中国开发者大会(暨中国本土最盛大的程序猿面基大会)马上又要召开了。如果你还不了解这是什么大会?:\u003Cblockquote\u003E\u003Ci\u003EJSConf China(JavaScript中国开发者大会)是一个为期两天的以技术开发者为中心的非营利国际性技术大会,主要关注JavaScript和Node.JS 方面的技术。期间我们将邀请众多国内外JavaScript社区著名的开发者来分享他们的知识及对JavaScript的独到见解。这里是过去几届活动的汇总链接:\u003Ca href=\&http:\u002F\\u002F?target=http%3A\\u002F\& class=\& external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E\u003Cspan class=\&invisible\&\u003Ehttp:\u002F\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&visible\&\\u002F\u003C\u002Fspan\u003E\u003Cspan class=\&invisible\&\u003E\u003C\u002Fspan\u003E\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E。\u003C\u002Fi\u003E\u003C\u002Fblockquote\u003E\u003Cp\u003E除了去年南京这一届没参加之外,外刊君都参加啦!大会T恤有一搭。\u003C\u002Fp\u003E\u003Cblockquote\u003E\u003Ci\u003E老婆:你的这些T恤都可以扔了啊! \u003C\u002Fi\u003E\u003C\u002Fblockquote\u003E\u003Cimg src=\&http:\u002F\\u002Fv2-4d4feb173cf44d1792743_b.jpg\& data-rawwidth=\&160\& data-rawheight=\&198\& class=\&content_image\& width=\&160\&\u003E\u003Cp\u003E这次就在家门口,那外刊君我是必须参加了。\u003C\u002Fp\u003E\u003Cp\u003E大会站点在这里:\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002F\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E2017 年 JavaScript 中国开发者大会\u003Ci class=\&icon-external\&\u003E\u003C\u002Fi\u003E\u003C\u002Fa\u003E,参会的讲师都已经陆续放了出来:\u003Cimg src=\&http:\u002F\\u002Fv2-1321c0ebe7bc7e5bdd702f1a738469ab_b.png\& data-rawwidth=\&1232\& data-rawheight=\&3052\& class=\&origin_image zh-lightbox-thumb\& width=\&1232\& data-original=\&http:\u002F\\u002Fv2-1321c0ebe7bc7e5bdd702f1a738469ab_r.png\&\u003E\u003Cb\u003E都是大神呐!!!\u003Cimg src=\&http:\u002F\\u002Fv2-2a1dfd9d0cffb3baa1385_b.jpg\& data-rawwidth=\&225\& data-rawheight=\&225\& class=\&content_image\& width=\&225\&\u003E\u003C\u002Fb\u003E\u003C\u002Fp\u003E\u003Cp\u003E好了最后送上购票链接,\u003Ca href=\&http:\u002F\\u002F?target=http%3A\u002F\\u002Fevent\u002F455850\& class=\& wrap external\& target=\&_blank\& rel=\&nofollow noreferrer\&\u003E购买 2017 JavaScript Conf China
门票\u003Ci class=\&icon-exter}

我要回帖

更多关于 js 页面之间的会话 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信