---
# System prepended metadata

title: 使用esbuild打包工具，Alpine框架實作BMI範例
tags: [JavaScript]

---

# 使用esbuild打包工具，Alpine框架實作BMI範例

設定流程 - 開啟專案範例 07_BMI
1. 開啟專案內終端機Terminal
2. 使用npm安裝打包工具和Alpine開發框架
    - npm init -y 
        - 加入-y : 用來省略手動輸入package.json 內物件初始定義，套用預設值
        - 會在目錄下自動生成`package.json`檔案
    
    - npm i esbuild alpinejs `--save-dev`
        - i : install的縮寫
        - esbuild 和 alpinejs 為要安裝的套件名稱
        - `--save-dev` : 表示安裝後會歸類在package.json中
        ```js
         "devDependencies": {
            "alpinejs": "^3.14.1", // ^表示只有在版本更新minor時候，才會自動更新
            "esbuild": "^0.23.0"
         }
        ```
3. 修改package.json內script 要執行的動作 (--watch可以即時監看)
    [主要修改] "main"指的是要抓來編譯的js檔案路徑
    ```js
    "main": "src/app.js",
    "scripts": {
        "build": "esbuild src/app.js --bundle --outfile=dist/bundle.js --watch"
    },
    ```
    [最後內容]
    ```js
    {
      "name": "07_bmi",
      "version": "1.0.0",
      "main": "src/app.js",
      "scripts": {
        "build": "esbuild src/app.js --bundle --outfile=dist/bundle.js --watch"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "description": "",
      "devDependencies": {
        "alpinejs": "^3.14.1",
        "esbuild": "^0.23.0"
      }
    }
    ```
4. index.html內容 (原始內容)
```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>BMI 計算機</title>
    <link rel="stylesheet" href="style.css" />
    <script src="./dist/bundle.js"></script>
  </head>
  <body>
    <section class="calculator">
      <section class="fields">
        <h1>BMI 計算機</h1>
        <h2>想要健康嗎？趕快動起來！</h2>
        <div>
          <label for="bodyHeight">身高</label>
          <input type="number" id="bodyHeight" min="0" />公分
        </div>
        <div>
          <label for="bodyWeight">體重</label>
          <input type="number" id="bodyWeight" min="0" />公斤
        </div>
        <button>計算</button>
      </section>

      <section class="result">
        <h2>計算結果：</h2>
        <p id="resultText">0</p>
      </section>
      <div class="clearfix"></div>
    </section>
  </body>
</html>
```

5. 在目錄下新增 `src`資料夾 和 要實作的`app.js`檔案 (src/app.js)
```js
import Alpine from "alpinejs";
console.log(Alpine);

Alpine.data("", () => ({}));
```
6. 開始編譯執行，在終端機輸入 `npm run build`
![image](https://hackmd.io/_uploads/r13uO0iPC.png)
    - 瀏覽器查看結果 (表示有正確抓到Alpine套件)
    ![image](https://hackmd.io/_uploads/B1Xod0iP0.png)
    ![image](https://hackmd.io/_uploads/SJT0uAsvA.png)
    
    dist/bundle.js ( 是在package.json的script->build指定的輸出路徑 )
    ![image](https://hackmd.io/_uploads/rkN8KAjvR.png)

7. 開始修改要實作內容 html
```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>BMI 計算機</title>
    <link rel="stylesheet" href="style.css" />
    // 指定輸出檔案路徑，記得加defer
    <script src="./dist/bundle.js" defer></script>
  </head>
  <body>
    // 加入 x-data 框選要抓取的範圍
    <section x-data="bmi_data" class="calculator">  
      <section class="fields">
        <h1>BMI 計算機</h1>
        <h2>想要健康嗎？趕快動起來！</h2>
        <div>
          <label for="bodyHeight">身高</label>
          // 加入x-model，使用雙向溝通特性，及時抓到和顯示使用者輸入的資料
          <input x-model="height" type="number" id="bodyHeight" min="0" />公分
        </div>
        <div>
          <label for="bodyWeight">體重</label>
          // 加入x-model，使用雙向溝通特性，及時抓到和顯示使用者輸入的資料
          <input x-model="weight" type="number" id="bodyWeight" min="0" />公斤
        </div>
        // 加入@click 指定到要執行的函數名稱
        <button @click="toDoCalculator">計算</button>
      </section>

      <section class="result">
        <h2>計算結果：</h2>
        // 加入x-text 指定要顯示的結果
        <p id="resultText" x-text="result">0</p>
      </section>
      <div class="clearfix"></div>
    </section>
  </body>
</html>

```

8. 修改src/app.js內容 
   Alpine.data("", ()=>({ })); 其中的{ } 指的是物件
```js
import Alpine from "alpinejs";

Alpine.data("bmi_data", () => ({
  // 定義變數
  height: "",
  weight: "",
  result: "0",
	
  // 定義函數功能
  toDoCalculator() {
    const h = Number(this.height) / 100.0;
    const w = Number(this.weight);
    const bmi = w / (h * h);
    this.result = bmi.toFixed(2);
  },
}));

Alpine.start();  <===== 記得要啟動才會運作
```

9. 重新編譯執行 npm run build
![image](https://hackmd.io/_uploads/H1zVoAow0.png)


10. 使用go live 查看網頁實作結果
![image](https://hackmd.io/_uploads/By9GsCjwA.png)

