使用Babel與Webpack轉換JavaScript程式碼

by vivid 23. 一月 2019 03:14

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:
N190120302
出刊日期: 2019/1/23

在這篇文章中,將要介紹如何在ASP.NET網站應用程式之中,使用Babel編譯JavaScript程式碼,以及利用Webpack來打包JavaScript到生產環境(Production)。

要開始之前,我們心回顧一下在Javaccript之中使用模組(Module)的好處:

1. 程式碼易於維護。可以將程式封裝在一起,不易被其它程式所影響。

2. 提供程式私有範圍。將變數與函式包裝在一個私有範圍(Private Scope),以和全域變數、函式有所區別。

3. 具備重複使用性。將功能相近的函式、物件包裝在一起,較容易重複使用。

不過在ECMAScript 2015版中,雖然有支援Javaccript模組,但大部分瀏覽器卻不支援,你需要一些額外的動作,才能在網站中使用到Javaccript模組。更多關於模組的細節請參考本站《ECMAScript 2015 - 模組》一文的說明。

 

轉譯器(Transpiler)

因為不是所有瀏覽器都支援ECMAScript 2015及其以上版本的新語法,有許多的專案會使用轉譯器(Transpiler),例如「Bable」來轉換JavaScript程式碼,轉譯程式可以將ECMAScript 2015及其以上版本的程式轉換成ECMAScript 5相容語法,以便於在瀏覽器之中使用。

 

模組打包器(Module Bunder)

模組打包器(Module Bunder)可以將多個模組檔案打包成一個單一檔案,可以將一堆有相依關係的檔案按照正確的順序來打包。將多個檔案打包成一個單一檔案帶來的好處是,可以減少HTTP請求的數量。Minification(壓縮)則是指將檔案中不要的空白、換行符號等去除,讓檔案變小,以減少載入時間來增進網站效能。我們需要工具來將模組轉換成瀏覽器可以看的懂的程式碼,這些工具稱做模組打包器(Module Bunder)或模組載入器(Module Loader)。其中較知名的工具則是「Webpack」。

接下來讓我們透過Visual Studio 2017開發工具來建立網站應用程式,以了解如何使用「Babel」來轉譯JavaScript程式碼。

 

建立網站專案

啟動Visual Studio 2017開發環境。從Visual Studio開發工具「File」-「New」-「Project」項目,在「New Project」對話盒中,選取左方「Installed」清單 -「Visual C#」程式語言,從「Web」分類中,選取「ASP.NET Web Application(.NET Framework)」。請參考下圖所示,設定專案名稱,與專案存放路徑,按下「OK」鍵。

clip_image002

圖 1:建立網站應用程式。

在「New ASP.NET Web Application」對話盒中,選取下方的「Empty 」樣版專案,清除勾選下方的所有核取方塊,確定右方的「Authentication」項目設定為「No Authentication」,然後按下「OK」按鈕建立專案,請參考下圖所示:

clip_image004

圖 2:建立空白網站專案。

在網站根目錄建立「src」資料夾。從「Solution Explorer」視窗 - 專案名稱上方按滑鼠右鍵,從快捷選單選擇「Add」- 「New Folder」選項,將新建立的資料夾命名為「src」,請參考下圖所示:

clip_image006圖 3:在網站根目錄建立「src」資料夾。

加入JavaScript檔案。從「Solution Explorer」視窗 -「src」資料夾上方,按滑鼠右鍵,從快捷選單選擇「Add」- 「New Item」項目,請參考下圖所示:

clip_image008

圖 4:加入JavaScript檔案。

在「Add New Item」對話盒中,從右上方文字方塊輸入「javascript」搜尋,選取「JavaScript File」,設定名稱為「app.js」,然後按下「Add」按鈕,建立新檔案,請參考下圖所示:

clip_image010

圖 5:建立「app.js」檔案。

在「app.js」檔案之中,加入以下程式碼,利用Promise與AJAX下載伺服端的「customers.json」檔案:

 

let requestPromise = new Promise( ( resolve, reject ) => {
    let xhr = new XMLHttpRequest();
    xhr.open("GET", "customers.json");
    xhr.send();
    xhr.onload = () => {
        if ( xhr.status === 200 ) {
            resolve( xhr.response );
        } else {
            reject( xhr.statusText );
        }
    };
});

