- BabelJs 教程
- BabelJs - 首頁
- BabelJs - 概述
- BabelJs - 環境搭建
- BabelJs - CLI
- BabelJs - ES6 程式碼執行
- BabelJs - 使用 Babel 6 進行專案設定
- BabelJs - 使用 Babel 7 進行專案設定
- 將 ES6 特性轉換為 ES5
- 將 ES6 模組轉換為 ES5
- 將 ES7 特性轉換為 ES5
- 將 ES8 特性轉換為 ES5
- BabelJs - Babel 外掛
- BabelJs - Babel Polyfill
- BabelJs - Babel CLI
- BabelJs - Babel 預設
- 使用 Babel 和 Webpack
- 使用 Babel 和 JSX
- 使用 Babel 和 Flow
- 使用 BabelJS 和 Gulp
- BabelJs - 示例
- BabelJs 有用資源
- BabelJs - 快速指南
- BabelJs - 有用資源
- BabelJs - 討論
BabelJS - 快速指南
BabelJS - 概述
BabelJS 是一個 JavaScript 轉換器,它將新特性轉換為舊標準。這樣,這些特性就可以在舊版和新版瀏覽器上無縫執行。一位澳大利亞開發者 Sebastian McKenzie 啟動了 BabelJS。
為什麼選擇 BabelJS?
JavaScript 是瀏覽器理解的語言。我們使用不同的瀏覽器來執行我們的應用程式 - Chrome、Firefox、Internet Explorer、Microsoft Edge、Opera、UC 瀏覽器等。ECMA Script 是 JavaScript 語言規範;ECMA Script 2015 ES6 是穩定的版本,在所有新舊瀏覽器中都能正常工作。
在 ES5 之後,我們有了 ES6、ES7 和 ES8。ES6 釋出了許多新特性,並非所有瀏覽器都完全支援。ES7、ES8 和 ESNext(ECMA Script 的下一個版本)也是如此。目前尚不確定所有瀏覽器何時能夠相容所有釋出的 ES 版本。
如果我們計劃使用 ES6 或 ES7 或 ES8 特性來編寫程式碼,由於缺乏對新更改的支援,它可能會在某些舊版瀏覽器中中斷。因此,如果我們想在程式碼中使用 ECMA Script 的新特性,並希望它在所有可用的瀏覽器上執行,我們需要一個工具將我們的最終程式碼編譯成 ES5。
Babel 做的就是這件事,它被稱為轉換器,可以將程式碼轉換為我們想要的 ECMA Script 版本。它具有預設和外掛等特性,可以配置我們需要轉換程式碼的 ECMA 版本。使用 Babel,開發人員可以使用 JavaScript 中的新特性編寫程式碼。使用者可以使用 Babel 轉換程式碼;這些程式碼隨後可以在任何瀏覽器中使用,而不會出現任何問題。
下表列出了 ES6、ES7 和 ES8 中可用的特性 -
| 特性 | ECMA Script 版本 |
|---|---|
| Let + Const | ES6 |
| 箭頭函式 | ES6 |
| 類 | ES6 |
| Promise | ES6 |
| 生成器 | ES6 |
| 迭代器 | ES6 |
| 模組 | ES6 |
| 解構 | ES6 |
| 模板字面量 | ES6 |
| 增強物件 | ES6 |
| 預設、剩餘和擴充套件屬性 | ES6 |
| Async - Await | ES7 |
| 指數運算子 | ES7 |
| Array.prototype.includes() | ES7 |
| 字串填充 | ES8 |
BabelJS 管理以下兩個部分 -
- 轉換
- 填充
什麼是 Babel-轉換器?
Babel-轉換器將現代 JavaScript 的語法轉換為舊版瀏覽器可以輕鬆理解的形式。例如,箭頭函式、const、let 類將轉換為函式、var 等。這裡語法,即箭頭函式被轉換為普通函式,在兩種情況下功能相同。
什麼是 Babel-填充?
JavaScript 中添加了一些新特性,例如 Promise、Map 和 includes。這些特性可以用於陣列;同樣,當使用 Babel 進行轉換時,不會被轉換。如果新特性是方法或物件,我們需要將 Babel-填充與轉換一起使用才能使其在舊版瀏覽器上工作。
以下是 JavaScript 中可用的 ECMA Script 特性列表,可以進行轉換和填充 -
- 類
- 裝飾器
- Const
- 模組
- 解構
- 預設引數
- 計算屬性名
- 物件剩餘/擴充套件
- 非同步函式
- 箭頭函式
- 剩餘引數
- 擴充套件
- 模板字面量
可以填充的 ECMA Script 特性 -
- Promise
- Map
- Set
- Symbol
- Weakmap
- Weakset
- includess
- Array.from、Array.of、Array#find、Array.buffer、Array#findIndex
- Object.assign、Object.entries、Object.values
BabelJS 的特性
在本節中,我們將瞭解 BabelJS 的不同特性。以下是 BabelJS 最重要的核心特性 -
Babel-外掛
外掛和預設是 Babel 轉換程式碼的配置細節。Babel 支援許多外掛,如果我們知道程式碼將在哪個環境中執行,則可以單獨使用這些外掛。
Babel-預設
Babel 預設是一組外掛,即 babel-轉換器的配置細節,指示 Babel 以特定模式進行轉換。我們需要使用預設,其中包含我們希望程式碼轉換為的環境。例如,es2015 預設會將程式碼轉換為 es5。
Babel-填充
有些特性(例如方法和物件)無法轉換。在這種情況下,我們可以使用 babel-填充來促進在任何瀏覽器中使用這些特性。讓我們以 Promise 為例;為了使該特性在舊版瀏覽器中工作,我們需要使用填充。
Babel-填充
Babel-cli 帶有一系列命令,可以使用這些命令輕鬆地在命令列上編譯程式碼。它還具有外掛和預設等特性,可以與命令一起使用,從而可以輕鬆地一次性轉換程式碼。
使用 BabelJS 的優勢
在本節中,我們將瞭解與使用 BabelJS 相關的不同優勢 -
BabelJS 為新增到 JavaScript 的所有新特性提供向後相容性,並且可以在任何瀏覽器中使用。
BabelJS 能夠轉換以獲取 JavaScript 的下一個即將釋出的版本 - ES6、ES7、ESNext 等。
BabelJS 可以與 gulp、webpack、flow、react、typescript 等一起使用,使其功能非常強大,並且可以用於大型專案,從而使開發人員的生活更輕鬆。
BabelJS 還與 react JSX 語法一起使用,並且可以編譯成 JSX 形式。
BabelJS 支援外掛、填充、babel-cli,這使得它易於處理大型專案。
使用 BabelJS 的缺點
在本節中,我們將瞭解使用 BabelJS 的不同缺點 -
BabelJS 程式碼在轉換時會更改語法,這使得釋出到生產環境後難以理解程式碼。
與原始程式碼相比,轉換後的程式碼大小更大。
並非所有 ES6/7/8 或即將釋出的新特性都可以轉換,我們必須使用填充才能使其在舊版瀏覽器上工作。
這是 babeljs 的官方網站 https://babeljs.io/。
BabelJS - 環境搭建
在本節中,我們將學習如何為 BabelJS 設定環境。
要使用 BabelJS,我們需要以下設定 -
- NodeJS
- Npm
- Babel-CLI
- Babel-Preset
- 用於編寫程式碼的 IDE
NodeJS
要檢查系統中是否安裝了 nodejs,請在終端中鍵入node –v。這將幫助您檢視當前安裝在系統上的 nodejs 版本。
如果它沒有列印任何內容,請在您的系統上安裝 nodejs。要安裝 nodejs,請訪問 nodejs 的主頁 https://nodejs.com.tw/en/download/ 並根據您的作業系統安裝軟體包。
以下螢幕截圖顯示了 nodejs 的下載頁面 -
根據您的作業系統,安裝所需的軟體包。安裝 nodejs 後,npm 也會隨之安裝。要檢查 npm 是否已安裝,請在終端中鍵入npm –v。它應該顯示 npm 的版本。
BabelJS - CLI
Babel 帶有一個內建的命令列介面,可用於編譯程式碼。
建立一個您將在其中工作的目錄。在這裡,我們建立了一個名為babelproject的目錄。讓我們利用 nodejs 建立專案詳細資訊。
我們使用npm init建立專案,如下所示 -
這是我們建立的專案結構。
現在要使用 Babel,我們需要安裝 Babel cli、Babel 預設、Babel 核心,如下所示 -
babel-cli
執行以下命令以安裝 babel-cli -
npm install --save-dev babel-cli
babel-preset
執行以下命令以安裝 babel-preset -
npm install --save-dev babel-preset-env
babel-core
執行以下命令以安裝 babel-core -
npm install --save-dev babel-core
安裝後,以下是 package.json 中可用的詳細資訊 -
我們已將 babel 外掛安裝到專案的本地。這樣做是為了我們可以根據專案需求以及 babeljs 的不同版本在專案中以不同的方式使用 babel。Package.json 提供了所用 babeljs 的版本詳細資訊。
為了在專案中使用 babel,我們需要在 package.json 中指定如下 -
Babel 主要用於編譯 JavaScript 程式碼,這將具有向後相容性。現在,我們將用 ES6 -> ES5 或 ES7 -> ES5 以及 ES7->ES6 等編寫程式碼。
為了在執行時向 Babel 提供相同的說明,我們需要在根資料夾中建立一個名為 .babelrc 的檔案。它包含一個具有預設詳細資訊的 json 物件,如下所示 -
我們將建立 JavaScript 檔案 index.js 並使用 Babel 將其編譯為 es2015。在此之前,我們需要安裝 es2015 預設,如下所示 -
在 index.js 中,我們使用箭頭函式建立了一個函式,這是 es6 中新增的新特性。使用 Babel,我們將程式碼編譯為 es5。
要執行到 es2015,使用以下命令 -
npx babel index.js
輸出
它顯示了上面所示的 es5 中的 index.js 程式碼。
我們可以透過執行如下命令將輸出儲存到檔案中:
npx babel index.js --out-file index_es5.js
輸出
這是我們建立的檔案,index_es5.js:
BabelJS - ES6 程式碼執行
BabelJS 是一個 JavaScript 編譯器,它將新增到 JavaScript 中的新特性轉換為 ES5 或 React,具體取決於給定的預設或外掛。ES5 是 JavaScript 最古老的形式之一,並且可以無縫執行在新舊瀏覽器上。在本教程的大多數示例中,我們都將程式碼編譯成了 ES5。
我們已經看到了 ES6、ES7 和 ES8 中添加了許多特性,例如箭頭函式、類、Promise、生成器、非同步函式等。當在舊瀏覽器中使用任何新新增的特性時,它都會丟擲錯誤。BabelJS 有助於編譯程式碼,使其向後相容舊版瀏覽器。我們已經看到 ES5 在舊版瀏覽器上執行良好,沒有任何問題。因此,考慮到專案環境的詳細資訊,如果需要在舊版瀏覽器上執行,我們可以在專案中使用任何新特性,並使用 babeljs 將程式碼編譯成 ES5,然後在任何瀏覽器中使用它而不會出現任何問題。
讓我們考慮以下示例來理解這一點。
示例
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing</title>
</head>
<body>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
index.js 檔案
var _foo = () => {
return "Hello World"
};
alert(_foo());
輸出
當我們在 Chrome 瀏覽器中執行以上 html 時,我們得到以下輸出:
當 HTML 在 Firefox 中執行時,它會生成以下輸出:
當相同的 HTML 在 Internet Explorer 中執行時,它會生成以下語法錯誤:
我們使用了 ES6 箭頭函式;如上所示,它並不適用於所有瀏覽器。為了使其正常工作,我們使用 BabelJS 將程式碼編譯為 ES5,並在所有瀏覽器中使用它。
將使用 babeljs 將 js 檔案編譯為 es5,並在瀏覽器中再次檢查。
在 html 檔案中,我們將使用 index_new.js,如下所示:
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing</title>
</head>
<body>
<script type="text/javascript" src="index_new.js"></script>
</body>
</html>
index_new.js
"use strict";
var _foo = function _foo() {
return "Hello World";
};
alert(_foo());
Chrome 輸出
Firefox 瀏覽器輸出
IE 瀏覽器輸出
BabelJS - 使用 Babel 6 進行專案設定
在本章中,我們將瞭解如何在專案中使用 babeljs。我們將使用 nodejs 建立一個專案,並使用 http 本地伺服器來測試我們的專案。
建立專案設定
在本節中,我們將學習如何建立專案設定。
建立一個新目錄並執行以下命令建立專案:
npm init
輸出
執行後,上述命令會生成以下輸出:
以下是建立的 package.json:
我們將安裝開始使用 babeljs 所需的軟體包。我們將執行以下命令來安裝babel-cli、babel-core、babel-preset-es2015。
npm install babel-cli babel-core babel-preset-es2015 --save-dev
輸出
執行後,上述命令會生成以下輸出:
Package.json 更新如下:
我們需要 http 伺服器來測試 js 檔案。執行以下命令安裝 http 伺服器:
npm install lite-server --save-dev
我們在 package.json 中添加了以下詳細資訊:
在指令碼中,Babel 負責將 src 資料夾中的 scripts.js 轉換為 dev 資料夾中的 scripts.bundle.js。我們在 package.json 中添加了編譯所需程式碼的完整命令。此外,添加了build,它將啟動lite-server 來測試更改。
src/scripts.js 中的 JavaScript 如下所示:
class Student {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname +"-"+this.lname;
}
}
我們在 index.html 中呼叫了轉換後的指令碼,如下所示:
<html>
lt;head></head>
<body>
<script type="text/javascript" src="dev/scripts.bundle.js?a=11"></script>
<h1 id="displayname"></h1>
<script type="text/javascript">
var a = new Student("Siya", "Kapoor", "15", "Mumbai");
var studentdet = a.fullname;
document.getElementById("displayname").innerHTML = studentdet;
</script>
</body>
</html>
我們需要執行以下命令,它將呼叫 babel 並編譯程式碼。該命令將從 package.json 呼叫 Babel:
npm run babel
scripts.bundle.js 是在 dev 資料夾中建立的新 js 檔案:
dev/scripts.bundle.js 的輸出如下:
"use strict";
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var Student = function () {
function Student(fname, lname, age, address) {
_classCallCheck(this, Student);
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
_createClass(Student, [{
key: "fullname",
get: function get() {
return this.fname + "-" + this.lname;
}
}]);
return Student;
}();
現在讓我們執行以下命令來啟動伺服器:
npm run build
當命令執行時,它將在瀏覽器中開啟 url:
輸出
上述命令生成以下輸出:
BabelJS - 使用 Babel 7 進行專案設定
Babel 的最新版本 7 釋出了對現有軟體包的更改。安裝部分與 Babel 6 相同。Babel 7 中唯一的區別是所有軟體包都需要使用@babel/安裝,例如 @babel/core、@babel/preset-env、@babel/cli、@babel/polyfill 等。
這是一個使用 babel 7 建立的專案設定。
命令
執行以下命令啟動專案設定:
npm init
安裝以下軟體包
npm install --save-dev @babel/core npm install --save-dev @babel/cli npm install --save-dev @babel/preset-env
以下是建立的 package.json:
現在將在根資料夾中建立一個.babelrc檔案:
建立一個資料夾src/並在其中新增檔案main.js,並將您的程式碼寫入轉換為 es5。
src/main.js
let add = (a,b) => {
return a+b;
}
轉換命令
npx babel src/main.js --out-file main_es5.js
main_es5.js
"use strict";
var add = function add(a, b) {
return a + b;
};
Babel 7 的工作原理與 Babel 6 相同。唯一的區別是使用 @babel 安裝軟體包。
Babel 7 中有一些預設已棄用。列表如下:
- ES20xx 預設
- babel-preset-env
- babel-preset-latest
- Babel 中的階段預設
此外,軟體包中的年份也被刪除 - @babel/plugin-transform-es2015-classes現在為@babel/plugin-transform-classes
我們將再舉一個使用 typescript 並使用 typescript 預設和 babel 7 將其轉換為 Es2015 JavaScript 的示例。
要使用 typescript,我們需要安裝 typescript 軟體包,如下所示:
npm install --save-dev @babel/preset-typescript
在src/資料夾中建立test.ts檔案,並以 typescript 形式編寫程式碼:
test.ts
let getName = (person: string) => {
return "Hello, " + person;
}
getName("Siya");
.babelrc
命令
npx babel src/test.ts --out-file test.js
test.js
"use strict";
var getName = function getName(person) {
return "Hello, " + person;
};
getName("Siya");
BabelJS - 將 ES6 特性轉換為 ES5
在本章中,我們將瞭解新增到 ES6 中的特性。我們還將學習如何使用 BabelJS 將這些特性編譯為 ES5。
以下是我們將在本章中討論的各種 ES6 特性:
- Let + Const
- 箭頭函式
- 類
- Promise
- 生成器
- 解構
- 迭代器
- 模板字面量
- 增強物件
- 預設、剩餘和擴充套件屬性
Let + Const
Let 在 JavaScript 中宣告一個塊作用域區域性變數。請考慮以下示例以瞭解 let 的用法。
示例
let a = 1;
if (a == 1) {
let a = 2;
console.log(a);
}
console.log(a);
輸出
2 1
第一個控制檯列印 2 的原因是a使用let再次宣告,並且僅在if塊中可用。使用 let 宣告的任何變數僅在其宣告的塊內可用。我們使用 let 聲明瞭兩次變數 a,但它不會覆蓋 a 的值。
這是 var 和 let 關鍵字之間的區別。當您使用 var 宣告變數時,該變數將在函式的作用域內可用,或者如果宣告為全域性變數。
如果使用 let 宣告變數,則該變數在塊作用域內可用。如果在 if 語句內宣告,則它僅在 if 塊內可用。這同樣適用於 switch、for 迴圈等。
現在我們將看到使用 babeljs 將程式碼轉換為 ES5。
讓我們執行以下命令來轉換程式碼:
npx babel let.js --out-file let_es5.js
從 es6 到 es5 的 let 關鍵字的輸出如下:
使用 ES6 的 Let
let a = 1;
if (a == 1) {
let a = 2;
console.log(a);
}
console.log(a);
使用 babel 轉換為 ES5
"use strict";
var a = 1;
if (a == 1) {
var _a = 2;
console.log(_a);
}
console.log(a);
如果您檢視 ES5 程式碼,let 關鍵字將替換為var關鍵字。此外,if 塊內的變數被重新命名為_a,以獲得與使用let關鍵字宣告時相同的效果。
Const
在本節中,我們將學習 ES6 和 ES5 中 const 關鍵字的工作原理。Const 關鍵字也存在於作用域內;如果在外部,它將丟擲錯誤。一旦賦值,宣告的 const 變數的值就不能更改。讓我們考慮以下示例以瞭解 const 關鍵字的使用方法。
示例
let a =1;
if (a == 1) {
const age = 10;
}
console.log(age);
輸出
Uncaught ReferenceError: age is not defined at:5:13
以上輸出丟擲錯誤,因為 const age 在 if 塊內定義,並且在 if 塊內可用。
我們將瞭解使用 BabelJS 轉換為 ES5。
ES6
let a =1;
if (a == 1) {
const age = 10;
}
console.log(age);
命令
npx babel const.js --out-file const_es5.js
使用 BabelJS 轉換為 ES6
"use strict";
var a = 1;
if (a == 1) {
var _age = 10;
}
console.log(age);
對於 ES5,const 關鍵字將替換為 var 關鍵字,如上所示。
箭頭函式
與變量表達式相比,箭頭函式具有更短的語法。它也稱為胖箭頭函式或 lambda 函式。該函式沒有自己的 this 屬性。在此函式中,省略了關鍵字 function。
示例
var add = (x,y) => {
return x+y;
}
var k = add(3,6);
console.log(k);
輸出
9
使用 BabelJS,我們將以上程式碼轉換為 ES5。
ES6 - 箭頭函式
var add = (x,y) => {
return x+y;
}
var k = add(3,6);
console.log(k);
命令
npx babel arrowfunction.js --out-file arrowfunction_es5.js
BabelJS - ES5
使用 Babel,箭頭函式將轉換為變量表達式函式,如下所示。
"use strict";
var add = function add(x, y) {
return x + y;
};
var k = add(3, 6);
console.log(k);
類
ES6 帶來了新的類特性。類類似於 ES5 中可用的基於原型的繼承。class 關鍵字用於定義類。類就像特殊的函式,並且具有類似於函式表示式的相似之處。它有一個建構函式,在類內部呼叫。
示例
class Person {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname +"-"+this.lname;
}
}
var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;
輸出
Siya-Kapoor
ES6 - 類
class Person {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname +"-"+this.lname;
}
}
var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;
命令
npx babel class.js --out-file class_es5.js
BabelJS - ES5
使用 babeljs 添加了額外的程式碼以使類的功能與 ES5 中相同。BabelJs 確保功能與在 ES6 中一樣。
"use strict";
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var Person = function () {
function Person(fname, lname, age, address) {
_classCallCheck(this, Person);
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
_createClass(Person, [{
key: "fullname",
get: function get() {
return this.fname + "-" + this.lname;
}
}]);
return Person;
}();
var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;
Promise
JavaScript Promise 用於管理程式碼中的非同步請求。
它使生活更輕鬆並使程式碼保持簡潔,因為您管理來自具有依賴關係的非同步請求的多個回撥。Promise 提供了一種更好的處理回撥函式的方法。Promise 是 ES6 的一部分。預設情況下,當您建立一個 Promise 時,Promise 的狀態為 pending。
Promise 有三種狀態:
- pending(初始狀態)
- resolved(成功完成)
- rejected(失敗)
new Promise()用於構造一個 Promise。Promise 建構函式有一個引數,它是一個回撥函式。回撥函式有兩個引數 - resolve 和 reject;
這兩個都是內部函式。您編寫的非同步程式碼,即 Ajax 呼叫、影像載入、定時函式將進入回撥函式。
如果回撥函式中執行的任務成功,則呼叫 resolve 函式;否則,將使用錯誤詳細資訊呼叫 reject 函式。
以下程式碼行顯示了 Promise 結構呼叫:
var _promise = new Promise (function(resolve, reject) {
var success = true;
if (success) {
resolve("success");
} else {
reject("failure");
}
});
_promise.then(function(value) {
//once function resolve gets called it comes over here with the value passed in resolve
console.log(value); //success
}).catch(function(value) {
//once function reject gets called it comes over here with the value passed in reject
console.log(value); // failure.
});
ES6 Promise 示例
let timingpromise = new Promise((resolve, reject) => {
setTimeout(function() {
resolve("Promise is resolved!");
}, 1000);
});
timingpromise.then((msg) => {
console.log(msg);
});
輸出
Promise is resolved!
ES6 - Promise
let timingpromise = new Promise((resolve, reject) => {
setTimeout(function() {
resolve("Promise is resolved!");
}, 1000);
});
timingpromise.then((msg) => {
console.log(msg);
});
命令
npx babel promise.js --out-file promise_es5.js
BabelJS - ES5
"use strict";
var timingpromise = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("Promise is resolved!");
}, 1000);
});
timingpromise.then(function (msg) {
console.log(msg);
});
對於 Promise,在轉換時程式碼不會發生變化。我們需要使用 babel-polyfill 才能使其在舊版瀏覽器上執行。babel-polyfills 的詳細資訊在 babel - poyfill 章節中進行了說明。
生成器
生成器函式類似於普通的function。該函式具有特殊的語法 function*,在函式中使用 *,以及yield關鍵字在函式內部使用。這旨在在需要時暫停或啟動函式。普通的函式一旦執行開始,就不能在中間停止。它要麼執行完整函式,要麼在遇到 return 語句時停止。生成器在這裡的行為有所不同,您可以使用 yield 關鍵字停止函式,並在需要時透過再次呼叫生成器來啟動它。
示例
function* generatorfunction(a) {
yield a;
yield a +1 ;
}
let g = generatorfunction(8);
console.log(g.next());
console.log(g.next());
輸出
{value: 8, done: false}
{value: 9, done: false}
ES6 - 生成器
function* generatorfunction(a) {
yield a;
yield a +1 ;
}
let g = generatorfunction(8);
console.log(g.next());
console.log(g.next());
命令
npx babel generator.js --out-file generator_es5.js
BabelJS - ES5
"use strict";
var _marked = /*#__PURE__*/regeneratorRuntime.mark(generatorfunction);
function generatorfunction(a) {
return regeneratorRuntime.wrap(function generatorfunction$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return a;
case 2:
_context.next = 4;
return a + 1;
case 4:
case "end":
return _context.stop();
}
}
}, _marked, this);
}
var g = generatorfunction(8);
console.log(g.next());
console.log(g.next());
迭代器
JavaScript 中的迭代器返回一個 JavaScript 物件,該物件具有值。該物件還有一個名為 done 的標誌,它具有 true/false 值。如果它不是迭代器的末尾,則返回 false。讓我們考慮一個示例,並檢視迭代器在陣列上的工作原理。
示例
let numbers = [4, 7, 3, 10]; let a = numbers[Symbol.iterator](); console.log(a.next()); console.log(a.next()); console.log(a.next()); console.log(a.next()); console.log(a.next());
在以上示例中,我們使用了數字陣列,並使用Symbol.iterator作為索引在陣列上呼叫了一個函式。
使用陣列上的 next() 獲得的輸出如下:
{value: 4, done: false}
{value: 7, done: false}
{value: 3, done: false}
{value: 10, done: false}
{value: undefined, done: true}
輸出給出一個具有 value 和 done 作為屬性的物件。每次next()方法呼叫都會從陣列中獲取下一個值,並且 done 為 false。只有當陣列中的元素完成時,done 的值才會為 true。我們可以將其用於迭代陣列。還有更多可用的選項,例如for-of迴圈,其用法如下:
示例
let numbers = [4, 7, 3, 10];
for (let n of numbers) {
console.log(n);
}
輸出
4 7 3 10
當for-of 迴圈使用鍵時,它會提供陣列值的詳細資訊,如上所示。我們將檢查這兩種組合,並檢視 babeljs 如何將其轉換為 es5。
示例
let numbers = [4, 7, 3, 10];
let a = numbers[Symbol.iterator]();
console.log(a.next());
console.log(a.next());
console.log(a.next());
console.log(a.next());
console.log(a.next());
let _array = [4, 7, 3, 10];
for (let n of _array) {
console.log(n);
}
命令
npx babel iterator.js --out-file iterator_es5.js
輸出
"use strict";
var numbers = [4, 7, 3, 10];
var a = numbers[Symbol.iterator]();
console.log(a.next());
console.log(a.next());
console.log(a.next());
console.log(a.next());
console.log(a.next());
var _array = [4, 7, 3, 10];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = _array[Symbol.iterator](),
_step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
_iteratorNormalCompletion = true) {
var n = _step.value;
console.log(n);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
在 es5 中添加了for-of迴圈的更改。但是 iterator.next 保持不變。我們需要使用babel-polyfill才能使其在舊版瀏覽器中執行。Babel-polyfill 與 babel 一起安裝,並且可以從 node_modules 中使用,如下所示:
示例
<html>
<head>
<script type="text/javascript" src="node_modules/babel-polyfill/dist/polyfill.min.js"></script>
<script type="text/javascript" src="iterator_es5.js"></script>
</head>
<body>
<h1>Iterators</h1>
</body>
</html>
輸出
解構
解構屬性的行為類似於 JavaScript 表示式,它從陣列、物件中解包值。
以下示例將解釋解構語法的使用方法。
示例
let x, y, rem;
[x, y] = [10, 20];
console.log(x);
console.log(y);
[x, y, ...rem] = [10, 20, 30, 40, 50];
console.log(rem);
let z = 0;
({ x, y } = (z) ? { x: 10, y: 20 } : { x: 1, y: 2 });
console.log(x);
console.log(y);
輸出
10 20 [30, 40, 50] 1 2
以上程式碼行展示瞭如何將陣列右側的值分配給左側的變數。帶有...rem的變數獲取陣列中所有剩餘的值。
我們還可以使用條件運算子,如下所示,將左側物件中的值分配給變數。
({ x, y } = (z) ? { x: 10, y: 20 } : { x: 1, y: 2 });
console.log(x); // 1
console.log(y); // 2
讓我們使用 babeljs 將其轉換為 ES5。
命令
npx babel destructm.js --out-file destruct_es5.js
destruct_es5.js
"use strict";
var x = void 0,
y = void 0,
rem = void 0;
x = 10;
y = 20;
console.log(x);
console.log(y);
x = 10;
y = 20;
rem = [30, 40, 50];
console.log(rem);
var z = 0;
var _ref = z ? { x: 10, y: 20 } : { x: 1, y: 2 };
x = _ref.x;
y = _ref.y;
console.log(x);
console.log(y);
模板字面量
模板字面量是一種字串字面量,允許在其中使用表示式。它使用反引號(``)而不是單引號或雙引號。當我們說字串內的表示式時,這意味著我們可以在字串內使用變數、呼叫函式等。
示例
let a = 5;
let b = 10;
console.log(`Using Template literal : Value is ${a + b}.`);
console.log("Using normal way : Value is " + (a + b));
輸出
Using Template literal : Value is 15. Using normal way : Value is 15
ES6 - 模板字面量
let a = 5;
let b = 10;
console.log(`Using Template literal : Value is ${a + b}.`);
console.log("Using normal way : Value is " + (a + b));
命令
npx babel templateliteral.js --out-file templateliteral_es5.js
BabelJS - ES5
"use strict";
var a = 5;
var b = 10;
console.log("Using Template literal : Value is " + (a + b) + ".");
console.log("Using normal way : Value is " + (a + b));
增強物件字面量
在 es6 中,新增到物件字面量的新特性非常棒且實用。我們將逐步瞭解 ES5 和 ES6 中物件字面量的幾個示例。
示例
ES5
var red = 1, green = 2, blue = 3;
var rgbes5 = {
red: red,
green: green,
blue: blue
};
console.log(rgbes5); // {red: 1, green: 2, blue: 3}
ES6
let rgbes6 = {
red,
green,
blue
};
console.log(rgbes6); // {red: 1, green: 2, blue: 3}
如果檢視以上程式碼,ES5 和 ES6 中的物件有所不同。在 ES6 中,如果變數名與鍵相同,則不必指定鍵值。
讓我們看看使用 babel 編譯到 ES5 的結果。
ES6-增強物件字面量
const red = 1, green = 2, blue = 3;
let rgbes5 = {
red: red,
green: green,
blue: blue
};
console.log(rgbes5);
let rgbes6 = {
red,
green,
blue
};
console.log(rgbes6);
let brand = "carbrand";
const cars = {
[brand]: "BMW"
}
console.log(cars.carbrand); //"BMW"
命令
npx babel enhancedobjliteral.js --out-file enhancedobjliteral_es5.js
BabelJS - ES5
"use strict";
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value, enumerable: true, configurable: true, writable: true
});
} else { obj[key] = value; } return obj;
}
var red = 1,
green = 2,
blue = 3;
var rgbes5 = {
red: red,
green: green,
blue: blue
};
console.log(rgbes5);
var rgbes6 = {
red: red,
green: green,
blue: blue
};
console.log(rgbes6);
var brand = "carbrand";
var cars = _defineProperty({}, brand, "BMW");
console.log(cars.carbrand); //"BMW"
預設、剩餘和擴充套件屬性
在本節中,我們將討論預設、剩餘和擴充套件屬性。
預設
使用 ES6,我們可以對函式引數使用預設引數,如下所示。
示例
let add = (a, b = 3) => {
return a + b;
}
console.log(add(10, 20)); // 30
console.log(add(10)); // 13
讓我們使用 babel 將以上程式碼轉換為 ES5。
命令
npx babel default.js --out-file default_es5.js
BabelJS - ES5
"use strict";
var add = function add(a) {
var b = arguments.length > 1 >> arguments[1] !== undefined ? arguments[1] : 3;
return a + b;
};
console.log(add(10, 20));
console.log(add(10));
剩餘
剩餘引數以三個點(...)開頭,如下面的示例所示。
示例
let add = (...args) => {
let sum = 0;
args.forEach(function (n) {
sum += n;
});
return sum;
};
console.log(add(1, 2)); // 3
console.log(add(1, 2, 5, 6, 6, 7)); //27
在以上函式中,我們向 add 函式傳遞了 n 個引數。如果在 ES5 中新增所有這些引數,則必須依賴 arguments 物件來獲取引數的詳細資訊。使用 ES6,rest 可以幫助使用三個點定義引數,如上所示,我們可以遍歷它並獲得數字的總和。
注意 - 使用三個點(即剩餘引數)時,不能使用其他引數。
示例
let add = (...args, value) => { //syntax error
let sum = 0;
args.forEach(function (n) {
sum += n;
});
return sum;
};
以上程式碼將導致語法錯誤。
編譯到 es5 的結果如下。
命令
npx babel rest.js --out-file rest_es5.js
Babel -ES5
"use strict";
var add = function add() {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var sum = 0;
args.forEach(function (n) {
sum += n;
});
return sum;
};
console.log(add(1, 2));
console.log(add(1, 2, 5, 6, 6, 7));
擴充套件
擴充套件屬性也像剩餘引數一樣使用三個點。以下是一個工作示例,展示瞭如何使用擴充套件屬性。
示例
let add = (a, b, c) => {
return a + b + c;
}
let arr = [11, 23, 3];
console.log(add(...arr)); //37
現在讓我們看看以上程式碼是如何使用 babel 轉換的。
命令
npx babel spread.js --out-file spread_es5.js
Babel-ES5
"use strict";
var add = function add(a, b, c) {
return a + b + c;
};
var arr = [11, 23, 3];
console.log(add.apply(undefined, arr));
代理
代理是一個物件,您可以在其中定義屬性查詢、賦值、列舉、函式、呼叫等操作的自定義行為。
語法
var a = new Proxy(target, handler);
目標 和 處理程式 都是物件。
目標 是一個物件,也可以是另一個代理元素。
處理程式 將是一個物件,其屬性為函式,這些函式將在被呼叫時提供行為。
讓我們嘗試透過一個示例來理解這些特性。
示例
let handler = {
get: function (target, name) {
return name in target ? target[name] : "invalid key";
}
};
let o = {
name: 'Siya Kapoor',
addr: 'Mumbai'
}
let a = new Proxy(o, handler);
console.log(a.name);
console.log(a.addr);
console.log(a.age);
我們在以上示例中定義了目標和處理程式,並將其與代理一起使用。代理返回帶有鍵值對的物件。
輸出
Siya Kapoor Mumbai invalid key
現在讓我們看看如何使用 babel 將以上程式碼轉換為 ES5。
命令
npx babel proxy.js --out-file proxy_es5.js
Babel-ES5
'use strict';
var handler = {
get: function get(target, name) {
return name in target ? target[name] : "invalid key";
}
};
var o = {
name: 'Siya Kapoor',
addr: 'Mumbai'
};
var a = new Proxy(o, handler);
console.log(a.name);
console.log(a.addr);
console.log(a.age);
BabelJS - 將 ES6 模組轉換為 ES5
在本章中,我們將瞭解如何使用 Babel 將 ES6 模組轉換為 ES5。
模組
考慮這樣一種情況:需要重用 JavaScript 程式碼的部分內容。ES6 透過模組的概念來解決這個問題。
模組只不過是寫在檔案中的 JavaScript 程式碼塊。除非模組檔案匯出它們,否則模組中的函式或變數不可用於使用。
簡單來說,模組可以幫助您在模組中編寫程式碼,並僅公開程式碼中其他部分應訪問的部分。
讓我們考慮一個示例,以瞭解如何使用模組以及如何匯出它以便在程式碼中使用它。
示例
add.js
var add = (x,y) => {
return x+y;
}
module.exports=add;
multiply.js
var multiply = (x,y) => {
return x*y;
};
module.exports = multiply;
main.js
import add from './add';
import multiply from './multiply'
let a = add(10,20);
let b = multiply(40,10);
console.log("%c"+a,"font-size:30px;color:green;");
console.log("%c"+b,"font-size:30px;color:green;");
我有三個檔案:add.js 用於新增兩個給定數字,multiply.js 用於將兩個給定數字相乘,以及 main.js,它呼叫 add 和 multiply 並輸出控制檯。
為了在 main.js 中使用 add.js 和 multiply.js,我們必須首先匯出它們,如下所示。
module.exports = add; module.exports = multiply;
要在 main.js 中使用它們,我們需要匯入它們,如下所示。
import add from './add'; import multiply from './multiply'
我們需要模組打包器來構建檔案,以便我們可以在瀏覽器中執行它們。
我們可以這樣做:
- 使用 Webpack
- 使用 Gulp
ES6 模組和 Webpack
在本節中,我們將瞭解 ES6 模組是什麼。我們還將學習如何使用 webpack。
在開始之前,我們需要安裝以下包。
npm install --save-dev webpack npm install --save-dev webpack-dev-server npm install --save-dev babel-core npm install --save-dev babel-loader npm install --save-dev babel-preset-env
Package.json
我們在指令碼中添加了 pack 和 publish 任務,以便使用 npm 執行它們。以下是 webpack.config.js 檔案,它將構建最終檔案。
webpack.config.js
var path = require('path');
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: path.resolve(__dirname, 'dev'),
filename: 'main_bundle.js'
},
mode:'development',
module: {
rules: [
{
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['env']
}
}
]
}
};
執行命令 npm run pack 來構建檔案。最終檔案將儲存在 dev/ 資料夾中。
命令
npm run pack
建立了 dev/main_bundle.js 通用檔案。此檔案將 add.js、multiply.js 和 main.js 組合在一起,並將其儲存在 dev/main_bundle.js 中。
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string')
for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) {
return Object.prototype.hasOwnProperty.call(object, property);
};
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./src/main.js");
/******/ })
/************************************************************************/
/******/ ({
/***/ "./src/add.js":
/*!********************!*\
!*** ./src/add.js ***!
\********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval(
"\n\nvar add = function add(x, y) {\n return x + y;\n};
\n\nmodule.exports = add;
\n\n//# sourceURL = webpack:///./src/add.js?"
);
/***/ }),
/***/ "./src/main.js":
/*!*********************!*\
!*** ./src/main.js ***!
\*********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval(
"\n\nvar _add = __webpack_require__(/*! ./add */ \"./src/add.js\");
\n\nvar _add2 = _interopRequireDefault(_add);
\n\nvar _multiply = __webpack_require__(/*! ./multiply */ \"./src/multiply.js\");
\n\nvar _multiply2 = _interopRequireDefault(_multiply);
\n\nfunction _interopRequireDefault(obj) {
return obj >> obj.__esModule ? obj : { default: obj };
}
\n\nvar a = (0, _add2.default)(10, 20);
\nvar b = (0, _multiply2.default)(40, 10);
\n\nconsole.log(\"%c\" + a, \"font-size:30px;color:green;\");
\nconsole.log(\"%c\" + b, \"font-size:30px;color:green;\");
\n\n//# sourceURL = webpack:///./src/main.js?"
);
/***/ }),
/***/ "./src/multiply.js":
/*!*************************!*\
!*** ./src/multiply.js ***!
\*************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
eval(
"\n\nvar multiply = function multiply(x, y) {\n return x * y;\n};
\n\nmodule.exports = multiply;
\n\n//# sourceURL = webpack:///./src/multiply.js?"
);
/***/ })
/******/ });
命令
以下是在瀏覽器中測試輸出的命令。
npm run publish
在您的專案中新增 index.html。它呼叫 dev/main_bundle.js。
<html>
<head></head>
<body>
<script type="text/javascript" src="dev/main_bundle.js"></script>
</body>
</html>
輸出
ES6 模組和 Gulp
要使用 Gulp 將模組捆綁到一個檔案中,我們將使用 browserify 和 babelify。首先,我們將建立專案設定並安裝所需的包。
命令
npm init
在開始專案設定之前,我們需要安裝以下包。
npm install --save-dev gulp npm install --save-dev babelify npm install --save-dev browserify npm install --save-dev babel-preset-env npm install --save-dev babel-core npm install --save-dev gulp-connect npm install --save-dev vinyl-buffer npm install --save-dev vinyl-source-stream
安裝後的 package.json
現在讓我們建立 gulpfile.js,它將幫助執行將模組捆綁在一起的任務。我們將使用上面與 webpack 一起使用的相同檔案。
示例
add.js
var add = (x,y) => {
return x+y;
}
module.exports=add;
multiply.js
var multiply = (x,y) => {
return x*y;
};
module.exports = multiply;
main.js
import add from './add';
import multiply from './multiply'
let a = add(10,20);
let b = multiply(40,10);
console.log("%c"+a,"font-size:30px;color:green;");
console.log("%c"+b,"font-size:30px;color:green;");
此處建立了 gulpfile.js。使用者將使用 browserify 並使用 transform 轉換為 babelify。babel-preset-env 用於將程式碼轉換為 es5。
Gulpfile.js
const gulp = require('gulp');
const babelify = require('babelify');
const browserify = require('browserify');
const connect = require("gulp-connect");
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
gulp.task('build', () => {
browserify('src/main.js')
.transform('babelify', {
presets: ['env']
})
.bundle()
.pipe(source('main.js'))
.pipe(buffer())
.pipe(gulp.dest('dev/'));
});
gulp.task('default', ['es6'],() => {
gulp.watch('src/app.js',['es6'])
});
gulp.task('watch', () => {
gulp.watch('./*.js', ['build']);
});
gulp.task("connect", function () {
connect.server({
root: ".",
livereload: true
});
});
gulp.task('start', ['build', 'watch', 'connect']);
我們使用 browserify 和 babelify 來處理模組匯出和匯入,並將它們組合到一個檔案中,如下所示。
gulp.task('build', () => {
browserify('src/main.js')
.transform('babelify', {
presets: ['env']
})
.bundle()
.pipe(source('main.js'))
.pipe(buffer())
.pipe(gulp.dest('dev/'));
});
我們在 transform 中呼叫了帶有 presets env 的 babelify。
將包含 main.js 的 src 資料夾提供給 browserify 並儲存在 dev 資料夾中。
我們需要執行命令 gulp start 來編譯檔案。
命令
npm start
以下是 dev/ 資料夾中建立的最終檔案。
(function() {
function r(e,n,t) {
function o(i,f) {
if(!n[i]) {
if(!e[i]) {
var c = "function"==typeof require&&require;
if(!f&&c)return c(i,!0);if(u)return u(i,!0);
var a = new Error("Cannot find module '"+i+"'");
throw a.code = "MODULE_NOT_FOUND",a
}
var p = n[i] = {exports:{}};
e[i][0].call(
p.exports,function(r) {
var n = e[i][1][r];
return o(n||r)
}
,p,p.exports,r,e,n,t)
}
return n[i].exports
}
for(var u="function"==typeof require>>require,i = 0;i<t.length;i++)o(t[i]);return o
}
return r
})()
({1:[function(require,module,exports) {
"use strict";
var add = function add(x, y) {
return x + y;
};
module.exports = add;
},{}],2:[function(require,module,exports) {
'use strict';
var _add = require('./add');
var _add2 = _interopRequireDefault(_add);
var _multiply = require('./multiply');
var _multiply2 = _interopRequireDefault(_multiply);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var a = (0, _add2.default)(10, 20);
var b = (0, _multiply2.default)(40, 10);
console.log("%c" + a, "font-size:30px;color:green;");
console.log("%c" + b, "font-size:30px;color:green;");
},
{"./add":1,"./multiply":3}],3:[function(require,module,exports) {
"use strict";
var multiply = function multiply(x, y) {
return x * y;
};
module.exports = multiply;
},{}]},{},[2]);
我們將它用於 index.html,並在瀏覽器中執行它以獲取輸出。
<html>
<head></head>
<body>
<h1>Modules using Gulp</h1>
<script type="text/javascript" src="dev/main.js"></script>
</body>
</html>
輸出
BabelJS - 將 ES7 特性轉換為 ES5
在本章中,我們將學習如何將 ES7 特性轉換為 ES5。
ECMA Script 7 添加了以下新特性。
- 非同步-等待
- 指數運算子
- Array.prototype.includes()
我們將使用 babeljs 將它們編譯為 ES5。根據您的專案需求,還可以將程式碼編譯為任何 ecma 版本,例如 ES7 到 ES6 或 ES7 到 ES5。由於 ES5 版本最穩定並且在所有現代和舊版瀏覽器上都能正常工作,因此我們將程式碼編譯為 ES5。
非同步-等待
Async 是一個非同步函式,它返回一個隱式 Promise。Promise 要麼被 fulfilled 要麼被 rejected。非同步函式與普通標準函式相同。該函式可以具有 await 表示式,該表示式會暫停執行,直到它返回一個 Promise,一旦獲得 Promise,執行就會繼續。只有當函式為非同步函式時,await 才能工作。
以下是一個關於非同步和等待的工作示例。
示例
let timer = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve("Promise resolved after 5 seconds");
}, 5000);
});
};
let out = async () => {
let msg = await timer();
console.log(msg);
console.log("hello after await");
};
out();
輸出
Promise resolved after 5 seconds hello after await
在呼叫 timer 函式之前添加了 await 表示式。timer 函式將在 5 秒後返回 Promise。因此,await 將暫停執行,直到 timer 函式上的 Promise 被 fulfilled 或 rejected,然後繼續執行。
現在讓我們使用 babel 將以上程式碼轉換為 ES5。
ES7 - 非同步-等待
let timer = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve("Promise resolved after 5 seconds");
}, 5000);
});
};
let out = async () => {
let msg = await timer();
console.log(msg);
console.log("hello after await");
};
out();
命令
npx babel asyncawait.js --out-file asyncawait_es5.js
BabelJS - ES5
"use strict";
var timer = function timer() {
return new Promise(function (resolve) {
setTimeout(function () {
resolve("Promise resolved after 5 seconds");
}, 5000);
});
};
var out = async function out() {
var msg = await timer();
console.log(msg);
console.log("hello after await");
};
out();
Babeljs 不會編譯物件或方法;因此,此處使用的 Promise 不會被轉換,並將按原樣顯示。為了在舊版瀏覽器上支援 Promise,我們需要新增程式碼,這些程式碼將支援 Promise。現在,讓我們安裝 babel-polyfill,如下所示。
npm install --save babel-polyfill
它應該被儲存為依賴項,而不是開發依賴項。
要在瀏覽器中執行程式碼,我們將使用 node_modules\babel-polyfill\dist\polyfill.min.js 中的 polyfill 檔案,並使用 script 標籤呼叫它,如下所示。
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing</title>
</head>
<body>
<script src="node_modules\babel-polyfill\dist\polyfill.min.js" type="text/javascript"></script>
<script type="text/javascript" src="aynscawait_es5.js"></script>
</body>
</html>
當您執行以上測試頁面時,您將在控制檯中看到以下輸出。
指數運算子
** 是 ES7 中用於冪運算的運算子。以下示例展示了 ES7 中其工作原理,以及使用 babeljs 轉換的程式碼。
示例
let sqr = 9 ** 2; console.log(sqr);
輸出
81
ES6 - 冪運算
let sqr = 9 ** 2; console.log(sqr);
要轉換冪運算子,我們需要安裝一個外掛,如下所示。
命令
npm install --save-dev babel-plugin-transform-exponentiation-operator
將外掛詳細資訊新增到 .babelrc 檔案中,如下所示。
{
"presets":[
"es2015"
],
"plugins": ["transform-exponentiation-operator"]
}
命令
npx babel exponeniation.js --out-file exponeniation_es5.js
BabelJS - ES5
"use strict"; var sqr = Math.pow(9, 2); console.log(sqr);
Array.prototype.includes()
如果傳遞給它的元素存在於陣列中,則此特性返回 true,否則返回 false。
示例
let arr1 = [10, 6, 3, 9, 17];
console.log(arr1.includes(9));
let names = ['Siya', 'Tom', 'Jerry', 'Bean', 'Ben'];
console.log(names.includes('Tom'));
console.log(names.includes('Be'));
輸出
true true false
我們必須再次使用 babel-polyfill,因為 includes 是陣列上的方法,它不會被轉換。我們需要額外的步驟來包含 polyfill 以使其在舊版瀏覽器中工作。
ES6 - array.includes
let arr1 = [10, 6, 3, 9, 17];
console.log(arr1.includes(9));
let names = ['Siya', 'Tom', 'Jerry', 'Bean', 'Ben'];
console.log(names.includes('Tom'));
console.log(names.includes('Be'));
命令
npx babel array_include.js --out-file array_include_es5.js
Babel-ES5
'use strict';
var arr1 = [10, 6, 3, 9, 17];
console.log(arr1.includes(9));
var names = ['Siya', 'Tom', 'Jerry', 'Bean', 'Ben'];
console.log(names.includes('Tom'));
console.log(names.includes('Be'));
要在舊版瀏覽器中測試它,我們需要使用 polyfill,如下所示。
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing</title>
</head>
<body>
<script src="node_modules\babel-polyfill\dist\polyfill.min.js" type="text/javascript"></script>
<script type="text/javascript" src="array_include_es5.js"></script>
</body>
</html>
輸出
BabelJS - 將 ES8 特性轉換為 ES5
字串填充是新增到 javascript 中的新 ES8 特性。我們將研究一個簡單的示例,該示例將使用 babel 將字串填充轉換為 ES5。
字串填充
字串填充根據指定的長度從左側新增另一個字串。字串填充的語法如下所示。
語法
str.padStart(length, string); str.padEnd(length, string);
示例
const str = 'abc'; console.log(str.padStart(8, '_')); console.log(str.padEnd(8, '_'));
輸出
_____abc abc_____
ES8 - 字串填充
const str = 'abc'; console.log(str.padStart(8, '_')); console.log(str.padEnd(8, '_'));
命令
npx babel strpad.js --out-file strpad_es5.js
Babel - ES5
'use strict'; var str = 'abc'; console.log(str.padStart(8, '_')); console.log(str.padEnd(8, '_'));
js 必須與 babel-polyfill 一起使用,如下所示。
test.html
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing</title>
</head>
<body>
<script src="node_modules\babel-polyfill\dist\polyfill.min.js" type="text/javascript"></script>
<script type="text/javascript" src="strpad_es5.js"></script>
</body>
</html>
BabelJS - Babel 外掛
BabelJS 是一個 JavaScript 編譯器,它根據可用的預設和外掛更改給定程式碼的語法。Babel 編譯流程涉及以下三個部分。
- 解析
- 轉換
- 列印
傳遞給 Babel 的程式碼會原樣返回,只是語法發生了改變。我們已經看到過將預設新增到 .babelrc 檔案中,以將程式碼從 es6 編譯到 es5 或反之亦然。預設只不過是一組外掛。如果在編譯期間未提供預設或外掛的詳細資訊,Babel 不會進行任何更改。
現在讓我們討論以下外掛 -
- transform-class-properties
- Transform-exponentiation-operator
- For-of
- 物件 rest 和擴充套件
- async/await
現在,我們將建立一個專案設定並使用一些外掛進行操作,這將使我們對 Babel 中外掛的需求有更清晰的瞭解。
命令
npm init
我們必須為 Babel 安裝所需的包 - Babel CLI、Babel Core、Babel 預設等。
Babel 6 的包
npm install babel-cli babel-core babel-preset-es2015 --save-dev
Babel 7 的包
npm install @babel/cli @babel/core @babel/preset-env --save-dev
在你的專案中建立一個 js 檔案並編寫你的 js 程式碼。
類 - Transform-class-properties
為此,請觀察以下給出的程式碼 -
示例
main.js
class Person {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname + "-" + this.lname;
}
}
var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;
目前,我們還沒有向 Babel 提供任何預設或外掛的詳細資訊。如果我們碰巧使用以下命令轉換程式碼 -
npx babel main.js --out-file main_out.js
main_out.js
class Person {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname + "-" + this.lname;
}
}
var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;
我們將獲得與程式碼相同的輸出。現在讓我們將預設新增到 .babelrc 檔案中。
注意 - 在專案根目錄下建立 .babelrc 檔案。
.babelrc for babel 6
.babelrc for babel 7
{
"presets":["@babel/env"]
}
我們已經安裝了預設;現在讓我們再次執行命令 -
npx babel main.js --out-file main_out.js
main_out.js
"use strict";
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var Person = function () {
function Person(fname, lname, age, address) {
_classCallCheck(this, Person);
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
_createClass(Person, [{
key: "fullname",
get: function get() {
return this.fname + "-" + this.lname;
}
}]);
return Person;
}();
var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;
在 ES6 中,類語法如下
class Person {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname + "-" + this.lname;
}
}
存在建構函式,並且類的所有屬性都在其中定義。如果我們需要在類外部定義類屬性,則無法這樣做。
示例
class Person {
name = "Siya Kapoor";
fullname = () => {
return this.name;
}
}
var a = new Person();
var persondet = a.fullname();
console.log("%c"+persondet, "font-size:25px;color:red;");
如果我們碰巧編譯上述程式碼,它將在 Babel 中丟擲一個錯誤。這導致程式碼無法編譯。
為了使其按我們想要的方式工作,我們可以使用名為 babel-plugin-transform-class-properties 的 Babel 外掛。為了使其工作,我們需要先安裝它,如下所示 -
Babel 6 的包
npm install --save-dev babel-plugin-transform-class-properties
Babel 7 的包
npm install --save-dev @babel/plugin-proposal-class-properties
將外掛新增到 .babelrc 檔案中以供 Babel 6 使用 -
.babelrc for babel 7
{
"plugins": ["@babel/plugin-proposal-class-properties"]
}
現在,我們將再次執行命令。
命令
npx babel main.js --out-file main_out.js
main.js
class Person {
name = "Siya Kapoor";
fullname = () => {
return this.name;
}
}
var a = new Person();
var persondet = a.fullname();
console.log("%c"+persondet, "font-size:25px;color:red;");
編譯到 main_out.js
class Person {
constructor() {
this.name = "Siya Kapoor";
this.fullname = () => {
return this.name;
};
}
}
var a = new Person();
var persondet = a.fullname();
console.log("%c"+persondet, "font-size:25px;color:red;");
輸出
以下是我們在瀏覽器中使用時獲得的輸出 -
指數運算子 - transform-exponentiation-operator
** 是 ES7 中用於指數運算的運算子。以下示例顯示了 ES7 中相同運算子的工作原理。它還展示瞭如何使用 BabelJS 轉換程式碼。
示例
let sqr = 9 ** 2;
console.log("%c"+sqr, "font-size:25px;color:red;");
要轉換指數運算子,我們需要安裝以下外掛 -
Babel 6 的包
npm install --save-dev babel-plugin-transform-exponentiation-operator
Babel 7 的包
npm install --save-dev @babel/plugin-transform-exponentiation-operator
將外掛詳細資訊新增到 .babelrc 檔案中,如下所示,以供 Babel 6 使用 -
{
"plugins": ["transform-exponentiation-operator"]
}
.babelrc for babel 7
{
"plugins": ["@babel/plugin-transform-exponentiation-operator"]
}
命令
npx babel exponeniation.js --out-file exponeniation_out.js
exponeniation_out.js
let sqr = Math.pow(9, 2);
console.log("%c" + sqr, "font-size:25px;color:red;");
輸出
For-of
Babel 6 和 7 中外掛所需的包如下 -
Babel 6
npm install --save-dev babel-plugin-transform-es2015-for-of
Babel 7
npm install --save-dev @babel/plugin-transform-for-of
.babelrc for babel 6
{
"plugins": ["transform-es2015-for-of"]
}
.babelrc for babel 7
{
"plugins": ["@babel/plugin-transform-for-of"]
}
forof.js
let foo = ["PHP", "C++", "Mysql", "JAVA"];
for (var i of foo) {
console.log(i);
}
命令
npx babel forof.js --out-file forof_es5.js
Forof_es5.js
let foo = ["PHP", "C++", "Mysql", "JAVA"];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = foo[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var i = _step.value;
console.log(i);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
輸出
物件 rest 和擴充套件
Babel 6 和 7 中外掛所需的包如下 -
Babel 6
npm install --save-dev babel-plugin-transform-object-rest-spread
Babel 7
npm install --save-dev @babel/plugin-proposal-object-rest-spread
.babelrc for babel 6
{
"plugins": ["transform-object-rest-spread"]
}
.babelrc for babel 7
{
"plugins": ["@babel/plugin-proposal-object-rest-spread"]
}
o.js
let { x1, y1, ...z1 } = { x1: 11, y1: 12, a: 23, b: 24 };
console.log(x1);
console.log(y1);
console.log(z1);
let n = { x1, y1, ...z1};
console.log(n);
命令
npx babel o.js --out-file o_es5.js
o_es5.js
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i]; for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
function _objectWithoutProperties(obj, keys) {
var target = {};
for (var i in obj) {
if (keys.indexOf(i) >= 0) continue;
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
target[i] = obj[i];
}
return target;
}
let _x1$y1$a$b = { x1: 11, y1: 12, a: 23, b: 24 },
{ x1, y1 } = _x1$y1$a$b,
z1 = _objectWithoutProperties(_x1$y1$a$b, ["x1", "y1"]);
console.log(x1);
console.log(y1);
console.log(z1);
let n = _extends({ x1, y1 }, z1);
console.log(n);
輸出
async/await
我們需要為 Babel 6 安裝以下包 -
npm install --save-dev babel-plugin-transform-async-to-generator
Babel 7 的包
npm install --save-dev @babel/plugin-transform-async-to-generator
.babelrc for babel 6
{
"plugins": ["transform-async-to-generator"]
}
.babelrc for babel 7
{
"plugins": ["@babel/plugin-transform-async-to-generator"]
}
async.js
let timer = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve("Promise resolved after 5 seconds");
}, 5000);
});
};
let out = async () => {
let msg = await timer();
console.log(msg);
console.log("hello after await");
};
out();
命令
npx babel async.js --out-file async_es5.js
async_es5.js
function _asyncToGenerator(fn) {
return function () {
var gen = fn.apply(this, arguments);
return new Promise(function (resolve, reject) {
function step(key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
} if (info.done) {
resolve(value);
} else {
return Promise.resolve(value).then(function (value) {
step("next", value);
},
function (err) {
step("throw", err); });
}
} return step("next");
});
};
}
let timer = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve("Promise resolved after 5 seconds");
}, 5000);
});
};
let out = (() => {
var _ref = _asyncToGenerator(function* () {
let msg = yield timer();
console.log(msg);
console.log("hello after await");
});
return function out() {
return _ref.apply(this, arguments);
};
})();
out();
我們必須為此使用 polyfill,因為它在不支援 Promise 的瀏覽器中不起作用。
輸出
BabelJS - Babel Polyfill
Babel Polyfill 為 Web 瀏覽器添加了對尚不可用功能的支援。Babel 將程式碼從最新的 Ecma 版本編譯到我們想要的版本。它根據預設更改語法,但無法對使用的物件或方法執行任何操作。我們必須為這些功能使用 polyfill 以實現向後相容性。
可以進行 polyfill 的功能
以下是當在舊版瀏覽器中使用時需要 polyfill 支援的功能列表 -
- Promise
- Map
- Set
- Symbol
- Weakmap
- Weakset
- Array.from、Array.includes、Array.of、Array#find、Array.buffer、Array#findIndex
- Object.assign、Object.entries、Object.values
我們將建立專案設定,並檢視 Babel Polyfill 的工作原理。
命令
npm init
我們現在將安裝 Babel 所需的包。
Babel 6 的包
npm install babel-cli babel-core babel-preset-es2015 --save-dev
Babel 7 的包
npm install @babel/cli @babel/core @babel/preset-env --save-dev
這是最終的 package.json -
我們還將 es2015 新增到預設中,因為我們希望將程式碼編譯到 es5。
.babelrc for babel 6
.babelrc for babel 7
{
"presets":["@babel/env"]
}
我們將安裝 lite-serve,以便我們可以在瀏覽器中測試程式碼 -
npm install --save-dev lite-server
讓我們將 Babel 命令新增到 package.json 中以編譯我們的程式碼 -
我們還添加了 build 命令,該命令呼叫 lite-server。
Babel-polyfill 與 babel-core 包一起安裝。babel-polyfill 將在 node_modules 中可用,如下所示 -
我們將進一步研究 Promise 並與之一起使用 babel-polyfill。
ES6 - Promise
let timingpromise = new Promise((resolve, reject) => {
setTimeout(function() {
resolve("Promise is resolved!");
}, 1000);
});
timingpromise.then((msg) => {
console.log("%c"+msg, "font-size:25px;color:red;");
});
命令
npx babel promise.js --out-file promise_es5.js
BabelJS - ES5
"use strict";
var timingpromise = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("Promise is resolved!");
}, 1000);
});
timingpromise.then(function (msg) {
console.log("%c"+msg, "font-size:25px;color:red;");
});
編譯不需要更改任何內容。Promise 的程式碼已原樣轉換。但是,即使我們將程式碼編譯到 es5,不支援 Promise 的瀏覽器也會丟擲錯誤。
要解決此問題,我們需要在最終的 es5 編譯程式碼中新增 polyfill。要在瀏覽器中執行程式碼,我們將從 node_modules 中獲取 babel-polyfill 檔案並將其新增到我們要使用 Promise 的 .html 檔案中,如下所示 -
index.html
<html>
<head>
</head>
<body>
<h1>Babel Polyfill Testing</h1>
<script type="text/javascript" src="node_modules/babel-polyfill/dist/polyfill.min.js"></script>
<script type="text/javascript" src="promise_es5.js"></script>
</body>
</html>
輸出
在 index.html 檔案中,我們使用了來自 node_modules 的 polyfill.min.js 檔案,然後是 promise_es5.js -
<script type="text/javascript" src="node_modules/babel-polyfill/dist/polyfill.min.js"></script> <script type="text/javascript" src="promise_es5.js"></script>
注意 - polyfill 檔案必須在主 JavaScript 呼叫之前開始使用。
字串填充
字串填充根據指定的長度從左側新增另一個字串。字串填充的語法如下所示。
語法
str.padStart(length, string); str.padEnd(length, string);
示例
const str = 'abc'; console.log(str.padStart(8, '_')); console.log(str.padEnd(8, '_'));
輸出
_____abc abc_____
Babel - ES5
npx babel strpad.js --out-file strpad_es5.js
命令
'use strict'; var str = 'abc'; console.log(str.padStart(8, '_')); console.log(str.padEnd(8, '_'));
js 必須與 babel-polyfill 一起使用,如下所示。
test.html
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing </title>
</head>
<body>
<script src="node_modules/babel-polyfill/dist/polyfill.min.js" type="text/javascript"></script>
<script type="text/javascript" src="strpad_es5.js"></script>
</body>
</html>
Map、Set、WeakSet、WeakMap
在本節中,我們將學習Map、Set、WeakSet、WeakMap。
Map 是一個具有鍵/值對的物件。
Set 也是一個物件,但具有唯一值。
WeakMap 和 WeakSet 也是具有鍵/值對的物件。
Map、Set、WeakMap 和 WeakSet 是新增到 ES6 中的新功能。要將其轉換為在舊版瀏覽器中使用,我們需要使用 polyfill。我們將使用一個示例並使用 polyfill 編譯程式碼。
示例
let m = new Map(); //map example
m.set("0","A");
m.set("1","B");
console.log(m);
let set = new Set(); //set example
set.add('A');
set.add('B');
set.add('A');
set.add('B');
console.log(set);
let ws = new WeakSet(); //weakset example
let x = {};
let y = {};
ws.add(x);
console.log(ws.has(x));
console.log(ws.has(y));
let wm = new WeakMap(); //weakmap example
let a = {};
wm.set(a, "hello");
console.log(wm.get(a));
輸出
Map(2) {"0" => "A", "1" => "B"}
Set(2) {"A", "B"}
true
false
hello
命令
npx babel set.js --out-file set_es5.js
Babel-ES5
"use strict";
var m = new Map(); //map example
m.set("0", "A");
m.set("1", "B");
console.log(m);
var set = new Set(); //set example
set.add('A');
set.add('B');
set.add('A');
set.add('B');
console.log(set);
var ws = new WeakSet(); //weakset example
var x = {};
var y = {};
ws.add(x);
console.log(ws.has(x));
console.log(ws.has(y));
var wm = new WeakMap(); //weakmap example
var a = {};
wm.set(a, "hello");
console.log(wm.get(a));
js 必須與 babel-polyfill 一起使用,如下所示。
test.html
<!DOCTYPE html>
<html>
<head>
<title>BabelJs Testing</title>
</head>
<body>
<script src="node_modules/babel-polyfill/dist/polyfill.min.js" type="text/javascript"></script>
<script type="text/javascript" src="set_es5.js"></script>
</body>
</html>
輸出
陣列方法
可以在陣列上使用許多屬性和方法;例如,array.from、array.includes 等。
讓我們考慮使用以下示例來更好地理解這一點。
示例
arraymethods.js
var arrNum = [1, 2, 3]; console.log(arrNum.includes(2)); console.log(Array.from([3, 4, 5], x => x + x));
輸出
true [6, 8, 10]
命令
npx babel arraymethods.js --out-file arraymethods_es5.js
Babel-es5
"use strict";
var arrNum = [1, 2, 3];
console.log(arrNum.includes(2));
console.log(Array.from([3, 4, 5], function (x) {
return x + x;
}));
陣列上使用的方法按原樣列印。為了使其在舊版瀏覽器上工作,我們需要在開頭新增 polyfill 檔案,如下所示 -
index.html
<html>
<head></head>
<body>
<h1>Babel Polyfill Testing</h1>
<script type="text/javascript" src="node_modules/babel-polyfill/dist/polyfill.min.js"></script>
<script type="text/javascript" src="arraymethods_es5.js"></script>
</body>
</html>
輸出
BabelJS - Babel CLI
BabelJS 帶有一個內建的命令列介面,其中可以使用易於使用的命令輕鬆地將 JavaScript 程式碼編譯到相應的 ECMA Script。我們將在本章中討論這些命令的使用。
首先,我們將為我們的專案安裝 babel-cli。我們將使用 babeljs 編譯程式碼。
為你的專案建立一個資料夾以使用 babel-cli。
命令
npm init
顯示
為上述專案建立的 Package.json -
讓我們執行命令來安裝 babel-cli。
Babel 6 的包
npm install --save-dev babel-cli
Babel 7 的包
npm install --save-dev @babel/cli
顯示
我們已經安裝了 babel-cli,這是更新後的 package.json -
此外,我們需要安裝 babel-preset 和 babel-core。現在讓我們看看安裝命令。
Babel 6 的包
npm install --save-dev babel-preset-env npm install --save-dev babel-core
Babel 7 的包
npm install --save-dev @babel/core npm install --save-dev @babel/preset-env
這是上述命令的更新後的 package.json -
由於我們需要編譯我們將要編寫的 JavaScript 程式碼以具有向後相容性,因此我們將將其編譯為 ECMA Script 5。為此,我們需要指示 Babel 查詢預設,即將在其中進行編譯的 es 版本。我們需要在建立的專案根目錄中建立一個 .babelrc> 檔案,如下所示。
它包含一個具有以下預設詳細資訊的 json 物件 -
{ "presets": ["env"] }
對於 Babel 7,.babelrc 如下所示 -
{
"presets":["@babel/env"]
}
我們已將 Babel 本地安裝到專案中。為了在我們的專案中使用 Babel,我們需要在 package.json 中指定它,如下所示 -
編譯 JS 檔案
現在我們準備編譯我們的 JavaScript 檔案了。在你的專案中建立一個名為 src 的資料夾;在這個資料夾中,建立一個名為 main.js 的檔案並編寫如下所示的 es6 javascript 程式碼 -
命令
npx babel src/main.js
輸出
在上述情況下,來自 main.js 的程式碼在終端中以 es5 版本顯示。來自 es6 的箭頭函式轉換為 es5,如上所示。我們將儲存在不同的檔案中,而不是在終端中顯示編譯後的程式碼,如下所示。
我們在專案中建立了一個名為 out 的資料夾,我們希望將編譯後的檔案儲存在其中。以下命令將編譯並將輸出儲存在我們想要的位置。
命令
npx babel src/main.js --out-file out/main_out.js
輸出
命令中的 --out-file 選項幫助我們將輸出儲存在我們選擇的資料夾位置。
如果我們希望每次更改主要檔案時都更新檔案,請將 --watch 或 -w 選項新增到命令中,如下所示。
命令
npx babel src/main.js --watch --out-file out/main_out.js
輸出
你可以對主要檔案進行更改;此更改將反映在編譯後的檔案中。
在上述情況下,我們更改了日誌訊息,並且 --watch 選項持續檢查是否有任何更改,並在編譯後的檔案中添加了相同的更改。
編譯後的檔案
在我們之前的章節中,我們學習瞭如何編譯單個檔案。現在,我們將編譯一個目錄並將編譯後的檔案儲存在另一個目錄中。
在 src 資料夾中,我們將建立另一個 js 檔案,名為 main1.js。目前,src 資料夾中有 2 個 javascript 檔案 main.js 和 main1.js。
以下是檔案中的程式碼 -
main.js
var arrowfunction = () => {
console.log("Added changes to the log message");
}
main1.js
var handler = () => {
console.log("Added one more file");
}
以下命令將編譯來自 src 資料夾的程式碼並將其儲存到 out/ 資料夾中。我們已從 out/ 資料夾中刪除所有檔案並將其清空。我們將執行該命令並檢查 out/ 資料夾中的輸出。
命令
npx babel src --out-dir out
我們在 out 資料夾中得到了 2 個檔案 - main.js 和 main1.js
main.js
"use strict";
var arrowfunction = function arrowfunction() {
console.log("Added changes to the log message");
};
main1.js
"use strict";
var handler = function handler() {
console.log("Added one more file");
};
接下來,我們將執行以下命令以使用 babeljs 將這兩個檔案編譯成一個檔案。
命令
npx babel src --out-file out/all.js
輸出
"use strict";
var arrowfunction = function arrowfunction() {
console.log("Added changes to the log message");
};
"use strict";
var handler = function handler() {
console.log("Added one more file");
};
如果我們希望忽略某些檔案不被編譯,我們可以使用 --ignore 選項,如下所示。
命令
npx babel src --out-file out/all.js --ignore src/main1.js
輸出
all.js
"use strict";
var arrowfunction = function arrowfunction() {
console.log("Added changes to the log message");
};
我們可以使用外掛選項在檔案編譯期間使用。要使用外掛,我們需要安裝它,如下所示。
命令
npm install --save-dev babel-plugin-transform-exponentiation-operator
expo.js
let sqr = 9 ** 2; console.log(sqr);
命令
npx babel expo.js --out-file expo_compiled.js --plugins=babel-plugin-transform-exponentiation-operator
輸出
"use strict"; var sqr = Math.pow(9, 2); console.log(sqr);
我們也可以在命令中使用預設,如下所示。
命令
npx babel src/main.js --out-file main_es5.js --presets=es2015
為了測試上述情況,我們已從 .babelrc 中刪除了預設選項。
main.js
var arrowfunction = () => {
console.log("Added changes to the log message");
}
main_es5.js
"use strict";
var arrowfunction = function arrowfunction() {
console.log("Added changes to the log message");
};
我們也可以從命令列忽略 .babelrc,如下所示 -
npx babel --no-babelrc src/main.js --out-file main_es5.js --presets=es2015
為了測試上述情況,我們已將預設添加回 .babelrc,並且由於我們在命令中添加了 --no-babelrc,因此它將被忽略。main_es5.js 檔案的詳細資訊如下 -
main_es5.js
"use strict";
var arrowfunction = function arrowfunction() {
console.log("Added changes to the log message");
};
BabelJS - Babel 預設
Babel 預設是 Babel 轉換器的配置詳細資訊,告訴它以指定的模式進行轉換。以下是一些我們將在本章中討論的最流行的預設 -
- ES2015
- Env
- React
我們需要使用包含我們希望程式碼轉換到的環境的預設。例如,es2015 預設會將程式碼轉換為 es5。值為 env 的預設也會轉換為 es5。它還具有其他功能,即選項。如果您希望該功能在最新版本的瀏覽器上受支援,則 Babel 僅在這些瀏覽器不支援該功能時才會轉換程式碼。使用 react 預設,Babel 會將程式碼轉換為 React 程式碼。
要使用預設,我們需要在專案根資料夾中建立一個 .babelrc 檔案。為了展示其工作原理,我們將建立一個如下所示的專案結構。
命令
npm init
我們必須按照如下方式安裝所需的 Babel 預設,以及 Babel CLI、Babel Core 等。
Babel 6 包
npm install babel-cli babel-core babel-preset-es2015 --save-dev
Babel 7 包
npm install @babel/cli @babel/core @babel/preset-env --save-dev
注意 - babel-preset-es2015 從 Babel 7 開始已棄用。
es2015 或 @babel/env
在專案的根目錄中建立 .babelrc 檔案 (Babel 6) -
在 .babelrc 中,預設為 es2015。這表示我們希望 Babel 編譯器將程式碼轉換為 es2015。
對於 Babel 7,我們需要按如下方式使用預設 -
{
"presets":["@babel/env"]
}
以下是安裝後的 package.json -
由於我們已在本地安裝了 Babel,因此我們在 package.json 的 scripts 部分添加了 Babel 命令。
讓我們做一個簡單的示例來檢查使用 es2015 預設進行轉譯。
示例
main.js
let arrow = () => {
return "this is es6 arrow function";
}
轉譯為 es5,如下所示。
命令
npx babel main.js --out-file main_es5.js
main_es5.js
"use strict";
var arrow = function arrow() {
return "this is es6 arrow function";
};
Env
使用 Env 預設,您可以指定您希望最終程式碼轉譯到的環境。
我們將使用上面建立的相同的專案結構,並將預設從 es2015 更改為 env,如下所示。
此外,我們需要安裝 babel-preset-env。我們將執行以下命令來安裝它。
命令
npm install babel-preset-env --save-dev
我們將再次編譯 main.js 並檢視輸出。
main.js
let arrow = () => {
return "this is es6 arrow function";
}
命令
npx babel main.js --out-file main_env.js
main_env.js
"use strict";
var arrow = function arrow() {
return "this is es6 arrow function";
};
我們看到轉譯後的程式碼是 es5。如果我們知道程式碼將執行的環境,我們可以使用此預設來指定它。例如,如果我們將瀏覽器指定為 Chrome 和 Firefox 的最後 1 個版本,如下所示。
命令
npx babel main.js --out-file main_env.js
main_env.js
"use strict";
let arrow = () => {
return "this is es6 arrow function";
};
我們現在獲得的箭頭函式語法保持不變。它沒有被轉譯成 ES5 語法。這是因為我們希望程式碼支援的環境已經支援箭頭函式。
Babel 使用 babel-preset-env 處理基於環境的程式碼編譯。我們還可以根據 Node.js 環境來指定編譯目標,如下所示
程式碼的最終編譯結果如下所示。
命令
npx babel main.js --out-file main_env.js
main_env.js
"use strict";
let arrow = () => {
return "this is es6 arrow function";
};
Babel 根據當前 Node.js 版本編譯程式碼。
React 預設
當我們使用 React.js 時,可以使用 React 預設。我們將做一個簡單的示例,並使用 React 預設檢視輸出。
要使用預設,我們需要安裝 babel-preset-react (Babel 6),如下所示 -
npm install --save-dev babel-preset-react
對於 Babel 7,如下所示 -
npm install --save-dev @babel/preset-react
對於 Babel 6,.babelrc 的更改如下 -
對於 Babel 7
{
"presets": ["@babel/preset-react"]
}
main.js
<h1>Hello, world!</h1>
命令
npx babel main.js --out-file main_env.js
main_env.js
React.createElement( "h1", null, "Hello, world!" );
使用預設:react,main.js 中的程式碼被轉換為 React.js 語法。
BabelJS - 使用 Babel 和 Webpack
Webpack 是一個模組打包器,它將所有模組及其依賴項(js、樣式、影像等)打包成靜態資源 .js、.css、.jpg、.png 等。Webpack 帶有預設,有助於將程式碼編譯成所需的格式。例如,React 預設有助於將最終輸出轉換為 React 格式,es2015 或 env 預設有助於將程式碼編譯為 ES5 或 6 或 7 等。我們在專案設定中使用了 Babel 6。如果您想切換到 Babel 7,請使用 @babel/babel-package-name 安裝 Babel 的所需包。
這裡,我們將討論使用 Babel 和 Webpack 的專案設定。建立一個名為 的資料夾,並在 Visual Studio IDE 中開啟它。
要建立專案設定,請執行 npm init babel webpack,如下所示 -
以下是 npm init 建立後的 package.json -
現在,我們將安裝使用 Babel 和 Webpack 所需的包。
npm install --save-dev webpack npm install --save-dev webpack-dev-server npm install --save-dev babel-core npm install --save-dev babel-loader npm install --save-dev babel-preset-env
以下是安裝後的 Package.json -
現在,我們將建立一個 webpack.config.js 檔案,其中包含打包 js 檔案的所有詳細資訊。這些檔案將使用 Babel 編譯成 es5。
要使用伺服器執行 Webpack,我們使用 webpack-server。以下是新增到其中的詳細資訊 -
我們添加了 publish 命令,它將啟動 webpack-dev-server 並更新最終檔案儲存的路徑。現在我們將用於更新最終檔案的路徑是 /dev 資料夾。
要使用 Webpack,我們需要執行以下命令 -
npm run publish
首先我們需要建立 webpack.config.js 檔案。這些檔案將包含 Webpack 工作的配置詳細資訊。
檔案中的詳細資訊如下 -
var path = require('path');
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: path.resolve(__dirname, 'dev'),
filename: 'main_bundle.js'
},
mode:'development',
module: {
rules: [
{
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['env']
}
}
]
}
};
檔案的結構如上所示。它以 path 開頭,提供當前路徑的詳細資訊。
var path = require('path'); //gives the current path
接下來是 module.exports 物件,它具有 entry、output 和 module 屬性。entry 是起點。在這裡,我們需要提供要編譯的主要 js 檔案。
entry: {
app: './src/main.js'
},
path.resolve(_dirname, ‘src/main.js’) -- 將在目錄中查詢 src 資料夾,並在該資料夾中查詢 main.js。
輸出
output: {
path: path.resolve(__dirname, 'dev'),
filename: 'main_bundle.js'
},
Output 是一個包含 path 和 filename 屬性的物件。Path 將儲存編譯檔案所在的資料夾,filename 將告訴您在 .html 檔案中使用的最終檔名。
module
module: {
rules: [
{
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['env']
}
}
]
}
Module 是一個包含規則詳細資訊的物件。它具有以下屬性 -
- test
- include
- loader
- query
Test 將儲存所有以 .js 結尾的 js 檔案的詳細資訊。它具有模式,將在給定的入口點中查詢結尾處的 .js。
Include 指示要檢視的檔案使用的資料夾。
Loader 使用 babel-loader 來編譯程式碼。
Query 具有 presets 屬性,它是一個數組,其值為 env - es5 或 es6 或 es7。
建立 src 資料夾和 main.js 檔案;在其中編寫您的 ES6 程式碼。稍後,執行命令以檢視它如何使用 Webpack 和 Babel 編譯為 es5。
src/main.js
let add = (a,b) => {
return a+b;
};
let c = add(10, 20);
console.log(c);
執行以下命令 -
npm run pack
編譯後的檔案如下所示 -
dev/main_bundle.js
!function(e) {
var t = {};
function r(n) {
if(t[n])return t[n].exports;var o = t[n] = {i:n,l:!1,exports:{}};
return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports
}
r.m = e,r.c = t,r.d = function(e,t,n) {
r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})
},
r.r = function(e) {
"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})
},
r.t = function(e,t) {
if(1&t&&(e = r(e)),8&t)return e;
if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;
var n = Object.create(null);
if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t) {return e[t]}.bind(null,o));
return n
},
r.n = function(e) {
var t = e&&e.__esModule?function() {return e.default}:function() {return e};
return r.d(t,"a",t),t
},
r.o = function(e,t) {return Object.prototype.hasOwnProperty.call(e,t)},
r.p = "",r(r.s = 0)
}([function(e,t,r) {"use strict";var n = function(e,t) {return e+t}(10,20);console.log(n)}]);
!function(e) {
var t = {};
function r(n) {
if(t[n])return t[n].exports;
var o = t[n] = {i:n,l:!1,exports:{}};
return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports
}
r.m = e,r.c = t,r.d = function(e,t,n) {
r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})
},
r.r = function(e) {
"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})
},
r.t = function(e,t) {
if(1&t&&(e=r(e)),
8&t)return e;
if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;
var n = Object.create(null);
if(
r.r(n),
Object.defineProperty(n,"default",{enumerable:!0,value:e}),
2&t&&"string"!=typeof e
)
for(var o in e)r.d(n,o,function(t) {return e[t]}.bind(null,o));
return n
},
r.n = function(e) {
var t = e&&e.__esModule?function() {return e.default}:function() {return e};
return r.d(t,"a",t),t
},
r.o = function(e,t) {
return Object.prototype.hasOwnProperty.call(e,t)
},
r.p = "",r(r.s = 0)
}([function(e,t,r) {
"use strict";
var n = function(e,t) {return e+t}(10,20);
console.log(n)
}]);
程式碼如上所示編譯。Webpack 添加了一些內部所需的程式碼,並且 main.js 中的程式碼位於末尾。我們已經像上面那樣控制檯輸出了值。
在 .html 檔案中新增最終的 js 檔案,如下所示 -
<html>
<head></head>
<body>
<script type="text/javascript" src="dev/main_bundle.js"></script>
</body>
</html>
執行以下命令 -
npm run publish
要檢查輸出,我們可以在以下地址開啟檔案 -
https://:8080/
我們得到如上所示的控制檯值。現在讓我們嘗試使用 Webpack 和 Babel 將程式碼編譯成單個檔案。
我們將使用 Webpack 將多個 js 檔案捆綁到一個檔案中。Babel 將用於將 es6 程式碼編譯為 es5。
現在,我們在 src/ 資料夾中有 2 個 js 檔案 - main.js 和 Person.js,如下所示 -
person.js
export class Person {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname +"-"+this.lname;
}
}
我們使用了 export 來使用 Person 類的詳細資訊。
main.js
import {Person} from './person'
var a = new Person("Siya", "Kapoor", "15", "Mumbai");
var persondet = a.fullname;
console.log(persondet);
在 main.js 中,我們從檔案路徑匯入了 Person。
注意 - 我們不必包含 person.js,只需檔名即可。我們建立了一個 Person 類的物件,並如上所示控制檯輸出了詳細資訊。
Webpack 將合併 person.js 和 main.js,並在 dev/main_bundle.js 中更新為一個檔案。執行命令 npm run publish 以在瀏覽器中檢查輸出 -
BabelJS - 使用 Babel 和 JSX
在本章中,我們將瞭解使用 JSX 和 Babel 的方法。在深入瞭解細節之前,讓我們先了解什麼是 JSX。
什麼是 JSX?
JSX 是一種 JavaScript 程式碼,其中包含 XML 語法。JSX 標籤具有標籤名稱、屬性和子元素,使其看起來像 XML。
React 使用 JSX 進行模板化,而不是普通的 JavaScript。這不是必須的,但是,以下是一些隨之而來的優點。
它更快,因為它在將程式碼編譯為 JavaScript 時執行最佳化。
它也是型別安全的,大多數錯誤可以在編譯時被捕獲。
如果您熟悉 HTML,它使編寫模板變得更容易和更快。
我們在專案設定中使用了 Babel 6。如果您想切換到 Babel 7,請使用 @babel/babel-package-name 安裝 Babel 的所需包。
我們將建立專案設定並使用 Webpack 將 JSX 與 React 編譯成正常的 JavaScript,使用 Babel。
要啟動專案設定,請執行以下命令以安裝 Babel、React 和 Webpack。
命令
npm init
現在,我們將安裝使用 Babel、Webpack 和 JSX 所需的包 -
npm install --save-dev webpack npm install --save-dev webpack-cli npm install --save-dev webpack-dev-server npm install --save-dev babel-core npm install --save-dev babel-loader npm install --save-dev babel-preset-es2015 npm install --save-dev babel-preset-react npm install --save-dev react npm install --save-dev react-dom
以下是安裝後的 package.json -
現在將建立一個 webpack.config.js 檔案,其中包含打包 js 檔案的所有詳細資訊,並使用 Babel 將其編譯成 es5。
要使用伺服器執行 Webpack,有一個名為 webpack-server 的工具。我們添加了一個名為 publish 的命令;此命令將啟動 webpack-dev-server 並更新最終檔案儲存的路徑。現在我們將用於更新最終檔案的路徑是 /dev 資料夾。
要使用 Webpack,我們需要執行以下命令 -
npm run publish
我們將建立 webpack.config.js 檔案,其中包含 Webpack 工作的配置詳細資訊。
檔案中的詳細資訊如下 -
var path = require('path');
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: path.resolve(__dirname, 'dev'),
filename: 'main_bundle.js'
},
mode:'development',
module: {
rules: [
{
test:/\.(js|jsx)$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['es2015','react']
}
}
]
}
};
檔案的結構如上所示。它以 path 開頭,提供當前路徑的詳細資訊。
var path = require('path'); //gives the current path
接下來是 module.exports 物件,它具有 entry、output 和 module 屬性。
Entry 是起點。在這裡,我們需要提供要編譯的主要 js 檔案。
entry: {
app: './src/main.js'
},
path.resolve(_dirname, ‘src/main.js’) -- 將在目錄中查詢 src 資料夾,並在該資料夾中查詢 main.js。
輸出
output: {
path: path.resolve(__dirname, 'dev'),
filename: 'main_bundle.js'
},
Output 是一個包含 path 和 filename 屬性的物件。Path 將儲存編譯檔案所在的資料夾,filename 將告訴您在 .html 檔案中使用的最終檔名。
module
module: {
rules: [
{
test:/\.(js|jsx)$/,
include: path.resolve(__dirname, 'src'),
loader: 'babel-loader',
query: {
presets: ['es2015','react']
}
}
]
}
模組是一個包含規則細節的物件,它具有屬性,例如 test、include、loader 和 query。
Test 將儲存所有以 .js 和 .jsx 結尾的 js 檔案的詳細資訊。它具有一個模式,將在給定的入口點中查詢結尾處的 .js 和 .jsx。
Include 指示用於查詢檔案的資料夾。
Loader 使用 babel-loader 來編譯程式碼。
Query 具有屬性 presets,它是一個數組,其值為 env – es5 或 es6 或 es7。我們使用了 es2015 和 react 作為預設。
建立資料夾 src/。在其中新增 main.js 和 App.jsx。
App.jsx
import React from 'react';
class App extends React.Component {
render() {
var style = {
color: 'red',
fontSize: 50
};
return (
<div style={style}>
Hello World!!!
</div>
);
}
}
export default App;
main.js
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.jsx'; ReactDOM.render(, document.getElementById('app'));
執行以下命令來打包 .js 檔案並使用預設 es2015 和 react 進行轉換。
命令
npm run pack
將 dev 資料夾中的 main_bundle.js 新增到 index.html 中 -
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "UTF-8">
<title>React App</title>
</head>
<body>
<div id = "app"></div>
<script src = "dev/main_bundle.js"></script>
</body>
</html>
命令
npm run publish
輸出
BabelJS - 使用 Babel 和 Flow
Flow 是 JavaScript 的靜態型別檢查器。要使用 Flow 和 Babel,我們將首先建立一個專案設定。我們在專案設定中使用了 Babel 6。如果您想切換到 Babel 7,請使用 @babel/babel-package-name 安裝 Babel 的必需包。
命令
npm init
安裝 Flow 和 Babel 的必需包 -
npm install --save-dev babel-core babel-cli babel-preset-flow flow-bin babel-plugin-transform-flow-strip-types
這是安裝後的最終 package.json。還添加了 Babel 和 Flow 命令,以便在命令列中執行程式碼。
在專案設定內建立 .babelrc,並新增如下所示的預設
建立一個 main.js 檔案,並使用 Flow 編寫您的 JavaScript 程式碼 -
main.js
/* @flow */
function concat(a: string, b: string) {
return a + b;
}
let a = concat("A", "B");
console.log(a);
使用 Babel 命令編譯程式碼,使用預設:將 Flow 轉換為普通 JavaScript
npx babel main.js --out-file main_flow.js
main_flow.js
function concat(a, b) {
return a + b;
}
let a = concat("A", "B");
console.log(a);
我們還可以使用名為 babel-plugin-transform-flow-strip-types 的外掛來代替預設,如下所示 -
在 .babelrc 中,新增如下所示的外掛 -
main.js
/* @flow */
function concat(a: string, b: string) {
return a + b;
}
let a = concat("A", "B");
console.log(a);
命令
npx babel main.js --out-file main_flow.js
main_flow.js
function concat(a, b) {
return a + b;
}
let a = concat("A", "B");
console.log(a);
BabelJS - 使用 BabelJS 和 Gulp
在本章中,我們將使用 Babel 和 Gulp 建立專案設定。Gulp 是一個使用 Node.js 作為平臺的任務執行器。Gulp 將執行將 JavaScript 檔案從 es6 轉換為 es5 的任務,完成後將啟動伺服器以測試更改。我們在專案設定中使用了 Babel 6。如果您想切換到 Babel 7,請使用 @babel/babel-package-name 安裝 Babel 的必需包。
我們將首先使用 npm 命令建立專案,並安裝所需的包以開始。
命令
npm init
我們建立了一個名為 gulpbabel 的資料夾。接下來,我們將安裝 Gulp 和其他必需的依賴項。
命令
npm install gulp --save-dev npm install gulp-babel --save-dev npm install gulp-connect --save-dev npm install babel-preset-env --save-dev npm install babel-core --save-dev
我們將如下所示將預設環境詳細資訊新增到 .babelrc 檔案中
gulpfile.js
var gulp =require('gulp');
var babel =require('gulp-babel');
var connect = require("gulp-connect");
gulp.task('build', () => {
gulp.src('src/./*.js')
.pipe(babel())
.pipe(gulp.dest('./dev'))
});
gulp.task('watch', () => {
gulp.watch('./*.js', ['build']);
});
gulp.task("connect", function () {
connect.server({
root: ".",
livereload: true
});
});
gulp.task('start', ['build', 'watch', 'connect']);
我們在 Gulp 中建立了三個任務:[‘build’,’watch’,’connect’]。src 資料夾中所有可用的 js 檔案將使用 Babel 轉換為 es5,如下所示 -
gulp.task('build', () => {
gulp.src('src/./*.js')
.pipe(babel())
.pipe(gulp.dest('./dev'))
});
最終更改儲存在 dev 資料夾中。Babel 使用 .babelrc 中的預設詳細資訊。如果您想更改為其他預設,可以在 .babelrc 檔案中更改詳細資訊。
現在,我們將使用 es6 javascript 在 src 資料夾中建立一個 .js 檔案,並執行 gulp start 命令來執行更改。
src/main.js
class Person {
constructor(fname, lname, age, address) {
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
get fullname() {
return this.fname +"-"+this.lname;
}
}
命令:gulp start
dev/main.js
這是使用 Babel 轉換的 -
"use strict";
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i <props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var Person = function () {
function Person(fname, lname, age, address) {
_classCallCheck(this, Person);
this.fname = fname;
this.lname = lname;
this.age = age;
this.address = address;
}
_createClass(Person, [{
key: "fullname",
get: function get() {
return this.fname + "-" + this.lname;
}
}]);
return Person;
}();
Index.html
這是使用 轉換後的 dev/main.js 完成的 -
<html>
<head></head>
<body>
<script type="text/javascript" src="dev/main.js"></script>
<h1 id="displayname"></h1>
<script type="text/javascript">
var a = new Student("Siya", "Kapoor", "15", "Mumbai");
var studentdet = a.fullname;
document.getElementById("displayname").innerHTML = studentdet;
</script>
</body>
</html>
輸出
BabelJS - 示例
我們將使用 ES6 功能並建立一個簡單的專案。Babeljs 將用於將程式碼編譯為 ES5。該專案將包含一組影像,這些影像將在固定時間間隔後自動滑動。我們將使用 ES6 類來處理它。我們在專案設定中使用了 Babel 6。如果您想切換到 Babel 7,請使用 @babel/babel-package-name 安裝 Babel 的必需包。
自動滑動影像
我們將使用 Gulp 來構建專案。首先,我們將建立如下所示的專案設定
命令
npm init
我們建立了一個名為 babelexample 的資料夾。接下來,我們將安裝 Gulp 和其他必需的依賴項。
命令
npm install gulp --save-dev npm install gulp-babel --save-dev npm install gulp-connect --save-dev npm install babel-preset-env --save-dev
以下是安裝後的 Package.json -
我們將如下所示將預設環境詳細資訊新增到 .babelrc 檔案中 -
由於我們需要 Gulp 任務來構建最終檔案,因此我們將建立包含所需任務的 gulpfile.js
gulpfile.js
var gulp = require('gulp');
var babel = require('gulp-babel');
var connect = require("gulp-connect");
gulp.task('build', () => {
gulp.src('src/./*.js')
.pipe(babel())
.pipe(gulp.dest('./dev'))
});
gulp.task('watch', () => {
gulp.watch('./*.js', ['build']);
});
gulp.task("connect", function () {
connect.server({
root: ".",
livereload: true
});
});
gulp.task('start', ['build', 'watch', 'connect']);
我們在 Gulp 中建立了三個任務,[‘build’,’watch’,’connect’]。src 資料夾中所有可用的 js 檔案將使用 Babel 轉換為 es5,如下所示
gulp.task('build', () => {
gulp.src('src/./*.js')
.pipe(babel())
.pipe(gulp.dest('./dev'))
});
最終更改儲存在 dev 資料夾中。Babel 使用 .babelrc 中的預設詳細資訊。如果您想更改為其他預設,可以在 .babelrc 檔案中更改詳細資訊。
現在,我們將使用 es6 JavaScript 在 src 資料夾中建立一個 .js 檔案,並執行 gulp start 命令來執行更改。
專案結構如下所示 -
src/slidingimage.js
class SlidingImage {
constructor(width, height, imgcounter, timer) {
this.counter = 0;
this.imagecontainerwidth = width;
this.imagecontainerheight = height;
this.slidercounter = imgcounter;
this.slidetimer = timer;
this.startindex = 1;
this.css = this.applycss();
this.maincontainer = this.createContainter();
this.childcontainer = this.imagecontainer();
this.autoslide();
}
createContainter() {
let maindiv = document.createElement('div');
maindiv.id = "maincontainer";
maindiv.class = "maincontainer";
document.body.appendChild(maindiv);
return maindiv;
}
applycss() {
let slidercss = ".maincontainer{ position : relative; margin :auto;}.left,
.right {
cursor: pointer; position: absolute;" +
"top: 50%; width: auto; padding: 16px; margin-top: -22px; color: white; font-weight: bold; " +
"font-size: 18px; transition: 0.6s ease; border-radius: 0 3px 3px 0;
}.right { right: 0; border-radius: 3px 0 0 3px;}" +
".left:hover, .right:hover { background-color: rgba(0,0,0,0.8);}";
let style = document.createElement('style');
style.id = "slidercss";
style.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(style);
let styleall = style;
if (styleall.styleSheet) {
styleall.styleSheet.cssText = slidercss;
} else {
let text = document.createTextNode(slidercss);
style.appendChild(text);
}
}
imagecontainer() {
let childdiv = [];
let imgcont = [];
for (let a = 1; a >= this.slidercounter; a++) {
childdiv[a] = document.createElement('div');
childdiv[a].id = "childdiv" + a;
childdiv[a].style.width = this.imagecontainerwidth + "px";
childdiv[a].style.height = this.imagecontainerheight + "px";
if (a > 1) {
childdiv[a].style.display = "none";
}
imgcont[a] = document.createElement('img');
imgcont[a].src = "src/img/img" + a + ".jpg";
imgcont[a].style.width = "100%";
imgcont[a].style.height = "100%";
childdiv[a].appendChild(imgcont[a]);
this.maincontainer.appendChild(childdiv[a]);
}
}
autoslide() {
console.log(this.startindex);
let previousimg = this.startindex;
this.startindex++;
if (this.startindex > 5) {
this.startindex = 1;
}
setTimeout(() => {
document.getElementById("childdiv" + this.startindex).style.display = "";
document.getElementById("childdiv" + previousimg).style.display = "none";
this.autoslide();
}, this.slidetimer);
}
}
let a = new SlidingImage(300, 250, 5, 5000);
我們將建立 src/ 中的 img/ 資料夾,因為我們需要顯示影像;這些影像需要每 5 秒旋轉一次。dev/ 資料夾將儲存編譯後的程式碼。執行 gulp start 以構建最終檔案。
最終專案結構如下所示 -
在 slidingimage.js 中,我們建立了一個名為 SlidingImage 的類,該類具有諸如 createcontainer、imagecontainer 和 autoslide 等方法,這些方法建立主容器並將影像新增到其中。autoslide 方法有助於在指定的時間間隔後更改影像。
let a = new SlidingImage(300, 250, 5, 5000);
在此階段,將呼叫該類。我們將傳遞 寬度、高度、影像數量和旋轉影像的秒數。
命令
gulp start
dev/slidingimage.js
"use strict";
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps); return Constructor;
};
}();
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var SlidingImage = function () {
function SlidingImage(width, height, imgcounter, timer) {
_classCallCheck(this, SlidingImage);
this.counter = 0;
this.imagecontainerwidth = width;
this.imagecontainerheight = height;
this.slidercounter = imgcounter;
this.slidetimer = timer;
this.startindex = 1;
this.css = this.applycss();
this.maincontainer = this.createContainter();
this.childcontainer = this.imagecontainer();
this.autoslide();
}
_createClass(SlidingImage, [{
key: "createContainter",
value: function createContainter() {
var maindiv = document.createElement('div');
maindiv.id = "maincontainer";
maindiv.class = "maincontainer";
document.body.appendChild(maindiv);
return maindiv;
}
}, {
key: "applycss",
value: function applycss() {
var slidercss = ".maincontainer{ position : relative; margin :auto;}.left, .right {
cursor: pointer; position: absolute;" + "top: 50%;
width: auto;
padding: 16px;
margin-top: -22px;
color: white;
font-weight: bold;
" + "font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
}
.right { right: 0; border-radius: 3px 0 0 3px;}" +
".left:hover, .right:hover { background-color: rgba(0,0,0,0.8);}";
var style = document.createElement('style');
style.id = "slidercss";
style.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(style);
var styleall = style;
if (styleall.styleSheet) {
styleall.styleSheet.cssText = slidercss;
} else {
var text = document.createTextNode(slidercss);
style.appendChild(text);
}
}
}, {
key: "imagecontainer",
value: function imagecontainer() {
var childdiv = [];
var imgcont = [];
for (var _a = 1; _a <= this.slidercounter; _a++) {
childdiv[_a] = document.createElement('div');
childdiv[_a].id = "childdiv" + _a;
childdiv[_a].style.width = this.imagecontainerwidth + "px";
childdiv[_a].style.height = this.imagecontainerheight + "px";
if (_a > 1) {
childdiv[_a].style.display = "none";
}
imgcont[_a] = document.createElement('img');
imgcont[_a].src = "src/img/img" + _a + ".jpg";
imgcont[_a].style.width = "100%";
imgcont[_a].style.height = "100%";
childdiv[_a].appendChild(imgcont[_a]);
this.maincontainer.appendChild(childdiv[_a]);
}
}
}, {
key: "autoslide",
value: function autoslide() {
var _this = this;
console.log(this.startindex);
var previousimg = this.startindex;
this.startindex++;
if (this.startindex > 5) {
this.startindex = 1;
}
setTimeout(function () {
document.getElementById("childdiv" + _this.startindex).style.display = "";
document.getElementById("childdiv" + previousimg).style.display = "none";
_this.autoslide();
}, this.slidetimer);
}
}]);
return SlidingImage;
}();
var a = new SlidingImage(300, 250, 5, 5000);
我們將如下所示在瀏覽器中測試程式碼行 -
index.html
<html>
<head></head>
<body>
<script type="text/javascript" src="dev/slidingimage.js"></script>
<h1>Sliding Image Demo</h1>
</body>
</html>
我們在 index.html 中使用了 dev 資料夾中的編譯檔案。命令 gulp start 啟動伺服器,我們可以在其中測試輸出。
在 Chrome 中
在 Firefox 中
在 Internet Explorer 中
編譯後的程式碼在所有瀏覽器中都能正常工作。