不要肆無忌憚地在你的項目中使用 ES78910 了~

若是我有故事,你有 star 嗎~css

故事背景

在一次 code review 中,我在咱們的項目(項目基於 vue-cli 3 建立)中找到了這句代碼 MDN前端

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

嗯嗯~多維數組扁平化,很酷炫霸拽吊炸天~vue

我再一看兼容性..node

圖片

打擾了..webpack

先腦補一波互懟的畫面git

我 : 老哥,你這個 API 是 ES2019 新特性啊,萬萬使不得啊~github

圖片

同事: 我有 vue-cli 3 啊~ 他封裝好了 Babel 啊, 我大 vue-cli 3 天下無敵啊~web

我 : 我...我真想跳起來打他的膝蓋啊~ 憑一句話 好像是毫無說服力啊,是時候表演真正的技術了..vue-cli

說(睡)服同事

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.npm

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 腳手架,難道咱們應該熟練的是使用腳手架嗎 ?

咱們在享受工具帶給咱們的便利跟快感時,是否是也應該想一想本身對前端工程化了解多少呢 ?

相關文章
相關標籤/搜索