prettier
安裝 prettier(方式一)
首先,輸入以下指令來安裝 husky, lint-staged 和 prettier
npm install --save husky lint-staged prettier
安裝好後,在 package.json 的任意位置加上這段:
husky 也是一個套件,lint-staged 也是一個套件
我在 commit 之前(pre-commit),我要執行 lint-staged
在執行 lint-staged 時,針對符合 src/**/*.{js,jsx,ts,tsx,json,css,scss,md} 這些規則的檔案,我要跑 prettier --write(針對要 commit 的這些檔案執行 prettier --write)
因為我不希望每次 commit 都對所有檔案做 prettier,如果是已經 commit 過的檔案,就不需要再對它執行 prettier 了(已經 prettier 好了)
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"src/*.{js,jsx,ts,tsx,json,css,scss,md}": [
"prettier --write"
]
},
注意,在文件上寫的規則是 "src/**/*.{js,jsx,ts,tsx,json,css,scss,md}",這樣會是「src 底下的子資料夾底下的檔案」
但是,在我的專案中,App.js 這些檔案就直接是在「src 底下」,所以規則要改成 "src/*.{js,jsx,ts,tsx,json,css,scss,md}"

這樣,在每次 commit 時,就會幫我用 prettier 做 code formatting 了
安裝 prettier(方式二)
第二種方式是用 vs code 的 plugin 來安裝 prettier
在 Extensions 搜尋 Prettier - Code formatter
Format On Save
安裝好之後,我可以設定在存檔時跑 prettier
設定方式:
在 vs code 的 Settings 搜尋「Format On Save」,把「Format On Save」選項打勾
接著,在 Settings 搜尋「Default Formatter」> 選擇 esbenp.prettier-vscode
這樣,在每次存檔時,就會幫我用 prettier 做 code formatting 了
可參考 Format on Save (prettier) stopped working with latest update
JSX 特性
JSX 會自動幫我處理好 XSS 的問題(會自動幫我做 escape)
也就是說,我在欄位輸入 <h1>hello</h1> 按下新增,JSX 會用純文字顯示出來,而不會是 h1 的標籤
如果我真的就是要輸出 HTML 的標籤,就要啟用 dangerouslySetInnerHTML 這個功能
文件可參考 dangerouslySetInnerHTML
把 <TodoContent> 改成:
在 dangerouslySetInnerHTML={} 裡面傳入一個物件,物件裡面在 __html: 後面放我要 render 出來的內容 todo.content
return (
<TodoItemWrapper className={className} data-todo-id={todo.id}>
<TodoContent
$isFinished={todo.isFinished}
size={size}
dangerouslySetInnerHTML={{
__html: todo.content,
}}
></TodoContent>
這樣就可以輸出 HTML 標籤了(我在欄位輸入的內容,會真的變成 innerHTML)
但要特別注意的是:React 內建無法防範在 <a></a> 的 click-based XSS
無論是否在寫 React,都要注意 click-based 的 XSS 的問題
例如:
我 render 出一個 a 連結 <a href={todo.content}>click me!</a>
todo.content 就是我在欄位輸入的內容
return (
<TodoItemWrapper className={className} data-todo-id={todo.id}>
<TodoContent $isFinished={todo.isFinished} size={size}>
{todo.content}
</TodoContent>
<a href={todo.content}>click me!</a>
然後,如果我在欄位輸入 javascript: alert('haha') 按下新增,當我點擊「click me!」這個 a 連結時,就會執行 javascript: alert(‘haha’) 這行 JavaScript(跳出 haha 的 alert)

「click-based 的 XSS」運用的特性就是:
在 a 連結的 href="" 裡面,如果用「javascript: 」就可以在點擊時執行 JavaScript 的程式碼
之所以 React 無法防範這個 click-based 的 XSS 是因為:
React 內建的防範只會幫我做 escape,只會跳脫 <, >, '', "" 這些特殊符號,並不會把冒號 : 做跳脫
用 window.encodeURIComponent() 來修正 click-based 的 XSS
用 window.encodeURIComponent() 把 todo.content 做編碼
<a href={window.encodeURIComponent(todo.content)}>click me!</a>
這樣,如果我輸入 javascript: alert(‘yo’) 按下新增,當我點擊「click me!」這個 a 連結時,javascript: alert(‘yo’) 會被編碼為 javascript%3A%20alert(‘yo’)
(會把冒號 : 做編碼)
因此,網頁會導向到 http://localhost:3000/javascript%3A%20alert(%E2%80%98yo%E2%80%99) ,但是並不會跳出 alert

![[MTR04] W0 D2 心態培養](https://static.coderbridge.com/images/covers/default-post-cover-2.jpg)
