write once,run everywhere--Babel 7.x

我這一輩子都在等待着,只是不知道到底在等誰  --- 幸福終點站javascript

做爲程序猿,對象歷來都是 new 啊! 😂😂😂css

const GF = new Object();
GF.happy(console.log("see a film with you On this Chinese Valentine's Day"));
複製代碼

前言

曾幾什麼時候,compile once,run everywhere 的 java 魅力無窮,吸引着不少的有志之士投入到其麾下。那時,javascript 還在爲規範到底遵循誰打的熱火朝天,ie 瀏覽器從引領 javascript 發展,到後來被嫌棄的不要不要的,寫個代碼還要考慮是否須要考慮兼容 ie (固然不止 ie ,這裏只是爲了嫌棄 ie)確實會讓人奔潰。隨着 Neo (Node) 的出現,自此 javascript 的發展迅速,竟有與 java 一爭世界最好語言之實力。許多有志之士夜以繼日苦思冥想 write once,run everywhere,終得解決之法---Babel。前端工程師喜大普奔,奔走相告,愈來愈多的前端工程師與產品經理握手言和。自此 javascript 一掃當初疲態,在高級語言的爭霸中顯露崢嶸,竟有稱王之勢。html

隨意杜撰的,😉😉😉,想一想三個月以前下定決心全棧,一路走來,已被 javascript 的魅力所折服,竟有想放棄 java 的念頭(俺只是擔憂之後光頭啊,只有光(熬)頭(夜)才能變強)前端

package.json

第一次接觸 javascript 的時候,內心是很抵觸的,一想我心愛的 java 有 maven 做爲依賴管理,我還在 html 中引入 javascript 文件,引入以前還要去依賴庫下載對應版本的類庫,嫌棄之情溢於言表。後來瞭解到了 package.json,Neo(Node) 救世主之名絕非浪得虛名啊。java

{
   "name": "fly-babel",
   "version": "1.0.0",
   "main": "index.js",
   "license": "MIT",
   "private": true,
   "scripts": {
       "babel": "./node_modules/.bin/babel src --out-dir lib"
   },
   "dependencies": {
       "@babel/runtime": "^7.5.5",
       "core-js": "3"
   },
   "devDependencies": {
       "@babel/cli": "^7.5.5",
       "@babel/core": "^7.5.5",
       "@babel/plugin-transform-runtime": "^7.5.5",
       "@babel/preset-env": "^7.5.5"
   }
}
複製代碼

運行 yarn babel 將 src 下面的代碼編譯輸出到 libnode

scripts 主要是用於運行腳本的。好比 yarn babel 或 yarn run babel 或 npm run babelreact

dependencies 主要是寫的代碼所需依賴庫,好比你引用的工具類庫 lodash ,項目打包的時候,這些依賴會打包進項目中android

devDependencies 是開發環境依賴,最終打包不會打到項目中webpack

yarn

yarn 中文文檔ios

一款比 Npm 更智能強大的依賴包管理器,用的人都說好,誰用誰知道

yarn 初始化項目

yarn init
複製代碼

全局安裝 yarn

# Mac 真是開發利器啊
brew install yarn
 # 使用 npm 安裝
npm install -g yarn
複製代碼

驗證 yarn 是否安裝成功

yarn --version
複製代碼

配置淘寶鏡像

yarn config set registry http://registry.npm.taobao.org/
複製代碼

安裝項目依賴

yarn install
複製代碼

添加項目依賴

# 添加最新版本 lodash 到生產依賴
yarn add [package]
# 添加指定版本
yarn add [package]@[version]
yarn add lodash
複製代碼

添加開發環境依賴

yarn add --dev [package]
# 添加 lodash 到開發依賴
yarn add --dev lodash
複製代碼

升級項目依賴

# 圖形化界面
yarn upgrade-interactive --latest

yarn upgrade [package]
 # 升級到指定版本
yarn upgrade [package]@[version]
複製代碼

移除依賴

yarn remove [package]
 # 移除 lodash
yarn remove lodash
複製代碼

運行 package.json 中的自定義命令

yarn run 
yarn run babel
yarn babel
複製代碼

Babel

記得使用是 Babel 7.x

Bablel 中文官方網站

Babel 在線轉換

答應我,官方網站資料必定要看哦,畢竟是一手資料。能夠先在在線轉換上體驗下,class 到底編譯成了什麼,推薦看下 Babel 7使用總結,官方文檔加這篇資料差很少就明白了 Babel 了。

安裝依賴

# 安裝開發依賴
yarn add --dev @babel/core @babel/cli @babel/preset-env @babel/runtime @babel/plugin-transform-runtime
 # 安裝項目依賴
yarn add core-js @babel/runtime
複製代碼

配置文件選擇---babel.config.js

js 文件可使用 javascript ,可擴展性較高,可使用 node 的 api。