requestPromise.then( data => {
    let employees = JSON.parse( data );
    let html = "<ul>";
    employees.forEach( employee => {
        html += `
                <li>
                    ${employee.firstName} ${employee.lastName}
                </li> `;
    });

    html += "</ul>";
    document.getElementById("list").innerHTML = html;
})
.catch( error => {
        console.log( error );
});

 

在網站根目錄加入「customers.json」檔案。從「Solution Explorer」視窗 – 專案名稱上方,按滑鼠右鍵,從快捷選單選擇「Add」- 「New Item」項目。在「Add New Item」對話盒中,從右上方文字方塊輸入「json」搜尋,選取「JSON File」,設定名稱為「customers.json」,然後按下「Add」按鈕,建立新檔案,請參考下圖所示:

clip_image012

圖 6:在網站根目錄加入「customers.json」檔案。

在「customers.json」檔案之中,加入以下顧客資料:

[
  {
    "id": 1,
    "firstName": "Michael",
    "lastName": "Jones"
  },
  {
    "id": 2,
    "firstName": "",
    "lastName": "Taylor"
  },
  {
    "id": 3,
    "firstName": "Amy",
    "lastName": "Wu"
  },
  {
    "id": 4,
    "firstName": "Caroline",
    "lastName": "Kingsley"
  },
  {
    "id": 5,
    "firstName": "Anup",
    "lastName": "Bradley"
  },
  {
    "id": 6,
    "firstName": "James",
    "lastName": "Kennedy"
  },
  {
    "id": 7,
    "firstName": "Jennifer",
    "lastName": "Sato"
  },
  {
    "id": 8,
    "firstName": "Jonathan",
    "lastName": "Gupta"
  }
]

 

在網站根目錄加入「index.html」檔案。從「Solution Explorer」視窗 – 專案名稱上方,按滑鼠右鍵,從快捷選單選擇「Add」- 「New Item」項目。在「Add New Item」對話盒中,從右上方文字方塊輸入「html」搜尋,選取「HTML Page」,設定名稱為「index.html」,然後按下「Add」按鈕,建立新檔案,請參考下圖所示:

clip_image014

圖 7:在網站根目錄加入「index.html」檔案。

在「index.html」檔案之中,加入以下程式碼,引用JavaScript並顯示「customers.json」檔案中顧客的清單:

<!DOCTYPE html>
<html>
<head>
    <meta charset = "utf-8" />
    <title > </title>
</head>
<body>
  <div id = "list"> </div>
  <script src = "src/app.js"> </script>
</body>
</html>

在Visual Studio開發工具,按CTRL+F5執行網站首頁(請注意:埠號可能會依據實際上的操作而有所不同),這個範例程式的執行結果,請參考下圖所示:

clip_image016

圖 8:Index.html網頁執行結果。

使用Babel轉譯JavaScript程式碼

在網站根目錄加入「package.json」組態設定檔案。從「Solution Explorer」視窗 – 專案名稱上方,按滑鼠右鍵,從快捷選單選擇「Add」- 「New Item」項目。在「Add New Item」對話盒中,從右上方文字方塊輸入「npm」搜尋,選取「npm Configuration File」,設定名稱為「package.json」,然後按下「Add」按鈕,建立新檔案,請參考下圖所示:

clip_image018

圖 9:在網站根目錄加入npm 組態設定檔案。

目前「package.json」檔案的內容看起來如下:

{
  "version": "1.0.0",
  "name": "asp.net",
  "private": true,
  "devDependencies": {}
}

切換到命令提示字元,在專案根目錄,輸入以下指令,利用「npm」安裝「@babel/core」、「@babel/cli」與「@babel/preset-env」,並指定「--save-dev」選項:

npm install --save-dev @babel/core @babel/cli @babel/preset-env

這個命令執行結果,請參考下圖所示:

clip_image020

圖 10:安裝套件。

完成此步驟之後,在專案的根目錄下,就會多出一個「node_modules」資料夾,安裝的套件將會放在此資料夾之中。而「package.json」檔案的內容將被更新如下,將已安裝的套件資訊放在「devDependencies」區段中:


