# 使用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`

- 瀏覽器查看結果 (表示有正確抓到Alpine套件)


dist/bundle.js ( 是在package.json的script->build指定的輸出路徑 )

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

10. 使用go live 查看網頁實作結果