.babelrc 是 json 格式,連註釋都加不了,難搞哦。不過項目中的子項目仍是能夠用.babelrc,babel.config.js 做爲整個項目全局配置。

// babel.config.js 配置文件
/** * @author: 張攀欽 * @description: babel 全局配置 * 一、plugins優先於presets進行編譯; * 二、plugins按照數組的index增序(從數組第一個到最後一個)進行編譯; * 三、presets按照數組的index倒序(從數組最後一個到第一個)進行編譯, */
module.exports = function (api) {
    api.cache(true);
    const babelrcRoots = [
        // Keep the root as a root
        ".",

        // Also consider monorepo packages "root" and load their .babelrc files.
        "./packages/*"
    ]
    const presets = [
        [
            "@babel/preset-env",
            {
                // 配置須要兼容的環境
                // chrome, edge, firefox, safari, ie, ios, node,android
                targets: {
                    ie: "8",
                    chrome: "67",
                    "browsers": ["> 1%", "last 2 versions", " ie>8", "android >= 4.0", "ios >= 7"]
                },
                // 是否輸出啓用的plugins列表
                debug: true,
                loose: true,
                // 模塊使用 es modules ,配置爲 "auto" 使用 commonJS 規範,
                modules: false,
                // 墊片使用 core.js
                corejs: 3,
                // 按需加載運用 polyfill
                useBuiltIns: "usage",
            },
        ],
    ];
    const plugins = [["@babel/plugin-transform-runtime", {
        corejs: 3,
        absoluteRuntime: false,
        helpers: true,
        regenerator: true,
        // 使用 es modules helpers
        useESModules: true
    }]];
    // 測試取 Node 相關變量
    if (process.env.NODE_ENV === "development") {
        console.log('開發環境', process.env);
    }
    return {
        presets,
        plugins, babelrcRoots
    };
}
複製代碼

這是我目前使用的配置,之後添加新的東東了,再來補充

presets 引入一些經常使用插件集合,@babel/preset-env 這個包含 es 中經常使用的語法轉換(@babel/preset-env則默認狀況下將轉換全部ECMAScript 2015+代碼。),而不用一個個添加到 plugins

plugins 引入特殊的插件進行墊片

小試牛刀

  • 源碼文件
[1, 2, 3].map((n) => n + 1);
class FlyYou {
    fly () {
        console.log('m fly you');
    }

    static sleep () {
        console.log('m sleep');
    }
}
console.log(Object.assign({}, { age: 1 }));
const arr = [1, 2, 3];
console.log('arr 是否包含 1:', arr.includes(1));
Promise.resolve('demo-1.js-Promise.resolve').then(data => console.log(data));
複製代碼
  • Babel 轉義以後的代碼
import "core-js/modules/es.object.to-string";
import "core-js/modules/es.promise";
import _Promise from "@babel/runtime-corejs3/core-js-stable/promise";
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
import _Object$assign from "@babel/runtime-corejs3/core-js-stable/object/assign";
import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";

var _context;

_mapInstanceProperty(_context = [1, 2, 3]).call(_context, function (n) {
  return n + 1;
});

var FlyYou =
/*#__PURE__*/
function () {
  function FlyYou() {}

  var _proto = FlyYou.prototype;

  _proto.fly = function fly() {
    console.log('m fly you');
  };

  FlyYou.sleep = function sleep() {
    console.log('m sleep');
  };

  return FlyYou;
}();

console.log(_Object$assign({}, {
  age: 1
}));
var arr = [1, 2, 3];
console.log('arr 是否包含 1:', _includesInstanceProperty(arr).call(arr, 1));

_Promise.resolve('demo-1.js-Promise.resolve').then(function (data) {
  return console.log(data);
});
複製代碼
  • 轉義分析
import _Promise from "@babel/runtime-corejs3/core-js-stable/promise";
_Promise.resolve('demo-1.js-Promise.resolve').then(function (data) {
  return console.log(data);
});
複製代碼

這個代碼是沒有辦法單獨在瀏覽器運行的,須要結合 webpack 將依賴打包運行。咱們能夠看到 Promise 被 _Promise 替換,這個就是墊片(polyfill),意思就是引入新的依賴,來檢查運行環境是否有 Promise 實現,有的話用原生的 Promise ,沒有的話用依賴庫(@babel/runtime-corejs3/core-js-stable/promise)實現的 Promise 。

@babel/polyfill 與 @babel/runtime 區別

兩者都會提供墊片,可是 @babel/polyfill 會檢查運行環境是否實現了 api,沒有的話會直接修改原型或添加對象到 window。@babel/runtime 不會污染全局變量,Babel 7.X 兩者選其一便可。推薦用 @babel/runtime。

舉個例子,好比 ie 沒有實現 Promise,你使用 @babel/polyfill編譯以後的代碼,是能夠直接在瀏覽器控制檯訪問 Promise ,而 @babel/runtime 不會污染全局變量,控制檯訪問不到 Promise。

相關文章
相關標籤/搜索