不要肆无忌惮地在你的项目中使用 ES78910 了~

如果我有故事,你有 star 吗~

故事背景

在一次 code review 中,我在我们的项目(项目基于 vue-cli 3 创建)中找到了这句代码 MDN

[1, 2, [3, 4, [5, 6]]].flat(Infinity); // [1, 2, 3, 4, 5, 6]

嗯嗯~多维数组扁平化,很酷炫霸拽吊炸天~

我再一看兼容性..

图片

打扰了..

先脑补一波互怼的画面

我 : 老哥,你这个 API 是 ES2019 新特性啊,万万使不得啊~

图片

同事: 我有 vue-cli 3 啊~ 他封装好了 Babel 啊, 我大 vue-cli 3 天下无敌啊~

我 : 我...我真想跳起来打他的膝盖啊~ 凭一句话 好像是毫无说服力啊,是时候表演真正的技术了..

说(睡)服同事

core-js

Modular standard library for JavaScript. Includes polyfills for ECMAScript up to 2019: promises, symbols, collections, iterators, typed arrays, many other features, ECMAScript proposals, some cross-platform WHATWG / W3C features and proposals like URL. You can load only required features or use it without global namespace pollution.

core-js 是 babel 转码的核心包,它使用 es5 API实现了一些 ECMAScript 到 2019 年的 polyfills,并且提供按需加载,且使用它不污染全局名称空间。

@babel/preset-env

@babel/preset-env is a smart preset that allows you to use the latest JavaScript without needing to micromanage which syntax transforms (and optionally, browser polyfills) are needed by your target environment(s). This both makes your life easier and JavaScript bundles smaller!

@babel/preset-env 是一个智能插件集合,允许您使用最新的 JavaScript ,而不需要对目标环境所需的API转换(以及可选的 browser polyfills)进行微管理。这不仅使您的生活更轻松,而且 JavaScript 包也更小!

下面我们简单了解一下它的其中两个核心配置项.

useBuiltIns

"usage" | "entry" | false, defaults to false.

(提供"usage" | "entry" | false 三个配置项,默认值为 false)

This option configures how @babel/preset-env handles polyfills.

(这个配置项用来决定@babel/preset-env 如何处理 polyfills)

When either the usage or entry options are used, @babel-preset-env will add direct references to core-js modules as bare imports (or requires). This means core-js will be resolved relative to the file itself and needs to be accessible.

(当使用 usage 或 entry 配置项时,@babel-preset-env 将直接(entry)引用(或按需(usage)引入)core-js 模块,这意味着 core-js 将对文件本身进行解析)

Since @babel/polyfill was deprecated in 7.4.0, we recommend directly adding core-js and setting the version via the corejs option.

(由于@babel/polyfill 在 7.4.0 中被弃用,我们建议直接添加 core-js 并通过 corejs 选项设置版本。)

corejs

2, 3 or { version: 2 | 3, proposals: boolean }, defaults to 2.

(指定 corejs 版本,2 或 3,默认值为 2)

This option only has an effect when used alongside useBuiltIns: usage or useBuiltIns: entry, and ensures @babel/preset-env injects the correct imports for your core-js version.

(此选项只有在 useBuiltIns 选项配置为 entry 或 usage 时才生效,并确保@babel/preset-env 为您的 core-js 版本注入正确的引入)

Ok,接下来我们来看一哈 Vue-cli 3 的 babel 配置~

// babel.config.js
module.exports = {
  presets: ['@vue/app']
};

可以看到 vue-cli 3 这边用的预设集合是自己封装的@vue/app,我们在 node_modules 找到@vue/app 的 package.json

图片
// package.json

"dependencies":{

  "@babel/preset-env": "^7.0.0 < 7.4.0",

  "core-js": "^2.6.5"
}

可以看到依赖里有 core-js 2.x 版本和@babel/preset-env ~

打开@vue/app 的 index.js

//index.js  部分代码

const envOptions = {
  spec,
  loose,
  debug,
  modules,
  targets,
  useBuiltIns, //  划重点,此处值 已定义为 'usage'
  ignoreBrowserslistConfig,
  configPath,
  include,
  exclude: polyfills.concat(exclude || []),
  shippedProposals,
  forceAllTransforms
};

presets.unshift([require('@babel/preset-env'), envOptions]);

由上,我们可以得出结论,vue-cli 使用的 vue-preset-app 封装了@babel/preset-env`,且配置

useBuiltIns: 'usage';

corejs 没做配置,所以为默认值 2

useBuiltIns: 'usage';
corejs: 2;

这么一看,结合我们上面所讲知识,flat 是应该会被转成 es5 咯 ? 啪啪啪,打脸?

倔强的我上 github 打开了 core-js

图片

奇怪的是,我在 core-js 2.65 版本里并没有找到 flat API的实现.

图片

求知欲爆炸的我,翻了 core-js@3 的文档,找到了以下这段话

图片

发现 Array.prototype.flat API是在 core-js@3 才加入的。

图片

结论

vue-cli 3 使用的是 core-js2.x 版本,所以并不能转义 Arrary.prototype.flat 这个API。

实践

得出理论 不实践一波 好像不符合我的风格啊~

npm init -y

npm i @babel/core @babel/preset-env -D
const babel = require('@babel/core');

const code = `[1, 2, 3, 4, [5, 6, [7, 8]]].flat(Infinity);`;
const ast = babel.transform(code, {
  presets: [
    [
      '@babel/preset-env',
      {
        useBuiltIns: 'usage',
        corejs: 2
      }
    ]
  ]
});
// 用core-js@2 来看看转码后的结果
console.log(ast.code);

// "use strict";

// [1, 2, 3, 4, [5, 6, [7, 8]]].flat(Infinity);
const babel = require('@babel/core');

const code = `[1, 2, 3, 4, [5, 6, [7, 8]]].flat(Infinity);`;
const ast = babel.transform(code, {
  presets: [
    [
      '@babel/preset-env',
      {
        useBuiltIns: 'usage',
        corejs: 3
      }
    ]
  ]
});
// 用core-js@3 来看看转码后的结果
console.log(ast.code);

// "use strict";

// require("core-js/modules/es.array.flat");

// require("core-js/modules/es.array.unscopables.flat");

// [1, 2, 3, 4, [5, 6, [7, 8]]].flat(Infinity);

ok~ 完美验证结论! 代码地址

vue-cli将在version 4 支持core-js 3

图片

思考

不可否认 vue-cli 是一个非常优秀的脚手架,它提供了一个很 nice 的工程化解决方案。

webpack 构建

babel 编译

postcss 兼容

...

我在一些简历上 经常看到 熟练使用 xxx 脚手架,难道我们应该熟练的是使用脚手架吗 ?

我们在享受工具带给我们的便利跟快感时,是不是也应该想想自己对前端工程化了解多少呢 ?

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容