babel7 從新理解

測試環境

node 10.14.1
Babel 7.4.3node

Babel 是什麼?

Babel 是一個工具鏈,主要用於將 ECMAScript2015+版本的代碼轉換爲向後兼容的 Javascript 代碼,以便可以運行在當前和舊版本的瀏覽器或其餘環境中。android

Babel 主要功能點:

  • 語法轉換
  • 墊片兼容處理,經過 Polyfill 方式在目標環境中添加缺失的特性
  • 源碼轉換
  • 其餘...

使用理念

  1. Babel 主要經過 插件 plugins 的形式 達到轉換代碼的目的。
  2. Babel 自己內置了部分環境預設 preset-env,固然項目中 須要根據實際 進行配置。
  3. 爲了方便書寫參數,通常經過 配置文件的方式 babel.config.js 或者.babelrc.js(以編程的方式建立配置)或者.bablerc

Babel 編譯兩大核心

- 語法轉換
- 墊片支持

Bable 核心模塊

@babel/core

Babel 語法轉換核心功能,內置 helpers 插件模塊,是語法轉換的主要輔助工具es6

@babel/preset-env

這是一個很是智能的環境預設模塊,根據 env 配置自動 分析查找對應的 helper 和 plugins 進行代碼編譯轉換
基本使用:chrome

presets: [
  [
    '@babel/preset-env',
    {
      targets: {
        chrome: '77',
        android: '2',
      },
      debug: true,
      useBuiltIns: false,
    },
  ],
],

其餘參數參考文檔配置就行了,這裏重點分析一下 useBuiltIns 屬性.
targets 可根據文檔自行配置,這個比較簡單。
debug 調試模式,建議開啓,開啓以後能夠看到 那些 target 使用了那些 plugins 和 polyfill編程

// 開啓debug 模式的構建信息
Using targets:
{
  "android": "2",
  "chrome": "77"
}

Using modules transform: auto

Using plugins:
  transform-template-literals { "android":"2" }
  transform-literals { "android":"2" }
  transform-function-name { "android":"2" }
  transform-arrow-functions { "android":"2" }
  ......
  ......

Using polyfills with `usage` option:

[/Users/weng/Documents/dongsheng/projects/bable/src/app.js] Added following core-js polyfills:
  es6.object.set-prototype-of { "android":"2" }
  es6.object.create { "android":"2" }
  es6.symbol { "android":"2" }
  es7.symbol.async-iterator { "android":"2" }

[/Users/weng/Documents/dongsheng/projects/bable/src/app.js] Added following core-js polyfills:
  es6.string.includes { "android":"2" }
  es7.array.includes { "android":"2" }
  es6.array.of { "android":"2" }

useBuiltIns 屬性使用:api

  • false 不開啓 polyfill 處理,只作語法代碼轉換。
  • usage 開啓 polyfill 處理(依賴@babel/polyfill 模塊)
  • entry 開啓 polyfill 處理(依賴@babel/polyfill 模塊)
    useBuiltIns 的值只要不爲 false,就不啓動 polyfill 兼容,其餘值都會引入 polyfill,存在全量變量污染的特性。

@babel/plugin-transform-runtime & @babel/runtime & @babel/runtime-corejs2

正常狀況下,每一個文件都有局部引入自身的 helpers 函數實現,打包後放置在文件的最頂部。
因此存在一個狀況,多個文件使用了一樣的語法,那麼一樣的 helpers 會屢次引入。
transform-runtime 就是解決這個問題的。
transform-runtime 爲了減小代碼量,引入的 helpers 只保留一份
看個栗子:
源代碼:瀏覽器

//app.js
import { add } from './add';
function app() {
  add(1, 2);
  console.log(Object.assign({}, { ...{ name: 'd' } }));
  const _a = Array.of(3, 11, 8);
}
app();
export function add(a, b) {
  console.log('加法:');
  console.log(Object.assign({}, { ...a }));
}
// 不啓動 transform-runtime 構建後:
// 包含了多個一樣的 helpers

不啓動transform-runtime

plugins: ['@babel/plugin-transform-runtime'];
// 一樣的helpers只加載一次,可是沒有 方法api的實現

啓動transform-runtime

// corejs設置版本號:2或者3,都會引入非實例方法api的兼容實現
plugins: [
  [
    '@babel/plugin-transform-runtime',
    {
      corejs: 2,
    },
  ],
];

啓動transform-runtime-corejs2

transform-runtime 也是作兼容的:babel

  • @babel/runtime 只作 語法轉換的(helpers 和 regenerator),只作語法轉換, 沒有新 api 的實現
  • @balel/runtime-corejs2 除了 helpers 和 regenarator ,還有 core-js 墊片兼容實現,替換 非實例方法

prest-env 影響 語法轉換 和 墊片兼容
並且自身還兼容了 默認的 代碼轉換功能,根據具體 env 分析要使用的 pluginsapp

語法轉換 和 墊片兼容 是兩個 獨立功能,只不過都是 根據 env 來 實現目標轉換.async

相關文章
相關標籤/搜索