{
  "version": "1.0.0",
  "name": "asp.net",
  "private": true,
  "devDependencies": {
    "@babel/cli": "^7.1.5",
    "@babel/core": "^7.1.5",
    "@babel/preset-env": "^7.1.5"
  }
}

修改「package.json」檔案,加入「scripts」區段,指定要將「src」資料夾中的JavaScript程式碼,轉譯完成之後,放在「dist」資料夾中:

{
  "version": "1.0.0",
  "name": "asp.net",
  "private": true,
  "devDependencies": {
    "@babel/cli": "^7.1.5",
    "@babel/core": "^7.1.5",
    "@babel/preset-env": "^7.1.5"
  },
  "scripts": {
    "build": "babel --presets @babel/preset-env src -d dist"
  }
}

 

切換到命令提示字元,在專案根目錄,輸入以下指令:

npm run build

這個命令執行結果,請參考下圖所示:

clip_image022

圖 11:轉譯程式碼。

轉換完成之後,「dist」資料夾中就會多出一個「app.js」檔案,請參考下圖所示:

clip_image024

圖 12:轉譯完成的JavaScript程式碼。

根據ECMAScript 2015標準,轉換完成的「app.js」程式碼,請參考如下:

"use strict";

var requestPromise = new Promise( function ( resolve, reject ) {
  var xhr = new XMLHttpRequest();
  xhr.open( "GET", "customers.json" );
  xhr.send();

  xhr.onload = function () {
    if (xhr.status === 200) {
      resolve( xhr.response );
    } else {
      reject( xhr.statusText );
    }
  };
});
requestPromise.then( function ( data ) {
  var employees = JSON.parse( data );
  var html = "<ul>";
  employees.forEach( function ( employee ) {
    html += "\n                <li>\n                    ".concat( employee.firstName, " ").concat( employee.lastName, "\n                </li> ");
  });
  html += "</ul>";
  document.getElementById("list").innerHTML = html;
}).catch( function ( error ) {
  console.log( error );
});

 

安裝Webpack套件

切換到命令提示字元,在專案根目錄,輸入以下指令,利用「npm」安裝「babel-loader」、「webpack」與「webpack-cli」套件,並指定「--save-dev」選項:

npm install -D babel-loader webpack webpack-cli --save-dev

這個命令執行結果,請參考下圖所示:

clip_image026

圖 13:安裝Webpack。

「package.json」檔案的內容將會更新如下,將已安裝的套件資訊放在「devDependencies」區段中:

{
  "version": "1.0.0",
  "name": "asp.net",
  "private": true,
  "devDependencies": {
    "@babel/cli": "^7.1.5",
    "@babel/core": "^7.1.5",
    "@babel/preset-env": "^7.1.5",
    "babel-loader": "^8.0.4",
    "webpack": "^4.25.1",
    "webpack-cli": "^3.1.2"
  },
  "scripts": {
    "build": "babel --presets @babel/preset-env src -d dist"
  }
}

 

安裝babel-polyfill套件

因為不是所有ECMAScript 2015新語法都有對應相容的ECMAScript 5語法,「babel-polyfill」套件可以模擬完整的ECMAScript 2015與環境,需和你的程式碼一起編譯到生產環境(Production),因此安裝「babel-polyfill」套件時使用「--save」參數。切換到命令提示字元,在專案根目錄,輸入以下指令:

npm install --save @babel/polyfill

這個命令執行結果,請參考下圖所示:

clip_image028

圖 14:安裝「babel-polyfill」套件。

「package.json」檔案的內容將被更新如下,將已安裝的套件資訊放在「dependencies」區段中:

{
  "version": "1.0.0",
  "name": "asp.net",
  "private": true,
  "devDependencies": {
    "@babel/cli": "^7.1.5",
    "@babel/core": "^7.1.5",
    "@babel/preset-env": "^7.1.5",
    "babel-loader": "^8.0.4",
    "webpack": "^4.25.1",
    "webpack-cli": "^3.1.2"
  },
  "scripts": {
    "build": "babel --presets @babel/preset-env src -d dist"
  },
  "dependencies": {
    "@babel/polyfill": "^7.0.0"
  }
}

 

