# 🚀 Modern JavaScript (ES6+)

**สารบัญ:**

1. [ES Modules](#1-es-modules-importexport)
2. [Module Bundlers](#2-module-bundlers-vite--webpack)
3. [NPM & Package Management](#3-npm--package-management)
4. [Code Organization & Project Structure](#4-code-organization--project-structure)
5. [Debugging Techniques](#5-debugging-techniques)
6. [Browser DevTools Mastery](#6-browser-devtools-mastery)
7. [Performance Basics](#7-performance-basics)
8. [Local & Session Storage](#8-local--session-storage)
9. [Git & GitHub Basics for Frontend](#9-git--github-basics-for-frontend)

---

## 1. ES Modules (import/export)

### 📖 คำอธิบาย

ES Modules เป็นระบบสำหรับแบ่งโค้ด JavaScript ออกเป็นไฟล์แยกกัน ช่วยให้โค้ดเป็นระเบียบและใช้ซ้ำได้

**ประโยชน์:**

- Code reusability - ใช้ฟังก์ชันที่เขียนไว้หลายครั้ง
- Namespace isolation - หลีกเลี่ยง naming conflicts
- Readability - โค้ดอ่านง่ายขึ้น
- Maintainability - แก้ไขง่ายขึ้น

### 💻 Named Exports

**คำอธิบาย:** Named Exports ใช้เมื่อต้องการส่งออกฟังก์ชันหรือตัวแปรหลายตัวจากไฟล์เดียว แต่ละตัวมีชื่อเฉพาะ เมื่อ import ต้องใช้ชื่อเดียวกันกับ export หรือใช้ aliases ได้

**ประเภท:**

- Inline export: `export const name = value`
- Named export: `export function name() { }`
- Batch export: `export { name1, name2, name3 }`

**เมื่อใช้:**

- มีฟังก์ชันหรือค่าหลายตัว
- ต้องการให้ผู้ใช้เลือกนำเข้าเฉพาะที่ต้องการ
- ต้องการชื่อที่ชัดเจนสำหรับแต่ละ export

```javascript
// 📄 math.js
// Export ฟังก์ชันแต่ละตัว
export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

export const PI = 3.14159;
```

```javascript
// 📄 main.js
// Import ฟังก์ชนที่ต้องการ
import { add, subtract, PI } from "./math.js";

console.log(add(5, 3)); // 8
console.log(subtract(10, 4)); // 6
console.log(PI); // 3.14159
```

### 💻 Default Export

**คำอธิบาย:** Default Export ใช้เมื่อต้องการส่งออกฟังก์ชันที่สำคัญที่สุดเพียงฟังก์ชันเดียว สามารถ import โดยใช้ชื่ออะไรก็ได้ไม่จำเป็นต้องใช้ชื่อเดียวกัน ไฟล์หนึ่งสามารถมี default export ได้เพียงหนึ่งตัวเท่านั้น

**ลักษณะเฉพาะ:**

- ไฟล์หนึ่งมี default export ได้ 1 ตัวเท่านั้น (ส่วน named export ได้หลายตัว)
- ไม่ต้องใช้ curly braces {} เมื่อ import
- สามารถตั้งชื่อใดๆ ก็ได้เมื่อ import

**เมื่อใช้:**

- ไฟล์มี "หลัก" หลักเดียว (เช่น class หลัก, function หลัก)
- ต้องการให้ผู้ใช้ import ง่าย
- เช่น React components, main utilities

```javascript
// 📄 calculator.js
export default class Calculator {
  add(a, b) {
    return a + b;
  }

  subtract(a, b) {
    return a - b;
  }
}
```

```javascript
// 📄 main.js
import Calculator from "./calculator.js";

const calc = new Calculator();
console.log(calc.add(5, 3)); // 8
```

### 💻 Mixed Import/Export

**คำอธิบาย:** ไฟล์เดียวสามารถมี default export และ named exports พร้อมกันได้ ใช้เมื่อมี"ตัวหลัก" (default) และ"ตัวช่วย" (named) หลายตัว เมื่อ import ต้องใช้ default import ร่วมกับ destructuring สำหรับ named imports

**ข้อดี:**

- ได้ใช้ประโยชน์จาก default export ที่สั้น
- สามารถ export ตัวช่วยเพิ่มเติม
- บางครั้งจำเป็นสำหรับ backward compatibility

**โครงสร้าง:**

```
default export + named exports = mixed exports
```

```javascript
// 📄 utils.js
export function helper1() {
  /* ... */
}
export function helper2() {
  /* ... */
}
export default function mainFunction() {
  /* ... */
}
```

```javascript
// 📄 app.js
import mainFunc, { helper1, helper2 } from "./utils.js";

mainFunc();
helper1();
```

### 💻 Import All as Namespace

**คำอธิบาย:** ใช้ `import * as name` เพื่อนำเข้า named exports ทั้งหมดจากไฟล์เป็น object เดียว ทำให้โค้ดเป็นระเบียบและหลีกเลี่ยง naming conflicts เมื่อมี named exports หลายตัว

**วิธีการเข้าถึง:**

```
namespace.functionName()
namespace.variableName
```

**ประโยชน์:**

- ป้องกัน name collision - ถ้า import หลายไฟล์
- โค้ดเป็นระเบียบ - ชัดเจนว่ามาจากไฟล์ไหน
- ง่ายมากขึ้น - แทนจะ import ทีละตัว

**เมื่อใช้:**

- ต้องการหลายตัวจากไฟล์เดียว
- ต้องการให้ชัดเจนว่า exported จากที่ไหน
- ป้องกันชื่อซ้ำกัน

```javascript
// 📄 main.js
import * as math from "./math.js";

console.log(math.add(5, 3)); // 8
console.log(math.subtract(10, 4)); // 6
console.log(math.PI); // 3.14159
```

### 💻 Selective Import with Aliases

**คำอธิบาย:** ใช้ `as` keyword เพื่อตั้งชื่อใหม่ (alias) ให้กับ named imports ช่วยเมื่อต้องการชื่อที่มีความหมายมากกว่า หรือหลีกเลี่ยง naming conflicts ในไฟล์ปัจจุบัน

**ไวยากรณ์:**

```javascript
import { originalName as newName } from "path";
```

**ประเภทการใช้:**

- **เปลี่ยนชื่อเพื่อความชัดเจน** - `add as sum`
- **ป้องกัน conflict** - ถ้ามี function "add" อยู่แล้ว
- **เขียนแบบย่อ** - `getUserData as getData`

**เมื่อใช้:**

- ชื่อ export ไม่ตรงกับความต้องการ
- ไฟล์มี variable ชื่อซ้ำ
- ต้องการเขียนชื่อที่มีความหมายมากกว่า

```javascript
// 📄 main.js
import { add as sum, subtract as diff } from "./math.js";

console.log(sum(5, 3)); // 8
console.log(diff(10, 4)); // 6
```

### 📝 ลำดับการทำงาน

1. **Export** - เตรียมส่งออก: `export function ...`
2. **Import** - นำเข้าที่ต้องการ: `import { ... } from '...'`
3. **ใช้งาน** - ใช้งานในไฟล์ปัจจุบัน

### 🎯 Best Practices

```javascript
// ดี - ชื่อตรงไปตรงมา
export function validateEmail(email) {
  /* ... */
}
export function formatDate(date) {
  /* ... */
}

// ไม่ดี - ชื่อสับสน
export function func1() {
  /* ... */
}
export function func2() {
  /* ... */
}
```

---

## 2. Module Bundlers (Vite & Webpack)

### 📖 คำอธิบาย

Module bundlers รวมไฟล์ JavaScript หลายตัว และ dependencies เป็นไฟล์เดียว (bundle) เพื่อให้เบราว์เซอร์โหลดได้

**ทำไมต้องใช้?**

- Combine files - รวมหลายไฟล์เป็นหนึ่ง
- Handle imports - จัดการ ES modules
- Minification - ลดขนาดโค้ด
- Build optimization - ปรับให้เร็ว
- Tree shaking - ลบโค้ดที่ไม่ใช้

### 🎯 Vite (Modern & Fast)

**ข้อดี:**

- Lightning fast - เร็วมาก
- Hot Module Replacement (HMR) - เปลี่ยนแปลงเห็นได้ทันที
- Minimal config - ตั้งค่าง่าย
- ESM dev server - ใช้ ES modules โดยตรง

**ขั้นตอน Setup:**

```bash
# 1️⃣ สร้าง project
npm create vite@latest my-app -- --template vanilla

# 2️⃣ เข้าไปใน folder
cd my-app

# 3️⃣ ติดตั้ง dependencies
npm install

# 4️⃣ รัน dev server
npm run dev

# 5️⃣ Build for production
npm run build
```

### 📦 npm run build

**คำอธิบาย:**
`npm run build` คือคำสั่งที่คอมไพล์และเตรียมโค้ดของเราให้พร้อมสำหรับปล่อยออกมายังเซิร์ฟเวอร์จริง ทำให้โค้ดเร็ว เล็ก และปลอดภัย

**ขั้นตอนที่ทำงาน:**

1. **Bundling (รวมไฟล์)**
   - รวมไฟล์ JavaScript หลายตัวเป็นไฟล์เดียว (bundle)
   - รวม modules ทั้งหมดตามความสัมพันธ์ของ imports/exports
   - ลบส่วนของโค้ดที่ไม่ใช้ (Tree shaking)

2. **Minification (บีบอัดโค้ด)**
   - ลบ whitespace, comments
   - เปลี่ยนชื่อตัวแปรให้สั้น: `myVariable` → `a`
   - ลบ semicolon ที่ไม่จำเป็น
   - ผลลัพธ์: โค้ดเล็กลง ~70%

3. **Transpiling (แปลงโค้ด)**
   - แปลง ES6+ เป็น ES5 เพื่อให้ browser เก่าเข้าใจได้
   - `const` → `var`, arrow functions → regular functions
   - ใช้ Babel หรือ swc

4. **Asset Optimization (ปรับปรุงสินทรัพย์)**
   - บีบอัดภาพ (images)
   - แยก CSS ออกมาเป็นไฟล์แยก
   - เพิ่ม cache-busting (ชื่อไฟล์มี hash)

5. **Output (ส่งออก)**
   - สร้างโฟลเดอร์ `dist/` (distribution)
   - เก็บไฟล์ที่พร้อมปล่อยออกมา
   - ไม่รวมโค้ดต้นฉบับ, node_modules

### 🔄 Babel และ swc - คืออะไร?

**Babel คืออะไร?**

Babel เป็น transpiler (ตัวแปลง) ที่แปลงโค้ด JavaScript สมัยใหม่ (ES6+) เป็นโค้ด JavaScript เก่า (ES5) ที่ browser เก่าสามารถเข้าใจได้

**ทำไมต้องใช้?**

- Browser เก่า (IE 11 ฯลฯ) ไม่เข้าใจ ES6+
- Babel แปลง ES6+ → ES5 เพื่อให้ browser เก่าร่วมด้วย
- สามารถใช้ฟีเจอร์ล่าสุดของ JavaScript ได้

**ตัวอย่างการแปลง:**

```javascript
// ✍️ Original Code (ES6+)
const add = (a, b) => a + b;
const user = { name: "John", age: 30 };
const { name } = user;

// 🔄 After Babel (ES5)
var add = function (a, b) {
  return a + b;
};
var user = { name: "John", age: 30 };
var name = user.name;
```

**Configuration:**

```json
// .babelrc หรือ babel.config.json
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "browsers": ["IE 11", "last 2 versions"]
        }
      }
    ]
  ]
}
```

---

**swc คืออะไร?**

swc (Speedy Web Compiler) เป็น transpiler ที่ทำสิ่งเดียวกับ Babel แต่เร็วกว่า **ประมาณ 10-20 เท่า**! ถูกเขียนด้วยภาษา Rust (ภาษาที่ประสิทธิภาพสูง)

**ข้อดี:**

- **วเร็วกว่า** - Babel 10-20 เท่า
- Standalone tool - ไม่ต้องขึ้นกับ Node.js
- Compatible - ใช้แทน Babel ได้โดยตรง
- รองรับ TypeScript, JSX โดยเบื้องต้น

**ตัวอย่างการใช้:**

```bash
# ✅ ใช้ swc แปลงแทน Babel
swc input.js --out-file output.js
```

---

**เปรียบเทียบ Babel vs swc:**

| ลักษณะ        | Babel       | swc                             |
| ------------- | ----------- | ------------------------------- |
| ⚡ ความเร็ว   | ปานกลาง     | **เร็วมาก (10-20x)**            |
| 📝 ซินแทกซ์   | JavaScript  | Rust                            |
| 🔌 Plugins    | มากมาย      | น้อย (แต่เพิ่มเติมได้ในภายหลัง) |
| 🎯 TypeScript | ผ่าน preset | Native support                  |
| 🛠️ Setup      | ตั้งค่าเยอะ | เรียบง่าย                       |
| 👥 Community  | ใหญ่        | เริ่มต้น (แต่เติบโตเร็ว)        |

---

**ใช้เมื่อไหร่?**

**ใช้ Babel:**

- ต้องการ plugins special มาก
- ต้องการ community ใหญ่
- Legacy projects
- ต้องการความคุ้นเคย

**ใช้ swc:**

- ต้องการ performance ที่ดี (production)
- Modern projects (Vite, Next.js 12+)
- ต้องการ native TypeScript support
- ต้องการ build ที่เร็ว

### ❓ ใช้ทั้ง Babel และ swc ด้วยหรือเลือกอันเดียว?

**ตอบ: เลือกเพียงตัวเดียวเท่านั้น!** ไม่ต้องใช้ทั้งคู่

**เหตุผล:**

- ทั้ง Babel และ swc ทำสิ่งเดียวกัน = **transpiler ทั้งคู่**
- ถ้าใช้ทั้งคู่ = ช้าลง (ไม่มีประโยชน์)
- ต้องเลือกเพียงอันเดียวเท่านั้น

**เครื่องมือต่างๆ ใช้ transpiler ต่างกัน:**

| เครื่องมือ          | ใช้ Transpiler ไหน            |
| ------------------- | ----------------------------- |
| Vite                | ✅ **swc** (ด้วย esbuild)     |
| Next.js 13+         | ✅ **swc**                    |
| Next.js 12          | ✅ **swc** (optional)         |
| Webpack 5           | ✅ **Babel** (default)        |
| Create React App    | ✅ **Babel** (default)        |
| TypeScript Compiler | ✅ **tsc** (ไม่ใช่ Babel/swc) |

**ในบริบท npm run build:**

```bash
# Vite (ใช้ swc/esbuild)
npm run build  # ⚡ เร็ว

# Webpack (ใช้ Babel)
npm run build  # ช้ากว่า

# Next.js (ใช้ swc)
npm run build  # ⚡ เร็วมากขึ้น
```

**วิธีตรวจสอบว่าโปรเจคใช้ Transpiler ไหน:**

```bash
# 1️⃣ ดู package.json
cat package.json
# ค้นหา "babel" หรือ "swc"

# 2️⃣ ดู config
# Babel → .babelrc หรือ babel.config.js
# swc → .swcrc หรือ swc ใน package.json

# 3️⃣ ดู node_modules
ls node_modules | grep babel  # ถ้ามี = ใช้ Babel
ls node_modules | grep swc    # ถ้ามี = ใช้ swc
```

**ตัวอย่าง package.json:**

```json
// ❌ ผิด - ติดตั้งทั้ง Babel และ swc
{
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@swc/core": "^1.3.0"  // ไม่ควรติดตั้งทั้งคู่
  }
}

// ✅ ถูก - เลือก Babel
{
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@babel/preset-env": "^7.20.0"
  }
}

// ✅ ถูก - เลือก swc
{
  "devDependencies": {
    "@swc/core": "^1.3.0",
    "@swc/cli": "^0.1.0"
  }
}
```

**ตัวอย่างการเปลี่ยนจาก Babel เป็น swc:**

```bash
# 1️⃣ ถอด Babel
npm uninstall @babel/core @babel/preset-env

# 2️⃣ ติดตั้ง swc
npm install -D @swc/core @swc/cli

# 3️⃣ ลบไฟล์ .babelrc
rm .babelrc

# 4️⃣ สร้าง .swcrc
cat > .swcrc << 'EOF'
{
  "env": {
    "targets": {
      "browsers": ["IE 11", "last 2 versions"]
    }
  }
}
EOF

# 5️⃣ รัน build
npm run build
```

**ลำดับการทำงาน Build:**

```
✅ ตัวแบบที่ถูก:
source code
  ↓
[Transpiler: เลือกตัวเดียว - Babel หรือ swc]
  ↓
[Minifier: Terser]
  ↓
output (dist/)

❌ ตัวแบบที่ผิด:
source code
  ↓
[Transpiler: Babel]
  ↓
[Transpiler: swc] ← ไม่จำเป็น ซ้ำแล้ว
  ↓
output ← ช้าเสียเวลา
```

---

**ความแตกต่างจากตัว Bundler:**

```
Transpiler (Babel/swc):
├─ ES6+ Code → ES5 Code
└─ ไม่รวมไฟล์ เพียงแค่แปลง

Bundler (Webpack/Vite):
├─ รวมไฟล์หลายตัว
├─ ใช้ Transpiler (Babel/swc) ด้านใน
├─ Minify & Optimize
└─ Output → dist/
```

**แตกต่างจาก Minifier:**

```
Transpiler (Babel):
├─ เปลี่ยน syntax
└─ const a = 1; → var a = 1;

Minifier (Terser):
├─ ลบ whitespace & comments
└─ const calculateTotal = (e) => e; → const calculateTotal=e=>e;

ใช้คู่กัน:
├─ Transpile ES6+ → ES5 (Babel)
├─ Minify ES5 (Terser)
└─ ผลลัพธ์ = โค้ดเล็กและ compatible
```

**แตกต่างจาก Compiler:**

```
JavaScript Transpiler (Babel/swc):
├─ JS → JS (เปลี่ยน syntax เท่านั้น)
└─ ไม่เปลี่ยนภาษา

Compiler (TypeScript):
├─ TS → JS (ป้าย syntax & type check)
└─ ออกมาเป็นภาษาใหม่
```

**แตกต่างจาก Build Process:**

```
npm run build:
├─ 1. Transpile (Babel/swc)  ← แปลง syntax
├─ 2. Bundle (Webpack/Vite)  ← รวมไฟล์
├─ 3. Minify (Terser)        ← บีบอัด
└─ Output → dist/

npm run dev:
├─ ข้าม minify
└─ ใช้ HMR (Hot Module Reload)
```

**แตกต่างจาก Polyfill:**

```
Transpiler (Babel):
├─ เปลี่ยน syntax
├─ const → var
├─ arrow → function
└─ ไม่แก้ API ที่ขาด

Polyfill:
├─ เพิ่ม API ที่ขาด
├─ Promise (ถ้า browser ไม่มี)
├─ Array.includes()
└─ ต้องใช้คู่กับ Transpiler
```

**ตัวอย่างจริง:**

```javascript
// Modern Code
class User {
  constructor(name) {
    this.name = name;
  }

  async fetchData() {
    const data = await fetch("/api/user");
    return data.json();
  }
}

// ✅ After Babel (ES5 compatible)
var User = function (name) {
  this.name = name;
};

User.prototype.fetchData = function () {
  var _this = this;
  return fetch("/api/user").then(function (data) {
    return data.json();
  });
};
```

**แตกต่างจาก Bundler ด้วย:**

Bundler (Webpack/Vite):

```
input:
├─ main.js
├─ utils.js
└─ components.js
↓ (รวมทั้งหมด)
output:
└─ dist/bundle.js
```

Transpiler (Babel/swc):

```
input:
├─ main.js (ES6+)
├─ utils.js (ES6+)
└─ components.js (ES6+)
↓ (แปลง syntax)
output:
├─ main.js (ES5)
├─ utils.js (ES5)
└─ components.js (ES5)
```

**แตกต่างจาก Parser:**

```
Parser:
├─ โค้ด → Abstract Syntax Tree (AST)
└─ เพียงแค่ วิเคราะห์

Transpiler:
├─ โค้ด → AST → โค้ดใหม่
└─ วิเคราะห์ + เปลี่ยนแปลง
```

**แตกต่างจาก Interpreter:**

```
Transpiler (Babel):
├─ ES6 → ES5 (offline)
└─ จากนั้นรัน

Interpreter (Browser):
├─ อ่านและรัน (real-time)
└─ ทีละบรรทัด
```

---

**แตกต่างจาก npm run dev:**

| npm run dev | npm run build             |
| ----------- | ------------------------- |
| ข้าม Minify | ใช้ Transpiler + Minifier |
| เหมาะดีบั๊ก | เหมาะ Production          |
| Hot Reload  | Output → dist/            |

**แตกต่างจาก npm run preview:**

```bash
npm run dev     # ใช้ dev server (HMR) - เร็วแต่ไม่ minify
npm run build   # สร้าง dist/ - ช้า แต่เล็กอัดแน่น
npm run preview # ดู dist/ ที่ built แล้ว - ใหญ่ + ช้า
```

---

5. **Output (ส่งออก)**
   - สร้างโฟลเดอร์ `dist/` (distribution)
   - เก็บไฟล์ที่พร้อมปล่อยออกมา
   - ไม่รวมโค้ดต้นฉบับ, node_modules

**ความแตกต่างจาก npm run dev:**

| npm run dev           | npm run build          |
| --------------------- | ---------------------- |
| เร็ว - ไม่มีการบีบอัด | ช้า - มีการค่อนข้างมาก |
| โค้ดชัดเจน            | โค้ดซ้อน               |
| ไฟล์ใหญ่              | ไฟล์เล็ก (5-10 เท่า)   |
| เหมาะทดสอบ            | เหมาะ Production       |
| ใช้หน่วยความจำมาก     | ประหยัด                |

**ตัวอย่างการเปลี่ยนแปลง:**

```javascript
// Development
const calculateTotal = (items) => {
  const result = items.reduce((sum, item) => sum + item.price, 0);
  return result;
};

// Production (Minified)
const calculateTotal = (e) => e.reduce((e, t) => e + t.price, 0);
```

**Output จากการ Build:**

```
dist/
├── index.html              # HTML เดียว
├── assets/
│   ├── index-abc123.js    # JavaScript bundle (minified)
│   ├── style-def456.css   # CSS bundle (minified)
│   └── logo-ghi789.png    # ภาพ (compressed)
└── ...
```

**ไฟล์ที่ได้:**

- `index.html` - ไฟล์ HTML ที่อ้างอิงไฟล์ minified ทั้งหมด
- `assets/index-[hash].js` - ไฟล์ JavaScript ที่บีบอัด (hash เพื่อให้ browser รู้ว่าเป็นเวอร์ชั่นใหม่)
- `assets/style-[hash].css` - ไฟล์ CSS ที่บีบอัด
- `assets/[filename]-[hash].[ext]` - ภาพและอื่นๆ

**ขั้นตอนหลังจาก Build:**

```bash
# ✅ 1. Build
npm run build

# ✅ 2. ทดสอบ production build ในเครื่อง
npm run preview

# ✅ 3. อัปโหลด dist/ ไปยังเซิร์ฟเวอร์
# ใช้ FTP, GitHub Pages, Netlify, Vercel เป็นต้น

# ✅ 4. เปิด website
# https://mysite.com
```

### 📤 การอัปโหลด dist/ ไปยังเซิร์ฟเวอร์

#### **1️⃣ FTP (Traditional Server)**

**คืออะไร:**
FTP = File Transfer Protocol ใช้ในการส่งไฟล์ไปเซิร์ฟเวอร์แบบเก่า

**เหมาะกับ:**

- Shared hosting (GoDaddy, Bluehost)
- Traditional web hosting
- ไม่มี CI/CD automation

**วิธี 1: ใช้ GUI (Filezilla)**

```
1️⃣ ดาวน์โหลด FileZilla
   → https://filezilla-project.org/

2️⃣ ตั้งค่า FTP Connection
   Host: ftp.your-domain.com
   Username: your_username
   Password: your_password
   Port: 21

3️⃣ เปิด folder ทั้งสอง
   ซ้าย: dist/ (ในเครื่องของคุณ)
   ขวา: public_html/ (เซิร์ฟเวอร์)

4️⃣ Drag & drop ไฟล์ทั้งหมดจาก dist/ → public_html/
   ✅ index.html
   ✅ assets/
   ✅ etc.

5️⃣ เปิด browser → https://your-domain.com
```

**วิธี 2: ใช้ Command Line**

```bash
# ติดตั้ง lftp
npm install -g lftp

# สร้าง script deploy.sh
cat > deploy.sh << 'EOF'
#!/bin/bash
lftp -u your_username,your_password ftp.your-domain.com << FTP_COMMANDS
cd public_html
mirror -R dist/ .
quit
FTP_COMMANDS
EOF

# รันให้ execute ได้
chmod +x deploy.sh

# รัน
./deploy.sh
```

**ข้อดี:**

- ✅ ถูก (hosting ส่วนใหญ่ฟรี)
- ✅ ควบคุมได้ครบถ้วน

**ข้อเสีย:**

- ❌ ช้า
- ❌ ง่ายผิดพลาด
- ❌ ไม่ automatic

---

#### **2️⃣ GitHub Pages (Free & Easy)**

**คืออะไร:**
GitHub Pages = free hosting จาก GitHub สำหรับ static websites (no backend)

**เหมาะกับ:**

- Portfolio, blog, documentation
- Open source projects
- ฟรี
- ต้องใช้ GitHub

**วิธี:**

```bash
# 1️⃣ สร้าง repository ใหม่บน GitHub
   ชื่อ: username.github.io
   (เปลี่ยน username เป็นชื่อ GitHub ของคุณ)

# 2️⃣ Clone ลงเครื่อง
git clone https://github.com/username/username.github.io.git
cd username.github.io

# 3️⃣ Build
npm run build

# 4️⃣ Copy dist/ ไปยัง root
cp -r dist/* .
# หรือ: xcopy dist /Y (Windows)

# 5️⃣ Commit & Push
git add .
git commit -m "Deploy website"
git push -u origin main

# ✅ เปิด browser
   https://username.github.io
```

**ตั้งค่าให้ publish จาก dist/:**

```bash
# package.json
{
  "scripts": {
    "build": "vite build",
    "deploy": "npm run build && gh-pages -d dist"
  },
  "devDependencies": {
    "gh-pages": "^5.0.0"
  }
}

# ติดตั้ง gh-pages
npm install -D gh-pages

# Deploy แบบเดียว
npm run deploy
```

**วิธีตั้งค่า (ครั้งแรก):**

```bash
# 1️⃣ GitHub Settings
   → Repository
   → Pages
   → Source: Deploy from a branch
   → Branch: gh-pages, /root

# 2️⃣ Deploy
npm run deploy

# ✅ เปิด
   https://username.github.io
```

**ข้อดี:**

- ✅ ฟรี 100%
- ✅ Automatic deployment
- ✅ ติดตั้งง่าย

**ข้อเสีย:**

- ❌ ไม่เหมาะ dynamic sites
- ❌ ต้องใช้ GitHub
- ❌ ไม่มี backend database

---

#### **3️⃣ Netlify (Recommended for Frontend)**

**คืออะไร:**
Netlify = hosting platform ที่ออกแบบสำหรับ frontend developers

**เหมาะกับ:**

- Static sites, SPAs
- ฟรี (tier free)
- Automatic deploys
- Custom domains

**วิธี:**

```bash
# 1️⃣ สมัครสมาชิก
   → https://app.netlify.com/signup

# 2️⃣ เชื่อมต่อ GitHub
   (Netlify จะเห็น repositories)

# 3️⃣ New site from Git
   → Select repository → Deploy

# 4️⃣ ตั้งค่า Build Settings
   Build command: npm run build
   Publish directory: dist

# 5️⃣ Netlify จะ auto deploy
   เมื่อคุณ push code ไป GitHub
   ✅ No need to upload manually!

# 6️⃣ เปิด website
   https://mysite.netlify.app
```

**Deploy แบบ Manual:**

```bash
# ติดตั้ง Netlify CLI
npm install -g netlify-cli

# Build
npm run build

# Deploy
netlify deploy --prod --dir=dist

# ✅ เปิด
   https://mysite.netlify.app
```

**เพิ่ม Custom Domain:**

```
Netlify Dashboard:
├─ Domain settings
├─ Add custom domain
├─ example.com
└─ ตั้งค่า DNS เพื่อชี้ไปที่ Netlify
```

**ข้อดี:**

- ✅ ฟรี
- ✅ Automatic git deployment
- ✅ Built-in SSL/HTTPS
- ✅ CDN ด้วย
- ✅ ง่ายที่สุด

**ข้อเสีย:**

- ❌ ไม่เหมาะ heavy backend
- ❌ Bandwidth จำกัด (tier free)

---

#### **4️⃣ Vercel (Best for Next.js & SPAs)**

**คืออะไร:**
Vercel = hosting สำหรับ modern frontend + serverless functions

**เหมาะกับ:**

- Next.js, React SPAs
- Serverless API
- ฟรี
- Performance ดี

**วิธี:**

```bash
# 1️⃣ สมัครสมาชิก
   → https://vercel.com/signup

# 2️⃣ Import Project from GitHub
   (เชื่อมต่อ GitHub account)

# 3️⃣ Select repository

# 4️⃣ Framework: Vite
   Build Command: npm run build
   Output Directory: dist

# 5️⃣ Deploy
   Vercel จะ auto deploy!

# 6️⃣ เปิด
   https://mysite.vercel.app
```

**Deploy แบบ Manual:**

```bash
# ติดตั้ง Vercel CLI
npm install -g vercel

# Deploy
vercel --prod

# ✅ รับ link
```

**ข้อดี:**

- ✅ ฟรี
- ✅ Serverless functions
- ✅ ดีที่สุดสำหรับ Next.js
- ✅ Performance อย่างดี

**ข้อเสีย:**

- ❌ ไม่เหมาะ heavy backend

---

#### **5️⃣ Traditional VPS/Cloud (AWS, DigitalOcean)**

**คืออะไร:**
Virtual Private Server = เซิร์ฟเวอร์เต็มตัว ควบคุมได้ทั้งหมด

**เหมาะกับ:**

- Full control ต้องการ
- Backend + Frontend
- Large projects
- Custom configuration

**วิธี (DigitalOcean):**

```bash
# 1️⃣ สร้าง Droplet (VPS)
   → https://cloud.digitalocean.com

# 2️⃣ SSH เข้าเซิร์ฟเวอร์
ssh root@your_server_ip

# 3️⃣ ติดตั้ง dependencies
apt update
apt install -y nodejs npm

# 4️⃣ Clone/upload project
git clone your_repo.git
cd your_repo
npm install

# 5️⃣ Build
npm run build

# 6️⃣ Setup web server (nginx)
apt install -y nginx

# 7️⃣ Copy dist/ → nginx
cp -r dist/* /var/www/html/

# 8️⃣ Start nginx
systemctl start nginx

# ✅ เปิด
   https://your_server_ip
```

**ข้อดี:**

- ✅ Control ทั้งหมด
- ✅ Scalable
- ✅ Backend compatible

**ข้อเสีย:**

- ❌ ไม่ฟรี (มีค่าใช้จ่าย)
- ❌ ซับซ้อนกว่า
- ❌ ต้อง DevOps knowledge

---

#### **📊 เปรียบเทียบแพลตฟอร์ม:**

| Platform         | ราคา | Setup   | Features     | Best for            |
| ---------------- | ---- | ------- | ------------ | ------------------- |
| **FTP**          | ราคา | ยุ่ง    | ง่าย         | Traditional hosting |
| **GitHub Pages** | ฟรี  | ง่าย    | Limited      | Portfolios, docs    |
| **Netlify**      | ฟรี  | ง่ายมาก | CDN, SSL     | Static sites        |
| **Vercel**       | ฟรี  | ง่ายมาก | Serverless   | Next.js, SPAs       |
| **DigitalOcean** | ราคา | ยุ่ง    | Full control | Large projects      |
| **AWS**          | ราคา | ยุ่งมาก | Unlimited    | Enterprise          |

---

#### **🎯 ลำดับการทำงาน (Production Deployment):**

```
1. npm run build
   ↓
2. npm run preview (ทดสอบ)
   ↓
3. เลือก Platform (GitHub Pages/Netlify/Vercel/FTP)
   ↓
4. Upload หรือ Push ไป Git
   ↓
5. Platform deploy dist/
   ↓
6. บ่อยครั้ง auto-test + ถ้า pass ก็ deploy
   ↓
7. เปิด website https://your-domain.com
   ↓
8. ถ้ามี error → fix → commit → re-deploy
```

---

#### **🚀 Best Practices สำหรับ Production:**

```javascript
// ✅ 1. เสมอ build ก่อน deploy
npm run build

// ✅ 2. ทดสอบ build locally
npm run preview

// ✅ 3. Use .gitignore ให้ถูก
.gitignore:
├─ node_modules/   (ไม่ upload)
├─ dist/           (generated - ไม่ต้อง)
└─ .env.local      (sensitive data)

// ✅ 4. ตั้งค่า Environment Variables
.env (development)
.env.production (production)

// ✅ 5. Set correct base URL
// vite.config.js
export default defineConfig({
  base: '/my-app/'  // ถ้า hosted on subdirectory
})

// ✅ 6. Enable caching
// in dist/index.html หรือ .netlify/headers
Cache-Control: max-age=31536000  // for dist/assets/*
Cache-Control: max-age=0         // for index.html

// ✅ 7. Monitor size
npm run build
# ดู dist/ size ให้น้อยที่สุด

// ✅ 8. Test before deploy
npm run build && npm run preview
```

---

#### **⚠️ Common Mistakes:**

```bash
# ❌ ผิด 1: Upload src/ แทน dist/
npm run build
# upload src/ ← ผิด! (ยังไม่ย่อย)

# ✅ ถูก
npm run build
# upload dist/ ← ถูก!

# ❌ ผิด 2: Upload โดยไม่ build
# copy src/ to server ← ผิด!

# ✅ ถูก
npm run build
npm run preview
# deploy dist/

# ❌ ผิด 3: ใช้ dev server ใน production
npm run dev  # ← เพื่อ development เท่านั้น

# ✅ ถูก
npm run build   # ← production
npm run preview # ← test locally

# ❌ ผิด 4: ลืม push code ไป Git
# deploy เพียงอย่าง แต่ยังไม่ commit

# ✅ ถูก
git add .
git commit -m "Update"
git push
# ← THEN deploy
```

---

**Best Practices:**

```bash
# ✅ ดี - upload แต่ dist/
npm run build
# ... upload เฉพาะ dist/ เพราะจะเล็กที่สุด
```

---

**โครงสร้าง Project:**

```
my-app/
├── index.html
├── package.json
├── vite.config.js
└── src/
    ├── main.js
    ├── style.css
    └── components/
        ├── Header.js
        └── Footer.js
```

**vite.config.js:**

```javascript
import { defineConfig } from "vite";

export default defineConfig({
  // ⚙️ ตั้งค่า development
  server: {
    port: 3000,
    open: true, // เปิด browser อัตโนมัติ
  },

  // ⚙️ ตั้งค่า build
  build: {
    outDir: "dist",
    minify: "terser",
  },
});
```

### 🎯 Webpack (Powerful & Flexible)

**ข้อดี:**

- 🎯 Powerful - มีความสามารถมาก
- 🔌 Plugins ecosystem - มี plugin มากมาย
- 🎛️ Fine-grained control - ควบคุมได้ลูกครัว
- 🎭 Complex projects - เหมาะสำหรับโปรเจคใหญ่

**ตัวอย่าง webpack.config.js:**

```javascript
const path = require("path");

module.exports = {
  // 📥 Entry point
  entry: "./src/index.js",

  // 📤 Output
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
  },

  // 🔧 Loaders
  module: {
    rules: [
      // CSS loader
      {
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      },

      // Image loader
      {
        test: /\.(png|jpg|gif)$/i,
        type: "asset/resource",
      },
    ],
  },

  // 🔌 Plugins
  plugins: [
    // เพิ่ม plugins ตรงนี้
  ],

  // 🔄 Dev server
  devServer: {
    port: 8080,
    open: true,
    hot: true,
  },
};
```

### 📊 เปรียบเทียบ Vite vs Webpack

| ฟีเจอร์      | Vite           | Webpack              |
| ------------ | -------------- | -------------------- |
| ความเร็ว     | ⚡⚡⚡ Fast    | ⚡⚡ Normal          |
| Setup        | ⭐⭐ Simple    | ⭐⭐⭐⭐ Complex     |
| ความยืดหยุ่น | ⭐⭐⭐ Decent  | ⭐⭐⭐⭐⭐ Excellent |
| Community    | ⭐⭐⭐ Growing | ⭐⭐⭐⭐⭐ Huge      |
| สำหรับ       | Small-Medium   | Medium-Large         |

---

## 3. NPM & Package Management

### 📖 คำอธิบาย

**NPM (Node Package Manager)** - ที่เก็บเก็บไลบรารี่ JavaScript สำหรับใช้ซ้ำ

**package.json - ไฟล์สำคัญ:**

- 📦 Project info - ชื่อ, เวอร์ชั่น
- 📚 Dependencies - ไลบรารี่ที่ใช้
- 🔧 Scripts - คำสั่ง npm

### 💻 สร้าง package.json

```bash
npm init -y

# Prompt จะถาม:
# - name: ชื่อโปรเจค
# - version: เวอร์ชั่น (default 1.0.0)
# - description: อธิบายโปรเจค
# - main: entry point (default index.js)
# - scripts: คำสั่ง custom
```

### 💻 ตัวอย่าง package.json

```json
{
  "name": "my-web-app",
  "version": "1.0.0",
  "description": "A modern web application",
  "main": "src/index.js",

  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "test": "jest"
  },

  "dependencies": {
    "axios": "^1.3.0",
    "lodash": "^4.17.21"
  },

  "devDependencies": {
    "vite": "^4.0.0",
    "@vitejs/plugin-vue": "^4.0.0",
    "jest": "^29.0.0"
  }
}
```

### 💻 Common NPM Commands

```bash
# 📦 ติดตั้ง dependencies
npm install
npm install axios

# 🔄 Update packages
npm update
npm update axios

# 🗑️ ลบ package
npm uninstall axios

# 📋 ดูรายการ packages
npm list
npm list --depth=0

# 🔍 ค้นหา outdated packages
npm outdated

# 🧹 ทำความสะอาด
npm cache clean --force
npm prune
```

### 📊 Dependencies vs DevDependencies

```javascript
// dependencies - ต้องใช้ในโปรดักชัน
"dependencies": {
  "axios": "^1.3.0",      // HTTP requests (ใช้ทั้งในการทำงาน)
  "lodash": "^4.17.21"    // Utilities (ใช้ทั้งในการทำงาน)
}

// devDependencies - ใช้แค่ในขั้น development
"devDependencies": {
  "vite": "^4.0.0",        // 🔧 Bundler (ใช้แค่ตอน build)
  "jest": "^29.0.0",       // 🧪 Testing (ใช้แค่ตอน test)
  "prettier": "^3.0.0"     // 🎨 Code formatter (ใช้แค่ development)
}
```

### 📝 Semantic Versioning

```
^1.3.0  → 1.x.x  (ยอม minor และ patch updates)
~1.3.0  → 1.3.x  (ยอม patch updates เท่านั้น)
1.3.0   → 1.3.0  (exact version)
*       → any version
```

### 🎯 Best Practices

```bash
# ดี - ระบุ package ที่ต้องใช้
npm install axios

# ดี - ติดตั้ง dev dependency
npm install --save-dev jest

# ไม่ดี - ติดตั้งโดยไม่บันทึก
npm install axios --no-save
```

---

## 4. Code Organization & Project Structure

### 📖 คำอธิบาย

การจัดระเบียบโค้ดช่วยให้:

- 📂 หาไฟล์ได้ง่าย
- 👥 ทีมทำงานได้ดี
- 🔧 Maintain ได้ง่าย
- 🧪 Test ได้ง่าย

### 📁 โครงสร้างที่ดี

```
my-app/
├── src/
│   ├── index.html
│   ├── main.js
│   ├── style.css
│   │
│   ├── components/
│   │   ├── Header.js
│   │   ├── Footer.js
│   │   └── Modal.js
│   │
│   ├── modules/
│   │   ├── api.js          // API calls
│   │   ├── storage.js      // localStorage
│   │   └── utils.js        // Utility functions
│   │
│   ├── pages/
│   │   ├── home.js
│   │   ├── about.js
│   │   └── contact.js
│   │
│   └── styles/
│       ├── main.css
│       ├── variables.css
│       └── responsive.css
│
├── tests/
│   ├── api.test.js
│   └── utils.test.js
│
├── public/
│   ├── images/
│   ├── fonts/
│   └── favicon.ico
│
├── package.json
├── vite.config.js
└── README.md
```

### 💻 ตัวอย่าง Modular Code

**📄 src/modules/api.js**

```javascript
const API_BASE_URL = "https://api.example.com";

// 📝 ฟังก์ชนสำหรับเรียก API
export async function fetchUsers() {
  try {
    const response = await fetch(`${API_BASE_URL}/users`);
    if (!response.ok) throw new Error("Failed to fetch");
    return await response.json();
  } catch (error) {
    console.error("Error fetching users:", error);
    throw error;
  }
}

export async function fetchUserById(id) {
  try {
    const response = await fetch(`${API_BASE_URL}/users/${id}`);
    if (!response.ok) throw new Error("User not found");
    return await response.json();
  } catch (error) {
    console.error(`Error fetching user ${id}:`, error);
    throw error;
  }
}
```

**📄 src/modules/storage.js**

```javascript
// 📝 ฟังก์ชันสำหรับ localStorage
export function saveToStorage(key, value) {
  try {
    localStorage.setItem(key, JSON.stringify(value));
  } catch (error) {
    console.error("Storage error:", error);
  }
}

export function getFromStorage(key) {
  try {
    const item = localStorage.getItem(key);
    return item ? JSON.parse(item) : null;
  } catch (error) {
    console.error("Storage error:", error);
    return null;
  }
}

export function removeFromStorage(key) {
  try {
    localStorage.removeItem(key);
  } catch (error) {
    console.error("Storage error:", error);
  }
}
```

**📄 src/modules/utils.js**

```javascript
// 📝 Utility functions
export function debounce(func, delay) {
  let timeoutId;
  return function (...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
}

export function throttle(func, delay) {
  let lastCall = 0;
  return function (...args) {
    const now = Date.now();
    if (now - lastCall >= delay) {
      lastCall = now;
      func.apply(this, args);
    }
  };
}

export function capitalize(str) {
  return str.charAt(0).toUpperCase() + str.slice(1);
}
```

**📄 src/components/Header.js**

```javascript
import { getFromStorage } from "../modules/storage.js";
import { capitalize } from "../modules/utils.js";

export function Header() {
  const user = getFromStorage("user");

  return `
    <header>
      <h1>My App</h1>
      <nav>
        <a href="/">Home</a>
        <a href="/about">About</a>
        ${user ? `<span>Welcome, ${capitalize(user.name)}</span>` : ""}
      </nav>
    </header>
  `;
}
```

**📄 src/main.js**

```javascript
import { Header } from "./components/Header.js";
import { fetchUsers } from "./modules/api.js";
import { saveToStorage } from "./modules/storage.js";
import "./style.css";

// 🎨 Render header
document.body.innerHTML = Header();

// 📡 Fetch users
(async () => {
  try {
    const users = await fetchUsers();
    saveToStorage("users", users);
    console.log("Users:", users);
  } catch (error) {
    console.error("App error:", error);
  }
})();
```

### 🎯 Best Practices

```javascript
// ดี - ชัดเจน
// src/modules/api.js - สำหรับ API calls
export async function getUser(id) {
  /* ... */
}

// ดี - แยก logic
// src/modules/validation.js - สำหรับ validation
export function validateEmail(email) {
  /* ... */
}

// ไม่ดี - ทำเยอะเกินไปในไฟล์เดียว
export function getUser(id) {
  /* ... */
}
export function validateEmail(email) {
  /* ... */
}
export function formatDate(date) {
  /* ... */
}
```

---

## 5. Debugging Techniques

### 📖 คำอธิบาย

Debugging คือการหาและแก้ไขข้อผิดพลาด ข้อ tips ช่วยให้หาบั้ก เร็วขึ้น

### 💻 console Methods

```javascript
// 📋 console.log - แสดงข้อมูล
console.log("ข้อมูล:", data);

// ⚠️ console.warn - แสดงคำเตือน (สีเหลือง)
console.warn("This might be a problem:", value);

// console.error - แสดง error (สีแดง)
console.error("Something went wrong:", error);

// ℹ️ console.info - แสดงข้อมูล (ฟ้า)
console.info("Information:", details);

// console.assert - ตรวจสอบเงื่อนไข
console.assert(value > 0, "Value must be positive");

// 📊 console.table - แสดง object/array เป็นตาราง
const users = [
  { id: 1, name: "Alice", age: 25 },
  { id: 2, name: "Bob", age: 30 },
];
console.table(users);

// 🎯 console.group - จัดกลุ่ม logs
console.group("User Info");
console.log("Name:", user.name);
console.log("Email:", user.email);
console.groupEnd();

// ⏱️ console.time - วัดความเร็ว
console.time("calculation");
// ... โค้ดที่ต้องวัด
console.timeEnd("calculation");
```

### 💻 Debugging Best Practices

```javascript
// ดี - ใช้ descriptive messages
console.log("User data:", { id: user.id, name: user.name });

// ไม่ดี - ข้อความสั้นเกินไป
console.log("data:", data);

// ดี - แสดงเงื่อนไข
if (!user) {
  console.error("User not found:", userId);
}

// ดี - ตรวจสอบค่า
function processData(data) {
  console.assert(Array.isArray(data), "Data must be an array");
  // ... process
}
```

### 🔍 Try-Catch for Error Handling

```javascript
// 📝 จับ error ได้อย่างไร
async function fetchData() {
  try {
    const response = await fetch("/api/data");

    if (!response.ok) {
      console.error("HTTP Error:", response.status);
    }

    const data = await response.json();
    console.log("Data received:", data);
    return data;
  } catch (error) {
    console.error("Fetch error:", error.message);
    console.error("Stack:", error.stack);

    // Handle error
    return null;
  }
}
```

### 💡 Debugging Tips

```javascript
// 💡 Tip 1: ใช้ debugger statement
function calculateTotal(items) {
  debugger; // ⏸️ Code จะหยุดตรงนี้
  return items.reduce((sum, item) => sum + item.price, 0);
}

// 💡 Tip 2: ตรวจสอบ truthy/falsy
console.log(!!value); // แสดง true/false

// 💡 Tip 3: ตรวจสอบ type
console.log(typeof variable); // string, number, object, etc.

// 💡 Tip 4: ตรวจสอบ null/undefined
console.log(value ?? "default"); // nullish coalescing

// 💡 Tip 5: ตรวจสอบ error messages
try {
  riskyFunction();
} catch (error) {
  console.error("Error name:", error.name);
  console.error("Error message:", error.message);
  console.error("Error stack:", error.stack);
}
```

---

## 6. Browser DevTools Mastery

### 📖 คำอธิบาย

Browser DevTools ช่วยในการ:

- 🔍 Debug JavaScript
- 🎨 Inspect & edit CSS
- 📊 Monitor network
- 📈 Analyze performance
- 💾 Manage storage

### 🎯 Open DevTools

```
Windows: F12 or Ctrl + Shift + I
Mac: Cmd + Option + I
```

### 📋 Elements Tab (Inspector)

```
ฟีเจอร์:
Inspect elements - คลิกที่ element ดู HTML/CSS
Edit live - แก้ CSS ได้ทันที (ไม่บันทึก)
Computed styles - ดู CSS ที่ apply จริงๆ
Box model - ดู margin, padding, border
Event listeners - ดู event ที่ attach ไว้
```

**วิธีใช้:**

1. เปิด DevTools → Elements tab
2. คลิกไอคอน inspect (ซ้ายบน)
3. คลิก element ที่ต้องดู

### 📋 Console Tab

```javascript
// Execute JavaScript
const result = 5 + 3;
console.log(result); // 8

// Access variables
const user = { name: "Alice", age: 25 };
user.age = 26;

// Copy object
copy(user); // Copy to clipboard

// Clear console
clear();

// Get element
$("#myId"); // querySelectorAll('#myId')
$$(".myClass"); // querySelectorAll('.myClass')

// Get last result
$_; // ผลลัพธ์จากคำสั่งล่าสุด
```

### 📋 Network Tab

```
ฟีเจอร์:
Monitor requests - ดู HTTP requests ทั้งหมด
Response body - ดู response ของ API
Request headers - ดู headers ที่ส่งไป
Timing - ดูความเร็วของแต่ละ request
Filter - ค้นหา XHR, JS, CSS, Img, Media
```

**วิธีใช้:**

1. เปิด DevTools → Network tab
2. Reload page หรือทำ action
3. ดู requests ที่เกิดขึ้น
4. คลิก request ดู details

### 📋 Sources Tab (Debugger)

```
ฟีเจอร์:
Breakpoints - หยุด code ที่บรรทัดที่ต้องการ
Step through - ทำงาน step by step
Watch expressions - ดูค่าตัวแปร
Call stack - ดูสำหรับแล้วมาถึงจุดนี้
```

**วิธี set breakpoint:**

1. เปิด DevTools → Sources tab
2. เลือกไฟล์ JavaScript
3. คลิกบรรทัดที่ต้องหยุด
4. Click ขอบซ้ายจะปรากฏจุดแดง

### 📋 Application Tab (Storage)

```
ฟีเจอร์:
Local Storage - ดู key-value ที่เก็บ
Session Storage - ดู session data
Cookies - ดู cookies ทั้งหมด
IndexedDB - ดู database
Manifest - ดู PWA manifest
```

### 📋 Performance Tab

```
วิธี record:
1. เปิด DevTools → Performance tab
2. คลิก record (⚫)
3. Reload page หรือทำ action
4. คลิก stop
5. ดู flame chart

เฉพาะ:
- Blue = DOM
- Yellow = JavaScript
- Purple = Rendering
- Green = Painting
```

### 💡 Pro Tips

```javascript
// Tip 1: ใช้ console.time()
console.time("render");
renderPage();
console.timeEnd("render"); // แสดง เวลาที่ใช้

// Tip 2: ใช้ conditional breakpoints
// คลิก breakpoint → Edit condition
// เช่น: i === 100 (หยุดแค่เมื่อ i = 100)

// Tip 3: ใช้ logpoint
// คลิก breakpoint → Edit → Log message
// จะแสดง log โดยไม่หยุด code

// Tip 4: ใช้ DOM breakpoint
// Elements tab → right-click element
// → Break on → subtree modifications/attributes

// Tip 5: ใช้ Event listener breakpoint
// Sources tab → Event Listener Breakpoints
// เลือก event (click, input, scroll, etc.)
```

---

## 7. Performance Basics

### 📖 คำอธิบาย

Performance คือความเร็วของเว็บไซต์ ส่งผลต่อ:

- 👥 User experience - ผู้ใช้พอใจมากขึ้น
- 🔍 SEO - ปรากฏในผลการค้นหาดีขึ้น
- 💰 Conversion - ยอดขายเพิ่มขึ้น

### ⏱️ Core Web Vitals

```
Google ดูแล 3 metrics:

1️⃣ LCP (Largest Contentful Paint)
   - เมื่อไร content หลักปรากฏ?
   - เป้า: < 2.5 seconds

2️⃣ FID (First Input Delay)
   - Delay ระหว่าง user input กับ response
   - เป้า: < 100 milliseconds

3️⃣ CLS (Cumulative Layout Shift)
   - Elements เลื่อนไปมา?
   - เป้า: < 0.1
```

### 💻 Performance Tips

```javascript
// Tip 1: ใช้ async/await แล้ว handle ความเร็ว
async function loadData() {
  // Parallel loading
  const [users, posts] = await Promise.all([
    fetch("/api/users").then((r) => r.json()),
    fetch("/api/posts").then((r) => r.json()),
  ]);

  return { users, posts };
}

// Tip 2: ลดจำนวน DOM mutations
const fragment = document.createDocumentFragment();
items.forEach((item) => {
  const li = document.createElement("li");
  li.textContent = item;
  fragment.appendChild(li);
});
document.getElementById("list").appendChild(fragment);

// Tip 3: ใช้ debounce สำหรับ resize/scroll
function debounce(func, delay) {
  let timeoutId;
  return function (...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func(...args), delay);
  };
}

window.addEventListener(
  "resize",
  debounce(() => {
    console.log("Resized!");
  }, 300),
);

// Tip 4: ใช้ Intersection Observer สำหรับ lazy loading
const observer = new IntersectionObserver((entries) => {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      loadImage(entry.target);
      observer.unobserve(entry.target);
    }
  });
});

document.querySelectorAll("img[data-src]").forEach((img) => {
  observer.observe(img);
});

// Tip 5: ลด bundle size
// 🔹 Remove unused imports
// 🔹 Use tree shaking
// 🔹 Minify CSS/JS
// 🔹 Compress images
```

### 📊 Lighthouse Score

```
Lighthouse measure 5 metrics:

1. Performance (0-100)
   - ความเร็วของหน้า

2. Accessibility (0-100)
   - ใช้ได้ทั้งหมดหรือไม่

3. Best Practices (0-100)
   - ปฏิบัติตามมาตรฐาน

4. SEO (0-100)
   - ค้นหาได้ง่ายหรือไม่

5. PWA (0-100)
   - Progressive Web App

วิธี run Lighthouse:
1. DevTools → Lighthouse
2. เลือก device (Mobile/Desktop)
3. คลิก Analyze page load
```

### 💡 Image Optimization

```html
<!-- ดี - responsive images -->
<img
  src="image.jpg"
  srcset="image-small.jpg 480w, image-large.jpg 1024w"
  sizes="(max-width: 480px) 100vw, 50vw"
  alt="Description"
/>

<!-- ดี - lazy loading -->
<img src="image.jpg" alt="Description" loading="lazy" />

<!-- ดี - modern format -->
<picture>
  <source srcset="image.webp" type="image/webp" />
  <source srcset="image.jpg" type="image/jpeg" />
  <img src="image.jpg" alt="Description" />
</picture>
```

---

## 8. Local & Session Storage

### 📖 คำอธิบาย

**Storage** ช่วยเก็บข้อมูลใน browser ไม่ต้อง server

**ความแตกต่าง:**

```
┌─────────────────┬──────────────────┬──────────────┐
│    Feature      │  Local Storage   │   Session    │
├─────────────────┼──────────────────┼──────────────┤
│ Expiration      │ Never (forever)  │ Tab close    │
│ Size            │ ~5-10 MB         │ ~5-10 MB     │
│ Scope           │ Same origin      │ Tab only     │
│ Use case        │ Remember me      │ Temp data    │
└─────────────────┴──────────────────┴──────────────┘
```

### 💻 Local Storage Methods

```javascript
// 💾 Save data
localStorage.setItem(
  "user",
  JSON.stringify({
    id: 1,
    name: "Alice",
    email: "alice@example.com",
  }),
);

// 📖 Retrieve data
const userData = localStorage.getItem("user");
const user = JSON.parse(userData);
console.log(user.name); // Alice

// 📋 Get all keys
console.log(localStorage.key(0)); // key ที่ index 0
console.log(localStorage.length); // จำนวน items

// 🗑️ Remove specific data
localStorage.removeItem("user");

// 🧹 Clear all
localStorage.clear();
```

### 💻 Session Storage

```javascript
// 💾 Save session data
sessionStorage.setItem("authToken", "abc123xyz");

// 📖 Retrieve session data
const token = sessionStorage.getItem("authToken");
console.log(token); // abc123xyz

// 🗑️ Remove
sessionStorage.removeItem("authToken");

// 🧹 Clear all
sessionStorage.clear();
```

### 💻 ตัวอย่าง Practical

**Remember User Theme:**

```javascript
// 🎨 Save theme preference
function setTheme(theme) {
  localStorage.setItem("theme", theme);
  document.body.className = `theme-${theme}`;
}

// 🔄 Load saved theme on page load
function loadTheme() {
  const savedTheme = localStorage.getItem("theme") || "light";
  document.body.className = `theme-${savedTheme}`;
}

// ใช้
document.getElementById("darkModeBtn").addEventListener("click", () => {
  setTheme("dark");
});

loadTheme();
```

**Remember Login Info:**

```javascript
// 💾 Save login
function loginUser(email, password) {
  const userData = { email, loginTime: new Date() };
  localStorage.setItem("currentUser", JSON.stringify(userData));
  localStorage.setItem("authToken", generateToken());
}

// Check if logged in
function isLoggedIn() {
  return localStorage.getItem("authToken") !== null;
}

// 🚪 Logout
function logout() {
  localStorage.removeItem("currentUser");
  localStorage.removeItem("authToken");
}
```

**Save Form Data:**

```javascript
// 💾 Auto-save form
const form = document.getElementById("myForm");

form.addEventListener("input", () => {
  const formData = new FormData(form);
  const data = Object.fromEntries(formData);
  sessionStorage.setItem("formDraft", JSON.stringify(data));
});

// 📖 Restore form if still in session
window.addEventListener("load", () => {
  const draft = sessionStorage.getItem("formDraft");
  if (draft) {
    const data = JSON.parse(draft);
    Object.entries(data).forEach(([key, value]) => {
      const field = form.querySelector(`[name="${key}"]`);
      if (field) field.value = value;
    });
  }
});
```

### 🎯 Storage Best Practices

```javascript
// ดี - Wrapper functions
const storage = {
  set(key, value) {
    try {
      localStorage.setItem(key, JSON.stringify(value));
    } catch (error) {
      console.error("Storage full or unavailable", error);
    }
  },

  get(key) {
    try {
      const item = localStorage.getItem(key);
      return item ? JSON.parse(item) : null;
    } catch (error) {
      console.error("Storage error", error);
      return null;
    }
  },

  remove(key) {
    localStorage.removeItem(key);
  },
};

// ใช้
storage.set("user", { name: "Alice" });
const user = storage.get("user");
storage.remove("user");
```

---

## 9. Git & GitHub Basics for Frontend

### 📖 คำอธิบาย

**Git** - Tool สำหรับจัดการเวอร์ชั่นโค้ด
**GitHub** - Platform สำหรับจัดเก็บและแชร์โค้ด

### 🎯 Setup Git

```bash
# 🔧 ตั้งค่า user
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# ตรวจสอบตั้งค่า
git config --list
```

### 📚 Basic Workflow

```bash
# 1️⃣ Clone repository
git clone https://github.com/username/repo.git

# 2️⃣ Check status
git status

# 3️⃣ Stage changes
git add .
git add src/  # เลือกเฉพาะ folder

# 4️⃣ Commit
git commit -m "Add new feature"

# 5️⃣ Push to GitHub
git push origin main

# 6️⃣ Pull latest changes
git pull origin main
```

### 🌿 Branches

```bash
# 📋 ดู branches
git branch
git branch -a  # รวม remote

# ✨ สร้าง branch ใหม่
git branch feature/new-feature
git checkout feature/new-feature

# ⚡ Shortcut - สร้างและ checkout
git checkout -b feature/new-feature

# 🔄 Switch branch
git checkout main
git switch main

# 🗑️ ลบ branch
git branch -d feature/new-feature

# 🔀 Merge branch
git checkout main
git merge feature/new-feature
```

### 📝 Commit Best Practices

```bash
# ดี - descriptive messages
git commit -m "Add user authentication module"
git commit -m "Fix: resolve mobile layout issues"
git commit -m "Refactor: simplify API request logic"

# ไม่ดี - vague messages
git commit -m "update"
git commit -m "fix"
git commit -m "changes"

# ดี - interactive staging
git add -p  # choose which parts to stage

# ดี - amend last commit
git commit --amend --no-edit
```

### 🔄 Common Scenarios

**1️⃣ Undo Changes**

```bash
# ดู history
git log --oneline

# Undo uncommitted changes
git checkout -- src/main.js

# Undo last commit (keep changes)
git reset --soft HEAD~1

# Undo last commit (discard changes)
git reset --hard HEAD~1
```

**2️⃣ Resolve Conflicts**

```bash
# หา conflict
git status

# แก้ไข manually แล้ว
git add .
git commit -m "Resolve merge conflict"
```

**3️⃣ Stash Changes**

```bash
# ซ่อน changes ชั่วคราว
git stash

# ย้ายไปอีก branch
git checkout feature/other

# กลับมา และนำค่า stash กลับ
git checkout feature/original
git stash pop
```

### 🐙 GitHub Basics

**สร้าง Repository:**

1. ไปที่ github.com
2. คลิก + → New repository
3. ใส่ชื่อและ description
4. เลือก Public/Private
5. Initialize with README (optional)
6. Create repository

**Clone:**

```bash
git clone https://github.com/username/repo.git
cd repo
```

**Push Changes:**

```bash
# 1. Make changes locally
# 2. Stage and commit
git add .
git commit -m "description"

# 3. Push to GitHub
git push origin main
```

**Pull Requests (PR):**

```bash
# 1. Create branch
git checkout -b feature/new-feature

# 2. Make changes
# 3. Push branch
git push origin feature/new-feature

# 4. Go to GitHub → Create Pull Request
# 5. Add description and reviewers
# 6. Wait for approval
# 7. Merge when ready
```

### 📋 .gitignore File

```
# 📄 .gitignore - ไฟล์ไหนที่ไม่ push

# Dependencies
node_modules/
.npm

# Environment
.env
.env.local

# Build output
dist/
build/
*.bundle.js

# IDE
.vscode/
.idea/
*.swp

# OS
.DS_Store
Thumbs.db

# Logs
*.log
npm-debug.log*
```

### 💡 Pro Tips

```bash
# Tip 1: Use meaningful branch names
git checkout -b feature/add-dark-mode
git checkout -b fix/button-alignment
git checkout -b docs/update-readme

# Tip 2: View changes before commit
git diff              # unstaged changes
git diff --staged     # staged changes

# Tip 3: View commit history
git log --oneline            # short view
git log --graph --all        # visual tree
git show <commit-hash>       # view specific commit

# Tip 4: Search commits
git log --grep="bug"         # search in messages
git log -S "variable name"   # search in code

# Tip 5: Use aliases for common commands
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
```

---

## 📚 Summary (สรุป)

```
🎯 Modern JavaScript Skills:

1. ES Modules - แยกโค้ดด้วย import/export
2. Bundlers - Vite สำหรับความเร็ว, Webpack สำหรับความยืดหยุ่น
3. NPM - จัดการ packages และ dependencies
4. Organization - Structure โค้ดให้เป็นระเบียบ
5. Debugging - หาและแก้บั้กได้อย่างมีประสิทธิภาพ
6. DevTools - ใช้ browser tools อย่างเชี่ยวชาญ
7. Performance - ทำให้เว็บไซต์เร็วขึ้น
8. Storage - เก็บข้อมูลใน browser
9. Git - ควบคุมเวอร์ชั่นและแชร์โค้ด
```

---

## 🎓 Practice Exercises

### 1️⃣ ES Modules

- [ ] สร้าง module สำหรับ utility functions
- [ ] Import modules หลาย files
- [ ] ใช้ default export และ named export

### 2️⃣ Vite Setup

- [ ] สร้าง Vite project
- [ ] Configure vite.config.js
- [ ] Run dev server

### 3️⃣ NPM Project

- [ ] สร้าง package.json
- [ ] ติดตั้ง packages
- [ ] เขียน npm scripts

### 4️⃣ Code Organization

- [ ] Organize files into folders
- [ ] Create utility modules
- [ ] Create components

### 5️⃣ Debugging

- [ ] ใช้ console methods
- [ ] Set breakpoints
- [ ] Use DevTools

### 6️⃣ Storage

- [ ] Save data to localStorage
- [ ] Retrieve and parse data
- [ ] Create storage wrapper

### 7️⃣ Git Workflow

- [ ] Create local repository
- [ ] Create branch
- [ ] Commit and push changes
- [ ] Create pull request

---
