---
title: NodeJS Workshop for MFEE20 (1)
tags: iii-mfee20
description: NodeJS Workshop for iii MFEE20
version: 20210919
---
# NodeJS Workshop for MFEE20 (1)
Ashley (小賴)
ashleylai58@gmail.com
共筆:
- [Git Workshop for MFEE20](https://hackmd.io/@ashleylai/S1SJk5pMt)
- [NodeJS 共筆(1)](https://hackmd.io/@ashleylai/S1p51vEmt)
- [NodeJS 共筆(2)](https://hackmd.io/@ashleylai/H1mvcZtUt)
- [上課範例 (Github)](https://github.com/azole/hello-node)
上課錄影檔: https://drive.google.com/drive/folders/1-bh6JHVJ0551ncXl6nbH4_WUb0C_uMbV?usp=sharing
作業繳交: https://docs.google.com/spreadsheets/d/1L9uniJq0n9u-PGADwk6IxV-oj92cwucqFZDwiBL-wWc/edit?usp=sharing
已經上線的同學可以寫一下測驗
- 9/26 測驗 https://forms.gle/vmnK9onhmi2aEeA16
- 9:20
另外,關於觀影心得,在 hello-git repo 有以 issue 的方式回覆,
同學可以去看過,看過後可以回覆或是關掉那個 issue。
---
# NodeJS
NodeJS 是什麼?
- 框架?
- JS架構下的開發工具?
以下三個是前端
- 動畫?
- 寫網頁功能?
- 互動?
NodeJS 一般來說:可以用 javascript 寫後端程式
到目前為止,你們寫的 JS 在哪裡被執行? --> 瀏覽器
瀏覽器可以執行 JS 是因為它內建了 JS 的執行環境
==> NodeJS 讓你在瀏覽器以外執行 JS 的環境
JS 有兩種執行環境:
- 瀏覽器
- NodeJS
NodeJS 是一個程式語言? 不是! Javascript 才是程式語言
NodeJS 是框架嗎? 不是!
![](https://i.imgur.com/JcXqMC2.png)
window.location ==> window object
document.getElementById => html
==> 瀏覽器提供
## 安裝方法
- 直接安裝 nodejs
LTS: long-term support 長期維護版
- Current: 最新的、目前的
- Active LTS: 正在積極維護跟升級中的版本
- Maintenance LTS: 維護中的 LTS 直到生命週期結尾
- EOL: end of life
- nvm: node version manager
「安裝路徑不可以出現中文字」
- mac:
https://github.com/nvm-sh/nvm#install--update-script
- windows:
https://github.com/coreybutler/nvm-windows/releases
```bash=
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
# 確認自己用的 shell 是哪一種後,修改相對應的設定檔
$ echo $0
# 根據 echo $0 的結果,下方選擇一個來確認
$ cat ~/.zshrc
$ cat ~/.bashrc
# 關掉 terminal 重新啟動
$ nvm -v
```
windows
nod nodespus
nvm-setup.zip
```bash=
# 列出可以安裝的版本
$ nvm ls-remote 14
# windows版本
$ nvm list available
# 安裝最新的 LTS
$ nvm install 14.17.6
# 切換版本
$ nvm use 14.17.6
# 確認目前 node 的版本
$ node -v
# 列出你電腦裡 node 的版本
$ nvm ls
# windows 用 list
$ nvm list
# 設定預設版本
$ nvm alias default 14.17.6
```
## 寫第一個 nodejs 程式
1. 在 github 上建立一個 hello-node 專案,勾選建立 readme
2. 找到自己這個專案的 url,在 home 目錄下 clone 這個專案
```bash=
$ cd ~
$ git clone <url>
```
3. 用 vscode 開啟這個專案,在專案內建立 practice 檔案夾
4. 在 practice 內建立 sum.js
```javascript=
console.log("hello world!");
function sum(param) {
// TODO: 請從 1 + 2 + 3 + .... + param
}
console.log(sum(3)); // 6
console.log(sum(6)); // 21
console.log(sum(10)); // 55
```
5. 測試結果
```bash=
$ cd practice
$ node sum.js
# 如果不切換
$ node practice/sum.js
```
6. 測試OK,請 push 到 github,在 excel 打勾
期限: 16:45
==9/19==
作業
- 完成 sum.js 並且推上 github -> 如果有 issue 要解
- 觀看影片 https://www.youtube.com/watch?v=DgbSc6Ys710
- 在 hello-git 建立一個 video.md 的檔案
- 在這個檔案紀錄心得/筆記
- 學習對的學習方式,事半功倍
- 這兩天上課的筆記/心得
- hello-git 的 readme.md
- 複習 javascript
- map, filter, indexOf, join, map, pop, push, reduce, slice, splice, sort 這幾個函式暸解一下
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Array
- 箭頭函式
星期五晚上 9:00 以前
mac --> Homebrew
ubuntu --> apt
centOS --> yum
windows --> [winget](https://zh.wikipedia.org/wiki/Windows%E7%A8%8B%E5%BA%8F%E5%8C%85%E7%AE%A1%E7%90%86%E5%99%A8)
資料結構 & 演算法
- 資料結構 Data Structure (DS)
資料怎麼儲存、怎麼存取、之間的關係的時候
例如: array
- 演算法 Algorithm (algo)
怎麼「有效率」解決一個題目
- 時間複雜度: 通常會希望愈快愈好
- 空間複雜度: 通常會希望用盡量少的記憶體
「用空間換取時間」
練習平台: leetcode (刷題)
梯形公式
從 1 加到 100000,重複 10000 次
SUM1: 2.289ms
從 1 加到 100,重複 10000 次
SUM1: 20.609ms
==> 在 n 很大的情況下,表現會比較好
for 迴圈的做法:
從 1 加到 100000,重複 10000 次
SUM2: 1.278s
SUM2: 4.675ms
==> 在 n 比較小的情況下,表現會比較好
- 梯形公式是 O(1) 的寫法,for-loop 是 O(n) 的寫法, O(n) 時間複雜度比較高。
- 時間複雜度跟真正的執行時間,不是一定符合的
- 時間複雜度的討論通常在 n 比較大的情況下
- 寫程式之前想一下
- 當你學會用鐵鎚的時候,你會覺得全世界都是釘子
------
NodeJS
> node sum.js
Ryan: web 伺服器方面的問題,研究過 apache, C, Lua, Haskell 或是 Ruby
瀏覽器大戰
netscape 瀏覽器 X
Microsoft windows, IE 6 獨佔
--> firefox
--> Chrome javascript 執行引擎 V8 --> 非常有效率的 JS 引擎
node 使用 chrome V8 來當作核心
- Chrome V8
- firefox SpiderMonkey
- Safari: Nitro
- Edge: Chakra --> V8
# JS 語言的特性
- 單執行緒: 啟動一個 process 而且裡面只有一個 thread 在執行你的程式
PHP 有處理過多執行緒?
-> multiple processes
```sequence
client->php process 1: req
```
```sequence
client->php process 2: req
```
NodeJS: 一個 process / single-thread
-n 10000 -c 1000
Requests per second: 2862.02 [#/sec] (mean)誤差不大
Time per request: 349.403 [ms] (mean)
-n 100000 -c 1000
Requests per second: 2993.87 [#/sec] (mean)
Time per request: 334.016 [ms] (mean)
-n 300000 -c 1000 大壓力
Requests per second: 3582.09 [#/sec] (mean)很快
Time per request: 279.167 [ms] (mean)
PHP: 瘋狂開公司(很多 processes)
-n 10000 -c 1000 在一萬個請求跑的數據是這樣
Requests per second: 2242.04 [#/sec] (mean)誤差不大
Time per request: 446.023 [ms] (mean)
-n 100000 -c 1000在十萬個請求跑的數據是這樣
Requests per second: 2893.70 [#/sec] (mean)
Time per request: 345.578 [ms] (mean)
-n 300000 -c 1000大壓力
Failed requests: 58
Requests per second: 2100.17 [#/sec] (mean)很慢
Time per request: 476.152 [ms] (mean)
NodeJS vs PHP
- php 會有很多個 processes
- 善用多核心
- context switching 很高
- swoole (PHP的框架)
- NodeJS single-thread
- 只有用到一個核心 (比較無法善用多核心的硬體能力)
- 小壓力的情況下,其實兩者差不了太多
- 大壓力: php 通常比較有可能掛掉
**所謂的效能比較,不同的情境之下,結果可能截然不同**
NodeJS 是 single-thread,他為什麼可以服務這麼多請求,而且還沒有比較慢?
- 非阻塞
- 非同步IO
- 事件循環
![](https://i.imgur.com/8gKhy7d.png)
資料結構 Stack: 先進後出 (後進先出)
First In Last Out (FILO)
Last In First Out (LIFO)
放任務放進 stack ==> push
把任務從 stack 拿出來 ==> pop
javascript array function
- push 從尾端放東西
- pop 從尾端拿東西
php
- array_push
- array_pop
資料結構 Queue 佇列 先進先出
First In First Out (FIFO)
生產者消費者模式
生產者 --> buffer --> 消費者
(queue)
call stack
![](https://i.imgur.com/CDkxhLn.png)
![](https://i.imgur.com/10XuJdB.png)
==9/26==
- 複習 OS: process, thread, context switching, race condition, 生產者/消費者模式
- 資料結構: stack, queue
- event loop: https://www.youtube.com/watch?v=8aGhZQkoFbQ
## OS 補充
作業系統 Operation System (OS)
編譯式: 要事先經過「編譯」 compile -> 把程式碼轉換成機器看得懂的語言
直譯式: 在執行的當下才去做轉換
```
硬碟 記憶體 CPU裡的register
大 <----------> 小
便宜 貴
慢 快
```
![](https://i.imgur.com/azCAxXO.png)
I/O: input/output
- 硬碟存取(開檔、讀檔)
- 網路存取
I/O 相較於 CPU 運算是非常花時間
排程 scheduling: 怎麼安排 process?什麼時候可以輪到使用 CPU?
Starvation: process 長期無法獲得執行的資源
Context Switching:
祐愷: CPU
弈劭: process
傳駿: process
在 CPU 控制權切換的時候,必須保存目前執行中 Process 的狀態
載入欲執行 Process 的狀態資訊
==> 這些狀態的讀寫之間是有成本
Process --> 公司
thread --> 是公司內的工人
因為是同一間公司,所以可以共用很多資料
四個 processes
一份報告需要處理1分鐘
如果只有一個 process,請問總要處理多久? 100min
如果有四個 process: 總共約需要 25 分鐘
P0: 1~25 份報告
P1: 26~50 份報告
P2: 51~75 份報告
p3: 76-100 份報告
一個 process 然後裡面建立了 4 個 threads
每一個 thread 都處理 1/4 的工作量 ==> 總共約需要 25 分鐘
用 4 個 thread 的方式會比用 4 個 processes 更省時間
multithreading programming ((C#, Java, C++)
公司老闆
A 先請一個人就好,等有新的工作再來招募人
- 省錢
- 會比較慢
B 先請 10 個人,有工作來就讓這 10 個人去做,如果同時間超過 10 個工作,那就再找人。
- 花錢
- 比較有效率
Race Condition: 在Share Memory 溝通方式下, 共享變數的值會因為
Processes/threads 執行的順序不同而 有所不同。
- 考卷: https://forms.gle/TbtE8fznCnv2QZnx7
# XMLHttpRequst
https://developer.mozilla.org/zh-TW/docs/Web/API/XMLHttpRequest
是一個物件
XML Http Request
- axios https://github.com/axios/axios/blob/master/lib/adapters/xhr.js
- jquery AJAX https://github.com/jquery/jquery/blob/a684e6ba836f7c553968d7d026ed7941e1a612d8/src/ajax/xhr.js#L6
XMLHttpRequest vs Fetch
金融業、航空業
```xml=
<user>
<name>Ashley</name>
<phone>0987654321</phone>
<address>台北市XXXXXXX</address>
</user>
```
==> 86 個字元
```json=
{
name: "Ashley",
phone: "0987654321",
address: "台北市XXXXXXX"
}
```
==> 58 個字元 ==> 用 json 格式比較節省流量 ==> 傳輸就會比較快
IPv4
IPv6
domain name server (DNS)
www.pchome.com.tw <---> 210.59.230.39
255.255.255.255
255x255x255x255
作業系統、資料結構、演算法
網路概論、網路XXX
member: ashleylai / xxxxx
--> 驗證之後,帳號密碼都正確
- authentication 驗證 ==> 登入 驗證你是不是某個人 ==> 401
- authorization 授權 ==> 你是不是管理員?你是不是 VIP?... ==> 403
- audit 稽核(後台)
## NodeJS/JS 的特性
- JS 單執行緒
- 非阻塞 (non-block)
- 非同步IO
- 事件循環 event loop (stack, queue)
```java=
JS 單執行緒(一人公司)
--> non-blocking(不阻塞)
--> 非同步
--> web api / nodejs API (外包給別人)
--> event loop & task queue
--> callback
--> callback hell
--> promise
```
```javascript=
setTimeout(() => {
console.log("settimeout")
}, 0);
```
==10/3==
作業
1. ES6 常用語法 https://gretema.github.io/javascript/20200504/221423942/
2. 理解 callback hell --> 解決方法 promise (--> async/await)
- 玩弄一下 promise 範例
- 參考資料
- https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Promise
- https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Guide/Using_promises
4. (optional) 網頁的背景會定時換顏色
- 每三秒換一個底色
- 總共有 7 種顏色
- 可以寫 callback 版本
- 可以寫 promise 版本
# 10/16
物件導向 vs functional language
1. PHP, C#, JAVA, C++, ...
class 類別 --- new ---> 物件(object) / 實例 (instance)
強型別
```csharp=
class Member {
String name;
String email;
Int age; // 4 bytes
Member() // 建構式
function void setName(String newName) {
this.name = newName;
}
}
```
let m1 = new Member();
// new 幫你要跟作業系統要一塊記憶體空間
// 這塊空間多大呢? 就是 Member 這麼大
m1.setName("AAA");
let m2 = new Member();
m2.setName("BBB");
2. JavaScript: 原型式 prototype
建構式 (也只是一個 function)
new 建構式([預設值]) --> 做出一個新的物件
new 跟作業系統要一塊記憶體的空間別
new Promise(執行者)
執行者也只是一個函式,會要求傳入兩個參數: (resolve, reject)
```javascript=
new Promise((resolve, reject) => {
// 通常這裡我們放一些非同步的工作
// 非同步工作原本可能是用 callback 來交還控制權(交還給單執行緒)
// 如果成功,就會呼叫 resolve
// 如果失敗,就會呼叫 reject
})
```
## readfile
// 1. new Promise
// 2. 製作執行函式
// 3. 把非同步函式放進去
// 4.1 成功的地方,呼叫 resolve 把資料傳出來
// 4.2 失敗的地方,呼叫 reject 把錯誤傳出來
```javascript=
const fs = require("fs");
readFile('input.txt', (err, data) => {
if (err) {
console.error("發生錯誤", err);
} else {
console.log("正確讀到", data);
}
});
```
改寫成 promise 版本,還要使用它
# Await / Async
以下都不是正式的程式碼,只是示意
```php=
doWork("刷牙");
sleep(3);
doWork("吃早餐");
sleep(5);
doWork("寫功課");
sleep(3);
```
callback hell
```javascript=
doWork("刷牙", (err, data) => {
doWork("吃早餐", (err, data) => {
doWork("寫功課", (err, data) => {
// .....
});
});
})
```
```javascript=
doWork("刷牙")
.then((data) => {
return new Pormise("吃早餐")
})
.then((data) => {
return new Pormise("寫功課")
})
.then((data) => {
// ....
})
```
```javascript=
doWork("刷牙");
doWork("吃早餐");
doWork("寫功課");
```
長得很像同步程式
await: 不是阻塞,他是「暫停」,他就有暫停的「範圍」
- 解除暫停? promise 裡的非同步工作完成時,呼叫 resolve 的時候會解除暫停,而且可以把結果傳出來
async: 告知「暫停的範圍」
```javascript=
async function main() {
let data1 = await doWork("刷牙");
let data2 = await doWork("吃早餐");
let data3 = await doWork("寫功課");
}
```
Q. 錯誤處理?
A: 只能自己用 try-catch 處理
```javascript=
try {
// 1
// 2 -> 發生錯誤
// 3
// 4
} catch {
} finally {
// 不管有沒有錯誤,都會執行到的地方
}
```
# module
ESM (ES Module)
```javascript=
import React from "react";
```
NodeJS 實作了 CJS (Common JS)
CJS 可以寫在前端嗎? 瀏覽器是不認得的
webpack -> 幫忙把 CJS 的寫法轉成瀏覽器認得的方式 (編譯)
```javascript=
const fs = require("fs");
fs.readFile(...);
const { readFile } = require("fs");
readFile(...);
```
```javascript=
// module.exports = exports = {};
module.exports = {getBrand, price...}
// return module.exports
```
module: 共用、封裝不想要透露的資料或者是功能
** 注意 module.exports 跟 exports 共用記憶體的陷阱 **
三個 package 的來源:
- nodejs 內建給我們用: fs
- 我們自己開發的: car, adder
- 別人開發: 怎麼使用呢?
nvm: node version manager
npm: node package manager/management
npm、yarn 都是 nodejs 的套件管理系統
```bash=
# 初始化一個專案,建立一個 package.json
npm init
# 安裝套件
npm install xxxx
npm i xxxx
# 移除 xxxx 套件
npm uninstall xxxx
# 根據 package.json 來安裝套件
npm install
# 查看 cowsay 總共有多少個版本
npm view cowsay versions
# 檢查哪些套件是過期的
npm outdated
# 查看專案裡裝了哪些套件跟他們的相依關係
npm list
```
package.json => 紀錄很多專案資料,紀錄 dependencies
下一次,只需要執行 npm install (不需要給套件名稱)
npm 會去讀這個檔案夾底下的 package.json 幫你安裝相依的套件
- 這些相依的套件也會有自己的需要的相依套件
- 會一層一層裝下去
- 安裝的套件會裝去 node_modules 檔案夾裏面
Q. package.json 需要放進 github repo?
A. YES
Q. 如果你在 git pull 的時候,發現 package.json 檔案有異動,你應該要做什麼事?
A. 要去執行 `npm install` 把 package.json 裡的異動處理一下(可能是安裝新的套件或是移除某些套件)
Q. node_modules 要不要放進 github repo 裡?
A. 大部分是不用,只要有 package.json 就好
semver: 主版本號.次版本號.patch版本
xx.xx.xx
1.2.3
2.0.1
主版本號: 不往前相容的更新(更新是比較大) --> 要做主版本號的更新,注意影響範圍、是否有足夠的時間修改、測試
次版本號: 可以向前相容的更新
patch號: 通常不會改變介面,通常就是修補 bug
~0.13.0: ~ 只會更新 patch 版本號
- 0.13.1 可以
- 0.14.0 不會更新
^: 不會更改最左邊、非零數字的更新
^1.2.3 最左邊非零是1
- 1.3.0 可以
- 1.2.4 可以
- 2.0.0 不可以
^0.2.3 最左邊非零是2
- 0.2.4 可以
- 0.3.0 不可以
1.2.3 就是指定使用 1.2.3
```json=
{
...
"dependencies": {
"cowsay": "^1.2.0"
}
}
```
==> 實際安裝下來會是 1.5.0 (最新的那個)
```json=
{
...
"dependencies": {
"cowsay": "~1.1.0"
}
}
```
==> 實際安裝下來會是 1.1.9 (最新的那個)
```bash=
npx create-react-app xxxx
```
無須安裝命令、就可以執行
==10/16==
1. promise
2. async/await
3. fs.readFile
- callback 版本
- 自己做了 promise 版本
4. CJS: module.exports (exports) ----> ESM
- 物件的記憶體
5. npm, npx
- package.json
- 利用 package.json 來管理相依套件
- 以 cowsay 為例做練習
npm 跟 yarn
https://polinwei.com/npm-vs-yarn/
在作法上跟 npm/yarn 完全不同
https://pnpm.io/
分析文章
https://zhuanlan.zhihu.com/p/377593512
-----
# 10/17
作業1:
- 建立一個 crawler 分支/切換到這個分支
- 建立 crawler 檔案夾
- hello-node/crawler
- 安裝 axios
- 實作 axios 的 get 去證交所拿資料(promise版)
- 請改成 await 版本
- push 到 github (crawler分支)
參考: https://github.com/azole/hello-node
```bash=
# 建立分支
git branch crawler
# 切換到 crawler 分支
git switch crawler
mkdir crawler
cd crawler
npm init
```
以下這個方式,只是從新的這個 commit 中移除而已
```bash=
# 會把 node_modules 整個刪掉,包括 git 中、也包括硬碟中
git rm -r node_modules
# 只會從 git 中刪除,不會刪掉硬碟的
git rm -r --cached node_modules
git commit -m "remove node_modules"
git push
```
利用 .gitignore 來設定不想放到 git repo 裡的檔案/檔案夾
Q. .gitignore 他自己本身要不要放進 git repo ?
A. 要放
參考哪些應該放在 .gitignore
https://www.toptal.com/developers/gitignore
關於 JS 的日期處理,可以考慮使用第三方套件
例如可以參考這類的文章來找有什麼可以用
https://openbase.com/categories/js/best-nodejs-date-libraries
爬蟲的進階:
- 日期改成動態取得當天的日期(要處理格式)
- 股票代碼紀錄在檔案中,透過讀檔案取得
- 股票代碼檔案可以有多個(可以參考 JS 的 string split 函式)
作業2:
在自己的資料庫建立好一個資料庫,並且在其中建立以下的資料表:
![](https://i.imgur.com/k2ZxSpD.png)
# 存取資料庫
https://www.npmjs.com/package/mysql
https://www.npmjs.com/package/mysql2
```bash=
npm i mysql
```
```javascript=
const mysql = require("mysql");
const connection = mysql.createConnection({
host: "localhost", // 本機 127.0.0.1
user: "???",
password: "???",
database: "???",
});
connection.connect();
connection.query(
"INSERT IGNORE INTO stock (stock_no, date, deal, amount, count) VALUES (?, ?, ?, ?, ?);",
[stockCode, firstItem[0], firstItem[1], firstItem[2], firstItem[8]],
(err, results) => {
if (err) {
console.error("發生錯誤", err);
} else {
console.log("db結果", results);
}
}
);
```
作業3: https://github.com/azole/hello-node/blob/crawler/crawler/app-db.js
改成 promise/await 版本
deadline: 3:40
***密碼等私密資料不可以傳到 github 上面去***
像是第三方服務給你設定的 secret
不能傳上去,但是要可以設定
利用 dotenv 這個套件來處理這些設定檔
https://www.npmjs.com/package/dotenv
```javascript=
require("dotenv").config();
// 利用 process.env.xxxx 來存取設定檔
const connection = mysql.createConnection({
host: process.env.DB_HOST, // 本機 127.0.0.1
port: process.env.DB_PORT, // 埠號 mysql 預設就是 3306
user: process.env.DB_USER,
password: process.env.DB_PWD,
database: process.env.DB_NAME,
});
```
製作一個 .env 檔案,裡面存著所有需要的設定
Q: .env 可以放到 github repo 去?
A: 當然不行,把 .env 放到 .gitignore
Q: 既然 .env 不可以放到 github repo 上去,協作者(同組的同學或同事)怎麼知道有哪些設定要做?
A: 建立一個檔案 .env.example,把 key 放到 .env.example 這個檔案來,
且會把 .env.example 放到 github repo 上去
==10/17==
作業
1. 爬蟲資料儲存到 mysql 的 await 做出來
2. 改成用 dotenv 來儲存私密資料
- .env.example
- 程式碼中不該出現任何密碼
3. 如何刪掉已經推上去的 commit?
4. 把 crawler 分支合併進去 main,但是不可以自己併
- 建立一個 pull request
- 找同學幫你 review
- 有沒有正確使用 dotenv
- 程式裡面是用 process.env.xxx 來設定的
- 有提供 .env.example
- 檢查程式碼是否正確
- axios 是否有用對
- 有沒有正確存到資料庫??
- 是不是用 promise/await
- 排版?
- 有沒有任何其他問題?
deadline: 10/27 (三) 晚上 12:00
-----
# 10/29
[bluebird](http://bluebirdjs.com/docs/api-reference.html) → 不是 promise 的東西包成 promise
```Bash=
$ npm i bluebird
# 覆蓋原生的 promise
const promise = require("bluebird")
```
-promisify (v.) → 把這個東西 promise 化
-connectAsync()
-promise.all() → 放好幾個 promise / 等到最後一個做完,再做下一件事
-promise.race() → 看誰第一個做完
- node.js 世界中的套件
1. 自己開發
2. 用第三方的
3. 用內建的
- Apache / Nginx → web server
- [nodemon](https://www.npmjs.com/package/nodemon) → 偵測檔案有無變動、自動重啟
- 只會改硬碟並不會讀進記憶體 → 除非重啟 node
- npm -g 裝在那個版本底下
- npm init -f 初始化且使用預設
別名:預設指令(保持彈性)
![link text](https://s3.us-west-2.amazonaws.com/secure.notion-static.com/2e262b8d-cefa-4087-93ba-86b6a19e4871/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAT73L2G45O3KS52Y5%2F20211029%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20211029T034122Z&X-Amz-Expires=86400&X-Amz-Signature=31b0775d9dbe44affb0baf52555fd7977cded8bd51b3802e073f783e4e1f64a8&X-Amz-SignedHeaders=host&response-content-disposition=filename%20%3D%22Untitled.png%22)
```Bash=
$ npm run dev
```
異地備份
![](https://s3.us-west-2.amazonaws.com/secure.notion-static.com/cec44fef-ae27-4b52-bb6d-c297232ebc86/Untitled.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAT73L2G45O3KS52Y5%2F20211029%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20211029T040636Z&X-Amz-Expires=86400&X-Amz-Signature=10573e6703f720f1f0e9e784bce7f140d584a862978856d87c51275cb348ee61&X-Amz-SignedHeaders=host&response-content-disposition=filename%20%3D%22Untitled.png%22)
- [SLA的系統妥善率](https://andersonwang.wordpress.com/2012/11/07/sla%E7%9A%84%E7%B3%BB%E7%B5%B1%E5%A6%A5%E5%96%84%E7%8E%87/)
-> 我要賣系統,我要如何告訴別人我的穩定度
# 補充資料
## Crash Course
- https://www.youtube.com/watch?v=tpIctyqH29Q&list=PL8dPuuaLjXtNlUrzyH5r6jN9ulIgZBpdo
https://crashcourse.club/category/
## ES6 常用語法
- https://gretema.github.io/javascript/20200504/221423942/
## JavaScript prototype
- https://byvoid.com/zht/blog/javascript-object-prototype/