加入Webpack組態檔案

在網站根目錄加入Webpack組態檔案。從「Solution Explorer」視窗 – 專案名稱上方,按滑鼠右鍵,從快捷選單選擇「Add」- 「New Item」項目。在「Add New Item」對話盒中,從右上方文字方塊輸入「javascript」搜尋,選取「JavaScript File」,設定名稱為「webpack.config.js」,然後按下「Add」按鈕,建立新檔案,請參考下圖所示:

clip_image030

圖 15:加入Webpack組態檔案。

在「webpack.config.js」組態檔案之中,加入以下程式碼:

var path = require('path');
var webpack = require('webpack');

module.exports = {
    entry: ['@babel/polyfill', './src/app.js'],
    output: {
        path: path.resolve(__dirname, 'build'),
        filename: 'app.bundle.js'
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                options: {
                    presets: ["@babel/preset-env"]
                }
            }
        ]
    },
    stats: {
        colors: true
    },
    devtool: 'source-map'
};

 

修改「app.js」檔案,在檔案最上方加入「require("@babel/polyfill");」程式碼,目前檔案的內容看起來如下所示:

require("@babel/polyfill");
let requestPromise = new Promise( ( resolve, reject ) => {
    let xhr = new XMLHttpRequest();
    xhr.open( "GET", "customers.json" );
    xhr.send();
    xhr.onload = () => {
        if ( xhr.status === 200 ) {
            resolve( xhr.response );
        } else {
            reject( xhr.statusText );
        }
    };
});

requestPromise.then( data => {
    let employees = JSON.parse( data );
    let html = "<ul>";
    employees.forEach( employee => {
        html += `
                <li>
                    ${employee.firstName} ${employee.lastName}
                </li> `;
    });

    html += "</ul>";
    document.getElementById("list").innerHTML = html;
})
.catch( error => {
        console.log( error );
});

 

修改「package.json」檔案,修改「scripts」區段,設定將使用webpack來編譯應用程式。

{
  "version": "1.0.0",
  "name": "asp.net",
  "private": true,
  "devDependencies": {
    "@babel/cli": "^7.1.5",
    "@babel/core": "^7.1.5",
    "@babel/preset-env": "^7.1.5",
    "babel-loader": "^8.0.4",
    "webpack": "^4.25.1",
    "webpack-cli": "^3.1.2"
  },
  "scripts": {
    "build": "babel --presets @babel/preset-env src -d dist",
    "webpack": "webpack"
  },
  "dependencies": {
    "@babel/polyfill": "^7.0.0"
  }
}

 

在網站根目錄建立「Build」資料夾。從「Solution Explorer」視窗 - 專案名稱上方按滑鼠右鍵,從快捷選單選擇「Add」- 「New Folder」選項,將新建立的資料夾命名為「Build」,請參考下圖所示:

clip_image032

圖 16:在網站根目錄建立「Build」資料夾。

切換到命令提示字元,在專案根目錄,輸入以下指令:

npm run webpack

這個命令執行結果,請參考下圖所示:

clip_image034

圖 17:編譯程式。

完成之後「Build」資料夾將產生「app.bundle.js」與「app.bundle.js.map」兩個檔案,請參考下圖所示:

clip_image036

圖 18:編譯結果。

打包完的「app.bundle.js」檔案,請參考下圖所示:

clip_image038

圖 19:「app.bundle.js」檔案。

使用打包的JavaScript檔案。修改網站「index.html」檔案,引用打包完成的「app.bundle.js」檔案:

<!DOCTYPE html>
<html>
<head>
    <meta charset = "utf-8" />
    <title > </title>
</head>
<body>
  <div id = "list"> </div>
  <!--<script src = "src/app.js"> </script>-->
  <script src = "build/app.bundle.js"></script>
</body>
</html>

 

在Visual Studio開發工具,按CTRL+F5執行網站首頁(請注意:埠號可能會依據實際上的操作而有所不同),這個範例程式的執行結果,請參考下圖所示:

clip_image040

圖 20:使用打包的JavaScript檔案。

Tags:

.NET Magazine國際中文電子雜誌 | ASP.NET | JavaScript

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List