🔍 搜尋結果:for

🔍 搜尋結果:for

JavaScript 系列六:第3課 ── 認識匿名函式

## 課程目標 能夠從陣列刪除元素 認識 for in 迴圈寫法 認識匿名函式(anonymous function) ## 課程內容 在 JavaScript 中,刪除陣列元素的方法,有超多種 這邊介紹一種根據索引刪除的方法 ``` var fruits = ["apple", "banana", "orange"]; var index = 1; var num = 1; fruits.splice(index, num) console.log(fruits) ``` `.splice()` 函式第一個傳索引,第二個傳要刪的數量,通常就傳 1 就好了(一次刪一個即可) 實務上,你就根據情況,隨便找一個能用的方式,來操作陣列就對了 --- 之前我們介紹過 for of 的寫法,很簡單好用 ``` var fruits = ["apple", "banana", "orange"]; for (const fruit of fruits) { console.log(fruit) } ``` 這邊多介紹一個 for in 的寫法,需要索引時可以用 ``` var fruits = ["apple", "banana", "orange"]; for (const index in fruits) { const fruit = fruits[index]; console.log(index); console.log(fruit); } ``` --- 最後來介紹匿名函式(anonymous function) 聽起來很玄,但其實就只是沒有名字的函式而已 以下是有名字的函式 ``` function hello1() { alert("hello1"); } var hello2 = () => { alert("hello2"); } ``` 以下是沒有名字的函式 ``` <button> hello </button> ``` ``` var button = document.querySelector('button'); button.onclick = () => { alert(123) }; ``` 動態宣告一個函式,然後直接指派、使用,就是匿名函式 在 JavaScript 中,很多時候,有些小任務,需要宣告新函式來用,但又懶得去設計命名那些的 這時候就可以用匿名函式來節省時間 雖然看起來有點不習慣、有點奇怪 但在實務上,非常多地方,其實都會用到匿名函式,算是 JavaScript 非常好用的一個功能、特性 ## 課後作業 接續上一課作業,這次來實作「刪除事項」 請更新 `render` 函式,讓 UI 看起來像這樣 ``` <ul> <li> <span>倒垃圾</span> <button>刪除</button> </li> <li> <span>繳電話費</span> <button>刪除</button> </li> <li> <span>採買本週食材</span> <button>刪除</button> </li> </ul> ``` 然後在過程中,動態產生 button 的時候,將 `.onclick` 屬性設定為一個 arrow function 這個 arrow function 不能直接更新 DOM,而是先去更新 data model,接著 render,用這種方式間接更新 DOM ``` deleteBtn.onclick = () => { // 請寫出此 arrow function 內容(更新 todos 陣列) render(); }; ``` --- 提示:由於 javascript 中 hoisting 的特性,for loop 拿到的索引,在裡面的 arrow function 中使用,很容易抓錯 關於索引一直拿不到的問題,請參閱這邊我跟 birdie 同學的討論 https://codelove.tw/@birdie2019/post/2anbka --- 做出以上功能,你就完成這次的課程目標了!

JavaScript 系列五:第4課 ── 學會 AJAX 基本原理

## 課程目標 認識基本的 AJAX 原理 ## 課程內容 這一課來認識大名鼎鼎的 AJAX 觀念 AJAX 全名 Asynchronous JavaScript and XML 簡單來說,就是「非同步從主機取得資料來更新網頁內容」的技術 舊式的網頁,都是瀏覽器向主機發送 HTTP 請求 -> 主機回應一大坨 html 內容 -> 瀏覽器顯示漂亮網頁給用戶看 因為是一次拿到一大坨 html 內容,我們說「網頁上全部內容都是同步取得」 現代的網頁,也是有很多頁面是這樣直接取得,但有更多功能,是依靠非同步取得資料之後來更新的 - 滑動到網頁下方,動態載入了更多貼文 - 對內容按讚,按讚成功網頁出現了小變化 - 聊天室與別人聊天,網頁也是一段一段文字更新 這些都是使用 AJAX 技術的例子 也就是先載入基本網頁內容,再接著根據需求,於不同時間點發送 HTTP 請求取得部份內容,所以叫做非同步 實務上,我們會說「這邊要發一個 AJAX 跟主機要資料」 --- 讓我們拿一個「模擬線上購物網站 API」來當作例子 https://fakestoreapi.com/ 發一個 AJAX 取得 ID 為 1 的用戶資料 ``` fetch('https://fakestoreapi.com/users/1') .then(res=>res.json()) .then(json=>console.log(json)) ``` 請在 jsfiddle 試試,看看結果 會看到一個包含信箱、ID、姓名、電話等等欄位的用戶個資,以物件的形式呈現 這邊使用了內建的 fetch 函式,參數放入要呼叫的 API 網址 接著使用 `.then()` 函式,由於是直接寫在後面,這相當於把 `fetch()` 回傳的東西,直接當成物件再接著呼叫 `.then()` 函式,然後再把結果當成物件再呼叫 `.then()` 一次 也就是跟這段一模一樣 ``` var result1 = fetch('https://fakestoreapi.com/users/1'); var result2 = result1.then(res=>res.json()); var result3 = result2.then(json=>console.log(json)); alert(result1) alert(result2) alert(result3) ``` 請在 jsfiddle 試試,會發現 console 顯示的個資一樣,這邊用三個 alert 觀察過程中的東西 會發現顯示三次 `[object Promise]`,這個 Promise 是一個進階觀念,這邊不細談,簡單講就是處理非同步請求的一種資料格式 `.then()` 參數傳進一個箭頭函式,這是省略大括號 `{}` 的箭頭函式寫法,其實就只是會自動回傳結果的函式寫法而已 但參數放了個函式,看起來有點怪,為何要這樣寫? --- 記得我們之前寫過的動態綁定 onclick 事件嗎? ``` <button id="my-btn">Click me</button> ``` ``` // 第一種寫法 function myFunction() { alert('你點擊了按鈕!'); } var btn = document.getElementById('my-btn'); btn.onclick = myFunction; ``` 網頁元素的事件處理,也是一種「非同步」程式設計 也就是我不確定「點擊」事件何時會發生,但我先「綁定」好事件發生時要做的任務,綁完就讓網頁正常呈現就好 上面的程式碼,可以改寫成這樣 ``` // 第二種寫法 var btn = document.getElementById('my-btn'); btn.onclick = () => { alert('你點擊了按鈕!'); } ``` 如果使用 jQuery,那還可以這樣改寫 ``` // 第三種寫法 $('#my-btn').click(() => { alert('你點擊了按鈕!'); }) ``` 第一種寫法,看起來像是:我先定義好函式,接著把函式名稱當作變數,綁定到 onclick 屬性 第二種寫法,看起來像是:onclick 這邊現場寫一個箭頭函式,把要執行的任務,當場交待清楚 第三種寫法,看起來像是:jQuery 提供的 `.click()` 函式,會負責把事件綁好,參數傳任務進去就對了 以上三種寫法,效果是完全一模一樣的! 所以你早就接觸過「非同步」程式設計了 也就是「有些任務現在還不會立刻執行,但我先把要執行的任務交待清楚,時間點到的時候,就執行」 以 UI 動作來說,時間點就是 `onclick` 之時、`onchange` 之時 以 AJAX 動作來說,時間點就是 `拿到主機回應` 之時 像這種不是馬上執行的動作,在 JavaScript 領域,我們習慣用「寫一段函式定義當作參數傳進去」來表達! --- 回頭看一下我們的範例 ``` fetch('https://fakestoreapi.com/users/1') .then(res=>res.json()) .then(json=>console.log(json)) ``` 因為 fetch 第一個回傳的結果,代表的是一個 `HTTP 回應物件`,這個回應物件的 HTTP body 是實際的 JSON 內容,可以用 `.json()` 函式取得內容 所以第二個 `.then()` 的參數,才是我們真正想做的事情 看不懂沒關係,我們多看幾個例子吧 取得全部用戶個資的 AJAX。觀察 console 結果,會看到一個陣列,內含大量個資物件 ``` fetch('https://fakestoreapi.com/users') .then(res=>res.json()) .then(json=>console.log(json)) ``` 取得五筆用戶個資,也是拿到陣列 ``` fetch('https://fakestoreapi.com/users?limit=5') .then(res=>res.json()) .then(json=>console.log(json)) ``` 以上內容,全部通通看不懂沒關係,畢竟,需要多了解一些 HTTP 協定與術語,比較好理解 你就先照做就好:要發 AJAX,就用 `fetch()` 函式,接著第一個 `then()` 要執行 `.json()` 函式,然後第二個函式才是你真正要執行的任務! ## 課後作業 請使用 https://jsfiddle.net/ 請使用「模擬線上購物網站 API」 https://fakestoreapi.com/ 假設正在開發一個讀取全部商品資料的頁面 用以下 html 為基礎 ``` <button>Load Products</button> <hr> <ul></ul> ``` 點擊按鈕,發送 AJAX 到 https://fakestoreapi.com/products 請求全部商品資料 拿到資料之後,將每筆資料用以下格式呈現,塞進 `<ul>` 元素裡面 ``` <li> <span>xxx</span> <button>Details</button> </li> ``` xxx 是商品名稱。點擊 Details 按鈕,連續跳出三個 alert,分別顯示 `id` `category` `description` --- 請注意,在 for 迴圈裡面綁定 onclick 事件的時候,for 迴圈的參數請加上 `const` 舉例來說,請這樣寫 ``` for (const product of json) { ``` 請「不要」這樣寫 ``` for (product of json) { ``` 否則,在迴圈裡面的 onclick 事件,執行起來會有 bug 原因跟上一課提到的 Hoisting 現象有關 我認為這是 JavaScript 的設計失敗,所以詳細原因我不想說明 這是屬於上個世代 JS 工程師的痛苦回憶,這一代的 JS 工程師不需要經歷 現在就用 ES6 語法,宣告變數一律記得加上 `const` 或 `let` 就對了 --- 做出以上功能,你就完成這次的課程目標了!

7 個好用的 React Hooks:可以在很多專案直接使用

Hooks 是 React 最強大的功能之一。 它們使我們能夠輕鬆地在應用程式的元件中重用功能。掛鉤的最大優點在於它們的可重用性——您可以跨元件和專案重用掛鉤。 以下是我在每個 React 專案中重複使用的七個最重要的鉤子。今天就試一試,看看它們在建置您自己的 React 應用程式時是否有幫助吧。 原文出處:https://dev.to/webdevhero-com/7-react-hooks-for-every-project-1jdo --- 在我們開始之前,要先澄清一下:並非每個自定義 React 鉤子都需要由您編寫。事實上,我將提到的所有鉤子都來自一個庫“@mantine/hooks”。 Mantine 是一個很棒的第三方庫,其中包含這些鉤子等等。他們將為您的 React 應用程式加入您能想到的幾乎所有重要功能。 您可以在 [mantine.dev](https://mantine.dev) 查看“@mantine/hooks”的文件。 ## `useIntersection` 鉤子 當用戶在您的應用程式中向下滾動頁面時,您可能想知道某個元素何時對他們可見。 例如,您可能希望僅在用戶看到特定元素時才啟動動畫。或者,您可能希望在他們向下滾動頁面一定程度後,顯示或隱藏元素。 ![use intersection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zilwvvdjppw9uz82iixo.gif) 要獲取有關元素是否可見的訊息,我們可以使用 **Intersection Observer API。**這是瀏覽器中內建的 JavaScript API。 我們可以使用純 JavaScript 單獨使用 API,但要知道有關特定元素是否在其滾動容器內,有個好方法是使用 useIntersection 掛鉤。 ``` import { useRef } from 'react'; import { useIntersection } from '@mantine/hooks'; function Demo() { const containerRef = useRef(); const { ref, entry } = useIntersection({ root: containerRef.current, threshold: 1, }); return ( <main ref={containerRef} style={{ overflowY: 'scroll', height: 300 }}> <div ref={ref}> <span> {entry?.isIntersecting ? 'Fully visible' : 'Obscured'} </span> </div> </main> ); } ``` 要使用它,我們需要做的就是在我們的元件中呼叫鉤子,並提供一個根元素。 Root 是滾動容器,可以使用 useRef 掛鉤將其作為 ref 提供。 `useIntersection` 回傳一個我們傳遞給目標元素的 ref,我們想要觀察其在滾動容器中的交集。 一旦我們有了對元素的引用,我們就可以追蹤元素是否相交。在上面的範例中,我們可以根據 entry.isIntersecting 的值查看元素何時被遮擋或何時完全可見。 您可以傳遞其他參數,這些參數允許您配置與目標可見百分比相關的**閾值**。 ## `useScrollLock` 鉤子 另一個與滾動相關的鉤子是 useScrollLock 鉤子。這個鉤子非常簡單:它使您能夠鎖定 body 元素上的任何滾動。 我發現當您想在當前頁面上顯示疊加層或跳出視窗,並且不想讓用戶在後台頁面上上下滾動時,它會很有幫助。這使您可以將注意力集中在視窗上,或允許在其自己的滾動容器內滾動。 ``` import { useScrollLock } from '@mantine/hooks'; import { Button, Group } from '@mantine/core'; import { IconLock, IconLockOpen } from '@tabler/icons'; function Demo() { const [scrollLocked, setScrollLocked] = useScrollLock(); return ( <Group position="center"> <Button onClick={() => setScrollLocked((c) => !c)} variant="outline" leftIcon={scrollLocked ? <IconLock size={16} /> : <IconLockOpen size={16} />} > {scrollLocked ? 'Unlock scroll' : 'Lock scroll'} </Button> </Group> ); } ``` `useScrollLock` 將用戶的滾動鎖定在頁面上的當前位置。該函數回傳一個陣列,它可以被解構,如上面的程式碼所示。 第二個值是一個允許我們鎖定滾動的函數。另一方面,第一個解構值是一個布林值,它告訴我們滾動條是否已被鎖定。 這個值很有用,例如,如果你想在滾動鎖定時顯示某些內容或告訴用戶它已被鎖定。您可以在下面的示例中看到,當滾動條被鎖定或解鎖時,我們會在我們的按鈕中進行指示。 ![use scroll lock](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wywccv7uexfrhfgayqj9.gif) ## `useClipboard` 鉤子 在許多情況下,您希望提供一個按鈕,允許用戶將內容複製到他們的剪貼板,這是存儲複製文本的地方。 一個很好的例子是,如果您的網站上有一個程式碼片段,並且您希望用戶輕鬆複製它。為此,我們可以使用另一個 Web API——**剪貼板 API**。 `@mantine/hooks` 為我們提供了一個方便的 `useClipboard` 鉤子,它回傳幾個屬性:`copied`,它是一個布林值,告訴我們是否已使用鉤子將值複製到剪貼板,以及` copy` 函數,我們可以將我們喜歡的任何字串值傳遞給它以進行複制。 在我們的範例中,我們想複製一個程式碼片段,供我們的用戶粘貼到他們喜歡的地方,如下面的影片所示: ![使用剪貼板](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6n0xd02vdg65bbfmb2xh.gif) ## useClipboard demo 當他們點擊我們指定的複制按鈕時,我們呼叫我們的 `copy` 函數,將程式碼片段傳遞給它,然後顯示一個小複選標記或向他們表明文本已被複製的東西。 巧妙的是 `useClipboard` 掛鉤帶有 **超時值**。在給定的超時時間(以毫秒為單位)之後,複製的狀態將被重置,向用戶顯示他們可以再次復製文本。 ## `useDebouncedValue` 鉤子 如果您的應用程式中有搜尋輸入,下一個鉤子“useDebouncedValue”是必不可少的。 每當用戶使用輸入執行搜尋時,搜尋操作通常涉及對 API 的 HTTP 請求。 您將遇到的一個典型問題是每次擊鍵都會執行查詢(請求),尤其是如果您希望用戶在鍵入時接收搜尋結果。即使對於一個簡單的搜尋查詢,也不需要在用戶完成輸入他們想要的內容之前執行這麼多請求。 這是 useDebounceValue 掛鉤的一個很好的用例,它對傳遞給它的文本應用「防抖」功能。 ``` import { useState } from 'react'; import { useDebouncedValue } from '@mantine/hooks'; import { getResults } from 'api'; function Demo() { const [value, setValue] = useState(''); const [results, setResults] = useState([]) const [debounced] = useDebouncedValue(value, 200); // wait time of 200 ms useEffect(() => { if (debounced) { handleGetResults() } async function handleGetResults() { const results = await getResults(debounced) setResults(results) } }, [debounced]) return ( <> <input label="Enter search query" value={value} style={{ flex: 1 }} onChange={(event) => setValue(event.currentTarget.value)} /> <ul>{results.map(result => <li>{result}</li>}</ul> </> ); } ``` 您使用 useState 將輸入的文本儲存在一個狀態中,並將狀態變數傳遞給 useDebouncedValue 。 作為該掛鉤的第二個參數,您可以提供一個等待時間,即值被「反抖」的時間段。反抖使我們能夠執行更少的查詢。 您可以在下面的影片中看到結果,用戶在其中鍵入內容,並且僅在 200 毫秒後,我們才能看到去抖值。 ![使用去抖值](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qfb5kqb6bxbkqfvog1hw.gif) ## `useMediaQuery` 鉤子 我一直使用的另一個非常有用的鉤子是 useMediaQuery 鉤子。 Media Queries 在純 CSS 中使用,`useMediaQuery` 鉤子允許我們訂閱我們傳遞給鉤子的任何媒體查詢。 例如,在我們的元件中,假設我們想要顯示一些文本或根據特定螢幕寬度(例如 900 像素)更改元件的樣式。我們像在 CSS 中一樣提供媒體查詢,並且 useMediaQuery 回傳給我們一個 true 或 false 的 matches 值。 ``` import { useMediaQuery } from '@mantine/hooks'; function Demo() { const matches = useMediaQuery('(min-width: 900px)'); return ( <div style={{ color: matches ? 'teal' : 'red' }}> {matches ? 'I am teal' : 'I am red'} </div> ); } ``` 它用 JavaScript 告訴我們媒體查詢的結果,這在我們想要使用 `style` 屬性在 JSX 中直接更改樣式時特別有用,例如。 ![使用媒體查詢](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7al1apywiq08ntgs4d8l.gif) 簡而言之,對於少數無法使用 CSS 處理媒體查詢的情況,這是一個必不可少的鉤子。 ## `useClickOutside` 鉤子 下一個掛鉤 - `useClickOutside` - 可能看起來很奇怪,但當您真正需要它時,您會發現它的重要性。 當你開發一個下拉菜單,或者在頁面內容前面彈出,並且之後需要關閉的東西時,這個鉤子是必不可少的。通過單擊按鈕打開這些類型的元件之一非常容易。關閉這些元件有點困難。 為了遵循良好的 UX 實踐,我們希望任何阻礙用戶視圖的東西都可以通過單擊元素外部輕鬆關閉。這正是 useClickOutside 掛鉤讓我們做的。 當我們呼叫 useClickOutside 時,它會返回一個 ref,我們必須將其傳遞給我們想要檢測點擊的外部元素。通常該元素將由一個布林狀態片段控制,例如我們在下面的示例中的狀態(即值“opened”)。 ``` import { useState } from 'react'; import { useClickOutside } from '@mantine/hooks'; function Demo() { const [opened, setOpened] = useState(false); const ref = useClickOutside(() => setOpened(false)); return ( <> <button onClick={() => setOpened(true)}>Open dropdown</button> {opened && ( <div ref={ref} shadow="sm"> <span>Click outside to close</span> </div> )} </> ); } ``` `useClickOutside` 接受一個回調函數,該函數控制當您實際單擊該元素外部時發生的情況。 在大多數情況下,我們想做一些非常簡單的事情,就是關閉它。為此,您可能需要一個狀態設置器(如 `setOpened`)並向其傳遞一個 false 值,然後隱藏您覆蓋的內容。 ![use click outside](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4jidp380brennyatol7w.gif) ## `useForm` 鉤子 在這個列表中,我最喜歡和最有用的鉤子是 `useForm` 鉤子。 這個鉤子專門來自 Mantine,涉及從庫中安裝一個特定的包:`@mantine/form`。它會為您提供在 React 中建立表單所需的一切,包括驗證輸入、顯示錯誤訊息以及在提交表單之前確保輸入值正確的能力。 `useForm` 接受一些初始值,這些初始值對應於您在表單中的任何輸入。 ``` import { TextInput, Button } from '@mantine/core'; import { useForm } from '@mantine/form'; function Demo() { const form = useForm({ initialValues: { email: '' }, validate: { email: (value) => (/^\S+@\S+$/.test(value) ? null : 'Invalid email'), }, }); return ( <div> <form onSubmit={form.onSubmit((values) => console.log(values))}> <TextInput withAsterisk label="Email" placeholder="[email protected]" {...form.getInputProps('email')} /> <Button type="submit">Submit</Button> </form> </div> ); } ``` `useForm` 的最大好處是它的助手,例如 `validate` 函數,它接收輸入到每個輸入的值,然後允許您建立驗證規則。 例如,如果您有一個電子郵件輸入,您可能有一個正則表達式來確定它實際上是否是一個有效的電子郵件(如您在上面的程式碼中所見)。如果沒有,那麼您可以顯示一條錯誤訊息並阻止提交表單。 ![使用表格](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n13l1gqejzx6y227p0j2.gif) 您如何獲取已輸入到表單中的值? Mantine 提供了一個非常方便的助手,叫做“getInputProps”,你只需提供你正在使用的輸入的名稱(比如電子郵件),它就會自動設置一個 onChange 來追蹤你在表單中輸入的值. 此外,為了處理表單提交,並在其值未通過驗證規則時阻止送出,它有一個特殊的 `onSubmit` 函數,您可以將其包裹在常規的 onSubmit 函數中。除了應用驗證規則之外,它還會負責在表單事件上呼叫 `preventDefault()`,這樣您就不必手動執行此操作。 我只用了這個鉤子的基本功能,但我強烈建議您在下一個專案中使用它。傳統上,表單很難正常工作,尤其是需要驗證和可見錯誤訊息的表單。 `useForm` 讓它變得異常簡單! --- 以上,簡單分享,希望對您有幫助。

現代前端框架的背後觀念:新手必讀基本功

框架背後有什麼必學觀念的?這篇文章簡單整理如下 原文出處:https://dev.to/lexlohr/concepts-behind-modern-frameworks-4m1g --- 很多初學者會問“我應該學哪個框架?”和“學一個框架之前需要學多少JS或TS?” - 無數自以為是的文章都在宣傳作者首選框架或庫的優勢,而不是向讀者展示其背後的概念、教他們如何做出明智的決定。讓我們先解決第二個問題: ## “在學習框架之前要學多少 JS/TS?” 盡可能多地理解它們的基本概念。您將需要了解基本資料類型、函數、基本運算符和文檔對像模型 (DOM),這是 HTML 和 CSS 在 JS 中的基礎。雖然先學一點當然沒關係,但沒必要先精通框架或庫。 如果您是一個完全的初學者,[JS for cats](http://jsforcats.com/) 可能是您第一步的好資源。繼續前進,直到您感到自信為止,然後繼續前進,直到您開始感到自信不足。那就是你了解足夠的 JS/TS 並可以開始學框架的時間。其餘的你可以邊走邊學。 ## “你指的是什麼概念?” - 狀態 - 效果 - 記憶化 - 模板和渲染 所有現代框架都從這些概念中衍伸出它們的功能。 ### 狀態 狀態只是讓您的應用程式跑起來的資料。它可能在全局級別上,適用於應用程式的較大部分,或適用於單個元件。讓我們以一個簡單的計數器為例。它保留的計數是狀態。我們可以讀取狀態並寫入狀態以增加計數。 最簡單的表示通常是一個變數,其中包含我們的狀態所包含的資料: ``` let count = 0; const increment = () => { count++; }; const button = document.createElement('button'); button.textContent = count; button.addEventListener('click', increment); document.body.appendChild(button); ``` 但是這段程式碼有一個問題:對 count 的更改,就像對 increment 所做的更改一樣,不會更新按鈕的文本內容。我們可以手動更新所有內容,但這對於更複雜的用例來說並不能很好地擴展。 `count` 更新其用戶的能力稱為*反應性*。這是通過訂閱並重新執行應用程式的訂閱部分來更新的。 幾乎每個現代前端框架和庫都有一種響應式管理狀態的方法。解決方案分為三部分,至少採用其中之一或混合使用: - Observables / Signals - Reconciliation of immutable updates - Transpilation #### Observables / Signals Observables 基本上是允許藉由訂閱閱讀器的函數來進行讀取的結構。然後訂閱者在更新時重新執行: ``` const state = (initialValue) => ({ _value: initialValue, get: function() { /* subscribe */; return this._value; }, set: function(value) { this._value = value; /* re-run subscribers */; } }); ``` 這個概念的第一個用途之一是在 [knockout](https://knockoutjs.com/) 中,它使用相同的函數,帶和不帶參數進行寫/讀存取。 這種模式目前正在以「信號」的形式復興,例如在 [Solid.js](https://www.solidjs.com/docs/latest/api#createsignal) 和 [preact signals](https://preactjs.com /guide/v10/signals/),但在 [Vue](https://vuejs.org/) 和 [Svelte](https://svelte.dev/) 的底層使用了相同的模式。 [RxJS](https://rxjs.dev/) 為 [Angular](https://angular.io/) 的反應層提供動力,是這一原則的延伸,超越了簡單狀態,但有人可能會爭辯說它模擬複雜性的能力可能反而綁手綁腳。 [Solid.js](https://www.solidjs.com/) 還以儲存(可以通過 setter 操作的物件)和可變(可以像平常一樣使用的物件)的形式進一步抽象這些信號 JS 物件或 [Vue](https://vuejs.org/) 中的狀態來處理巢狀狀態物件。 #### Reconciliation of immutable states 不變性意味著如果一個物件的屬性發生變化,整個物件引用必須改變,所以簡單的引用比較可以很容易地檢測到是否有變化,這就是協調器所做的。 ``` const state1 = { todos: [{ text: 'understand immutability', complete: false }], currentText: '' }; // updating the current text: const state2 = { todos: state1.todos, currentText: 'understand reconciliation' }; // adding a to-do: const state3 = { todos: [ state.todos[0], { text: 'understand reconciliation', complete: true } ], currentText: '' }; // this breaks immutability: state3.currentText = 'I am not immutable!'; ``` 如您所見,未更改專案的引用被重新使用。如果協調器檢測到不同的物件引用,它會再次使用狀態(props, memos, effects, context)來重跑所有元件。由於讀取存取是被動的,這需要手動指定對反應值的依賴性。 顯然,您不是以這種方式定義狀態。您可以從現有屬性建置它,也可以使用所謂的 reducer。reducer 是一個函數,它接受一個狀態並返回另一個狀態。 [react](https://reactjs.org/) 和 [preact](https://preactjs.com/) 使用此模式。它適合與 vDOM 一起使用,我們將在稍後描述模板時探討它。 並非每個框架都使用其 vDOM 來使狀態完全響應。 例如 [Mithril.JS](https://mithril.js.org/components.html#state),元件會在設置的事件後變化後更新狀態;否則你必須手動觸發 `m.redraw()`。 #### Transpilation Transpilation 是一個建置步驟,它重寫我們的程式碼以使其在舊瀏覽器上執行或賦予它額外的能力;在這種情況下,該技術用於將簡單變數更改為反應系統的一部分。 [Svelte](https://svelte.dev/) 基於一個轉譯器,該轉譯器還通過看似簡單的變數宣告和存取為其反應式系統提供動力。 順便說一句,[Solid.js](https://solidjs.com) 使用轉譯,但不是針對它的狀態,只是針對模板。 ### 效果 在大多數情況下,我們需要對反應狀態做更多的事情,而不是從中衍伸並渲染到 DOM 中。我們必須管理副作用,這些都是由於視圖更新之外的狀態更改而發生的所有事情(儘管 [Solid.js](https://solidjs.com) 等一些框架也將視圖更改視為效果)。 還記得第一個例子中,訂閱處理被故意遺漏的狀態嗎?讓我們完成這個處理效果,來作為對更新的反應: ``` const context = []; const state = (initialValue) => ({ _subscribers: new Set(), _value: initialValue, get: function() { const current = context.at(-1); if (current) { this._subscribers.add(current); } return this._value; }, set: function(value) { if (this._value === value) { return; } this._value = value; this._subscribers.forEach(sub => sub()); } }); const effect = (fn) => { const execute = () => { context.push(execute); try { fn(); } finally { context.pop(); } }; execute(); }; ``` 這基本上是 [preact signals](https://preactjs.com/guide/v10/signals/) 或 [Solid.js](https://solidjs.com) 中反應狀態的簡化,沒有錯誤處理和狀態突變模式(使用接收前一個值並返回下一個值的函數),但這很容易加入。 它允許我們使前面的範例具有反應性: ``` const count = state(0); const increment = () => count.set(count.get() + 1); const button = document.createElement('button'); effect(() => { button.textContent = count.get(); }); button.addEventListener('click', increment); document.body.appendChild(button); ``` > ☝ 使用您的開發人員工具在 [空白頁面](about:blank) 中嘗試上述兩個程式碼塊。 在大多數情況下,框架允許不同的時間安排,讓效果在渲染 DOM 之前、期間或之後執行。 ### 記憶化 Memoization 意味著緩存從狀態計算的值,它會從狀態衍伸的變化更新時更新。它基本上是一種回傳衍伸狀態的效果。 在重新執行元件功能的框架中,例如 [react](https://reactjs.org/) 和 [preact](https://preactjs.com/),這讓某些複雜計算不需要每次都重複計算。 對於其他框架,情況恰恰相反:它允許您選擇部分組件進行響應式更新,同時緩存之前的計算。 對於我們簡單的反應式系統,memo 看起來像這樣: ``` const memo = (fn) => { let memoized; effect(() => { if (memoized) { memoized.set(fn()); } else { memoized = state(fn()); } }); return memoized.get; }; ``` ### 模板化和渲染 現在我們有了純的、衍伸的和緩存形式的狀態,我們想把它展示給用戶。在我們的範例中,我們直接使用 DOM 來加入按鈕並更新其文本內容。 為了對開發人員更加友好,幾乎所有現代框架都支持一些特定領域的語言來編寫類似於程式碼中所需輸出的內容。儘管有不同的風格,比如 `.jsx`、`.vue` 或 `.svelte` 文件,但它們都歸結為用類似於 HTML 的程式碼表示 DOM,因此基本上 ``` <div>Hello, World</div> // in your JS // becomes in your HTML: <div>Hello, World</div> ``` 你可能會問“我要把狀態放在哪裡?”。很好的問題。在大多數情況下,`{}` 用於表示屬性和節點周圍的動態內容。 最常用的 JS 模板語言擴展無疑是 JSX。對於 [react](https://reactjs.org),它被編譯為純 JavaScript,其方式允許它建立 DOM 的虛擬表示,一種稱為虛擬文檔對像模型或簡稱 vDOM 的內部視圖狀態。 這樣設計的原因是:建立物件比存取 DOM 快得多,所以如果你能用當前的替換後者,你可以節省時間。但是,如果您在任何情況下都有大量 DOM 更改或建立無數物件而沒有更改,則此解決方案的優點就變成必須通過「記憶化」來規避的缺點。 ``` // original code <div>Hello, {name}</div> // transpiled to js createElement("div", null, "Hello, ", name); // executed js { "$$typeof": Symbol(react.element), "type": "div", "key": null, "ref": null, "props": { "children": "Hello, World" }, "_owner": null } // rendered vdom /* HTMLDivElement */<div>Hello, World</div> ``` 不過,JSX 不僅限於 react。例如,Solid 使用其轉譯器更徹底地更改程式碼: ``` // 1. original code <div>Hello, {name()}</div> // 2. transpiled to js const _tmpl$ = /*#__PURE__*/_$template(`<div>Hello, </div>`, 2); (() => { const _el$ = _tmpl$.cloneNode(true), _el$2 = _el$.firstChild; _$insert(_el$, name, null); return _el$; })(); // 3. executed js code /* HTMLDivElement */<div>Hello, World</div> ``` 雖然轉譯後的程式碼乍看可能令人望而生畏,但解釋這裡發生的事情卻相當簡單。首先,建立包含所有靜態部分的模板,然後複製它以建立其內容的新實體,並加入動態部分並連接以根據狀態更改進行更新。 Svelte 走得更遠,不僅可以轉換模板,還可以轉換狀態。 ``` // 1. original code <script> let name = 'World'; setTimeout(() => { name = 'you'; }, 1000); </script> <div>Hello, {name}</div> // 2. transpiled to js /* generated by Svelte v3.55.0 */ import { SvelteComponent, append, detach, element, init, insert, noop, safe_not_equal, set_data, text } from "svelte/internal"; function create_fragment(ctx) { let div; let t0; let t1; return { c() { div = element("div"); t0 = text("Hello, "); t1 = text(/*name*/ ctx[0]); }, m(target, anchor) { insert(target, div, anchor); append(div, t0); append(div, t1); }, p(ctx, [dirty]) { if (dirty & /*name*/ 1) set_data(t1, /*name*/ ctx[0]); }, i: noop, o: noop, d(detaching) { if (detaching) detach(div); } }; } function instance($$self, $$props, $$invalidate) { let name = 'World'; setTimeout( () => { $$invalidate(0, name = 'you'); }, 1000 ); return [name]; } class Component extends SvelteComponent { constructor(options) { super(); init(this, options, instance, create_fragment, safe_not_equal, {}); } } export default Component; // 3. executed JS code /* HTMLDivElement */<div>Hello, World</div> ``` 也有例外。例如,在 [Mithril.js](https://mithril.js.org/) 中,雖然可以使用 JSX,但我們鼓勵您編寫 JS: ``` // 1. original JS code const Hello = { name: 'World', oninit: () => setTimeout(() => { Hello.name = 'you'; m.redraw(); }, 1000), view: () => m('div', 'Hello, ' + Hello.name + '!') }; // 2. executed JS code /* HTMLDivElement */<div>Hello, World</div> ``` 雖然大多數人會發現開發人員缺乏經驗,但其他人更喜歡完全控制他們的程式碼。根據他們主要想解決的問題,缺少轉譯步驟甚至可能是有益的。 儘管很少有人這樣推薦,許多其他框架都允許在不進行轉譯的情況下使用。 ## “我現在應該學習什麼框架或庫?” 我有一些好訊息和一些壞訊息要告訴你。 壞訊息是:沒有萬靈丹。沒有哪個框架在每個方面都比其他框架好得多。他們每個人都有自己的優勢和妥協。 [React](https://reactjs.org/) 有它的鉤子規則,[Angular](https://angular.io/) 缺乏簡單的信號,[Vue](https://vuejs.org/)缺乏向後兼容性,[Svelte](https://svelte.dev/) 不能很好地擴展,[Solid.js](https://www.solidjs.com/) 禁止解構,[Mithril.js]( https://mithril.js.org/) 並不是真正的反應式,僅舉幾例。 好訊息是:沒有錯誤的選擇——至少,除非專案的要求真的很有限,無論是在 bundle 大小還是性能方面。每個框架都會完成它的工作。有些人可能需要配合團隊的設計決策,這可能會使您的速度變慢,但無論如何您都應該能夠獲得可行的結果。 話雖這麼說,沒有框架也可能是一個可行的選擇。許多專案都被過度使用 JavaScript 破壞了。其實帶有一些互動性的靜態頁面就可以完成這項工作。 現在您已經了解了這些框架和庫應用的概念,請選擇最適合您當前任務的概念。不要害怕在下一個專案中切換框架。沒有必要學習所有這些。 如果你嘗試一個新的框架,我發現最有幫助的事情之一就是跟它的社群有所連結,無論是在社群媒體、discord、github 還是其他地方。他們可以告訴您哪些方法適合他們的框架,這將幫助您更快地獲得更好的解決方案。 ## “拜託,你*總是*有個人喜好吧!” 如果你的主要目標是就業,我建議學習 [react](https://reactjs.org/)。如果您想要輕鬆的性能和控制體驗,請嘗試 [Solid.js](https://solidjs.com);你可能會在 Solid 的 [Discord](https://discord.com/invite/solidjs) 上見到我。 但請記住,所有其他選擇都同樣有效。你不應該因為我這麼說就選擇一個框架,而應該使用最適合你的框架。

JavaScript 系列四:第4課 ── jQuery 套件

## 課程目標 認識並且能使用 jQuery 套件 ## 課程內容 這一課要教的東西比較有爭議 jQuery 是 2006 - 2015 年代,前端網頁開發的王者 當時的瀏覽器廠商眾多,網頁規格 API 支援方式不同、不完整(尤其是 IE 一堆奇怪的 API) 當時的前端工程師,非常痛苦,要為了 IE 多改很多寫法 加上當時很多瀏覽器沒有支援 `.querySelector` `.querySelectorAll` 這些 Selector API 所以 jQuery 的出現,強大的選擇器語法,以及眾多方便的功能,大幅降低了前端開發的成本 不過,時至今日,jQuery 的大部份功能,都已在瀏覽器 JavaScript 語法中原生支援了 再加上開發大型應用程式,DOM 的管理一旦複雜起來,就會直接使用 React 或者 Vue 這種框架來管理 DOM,不會再手動去操作 DOM (前端框架會處理完 DOM 互動的部份。此時如果再手動操作 DOM,那程式碼就會一團混亂) 也就是說,小型專案,「不需要」用 jQuery;大型專案,「不可以」用 jQuery 除此之外,jQuery 套件本身檔案不小,引入此套件會影響網頁載入速度,影響 UX,同時會影響搜尋引擎 SEO 排名 --- 因為上述種種原因,在今天,前端工程師普遍鄙視 jQuery,避之惟恐不及 我個人的建議是:團隊在開發複雜的前端應用時,的確不要再用 jQuery 了! 但是,當只是做小網站,接小案子賺錢,或者做個人的業餘專案(side project),只是希望快速做完某些功能時,jQuery 還是非常好用! 原因有兩個 第一,jQuery 選擇器寫起來很短,可以少打很多字,開發很快速 第二,jQuery 外掛生態系存在已久,很多強大的 UI 元件會用到 jQuery,適合的話,實在沒道理全面放棄不用 而且,並不是所有網站,都需要直接導入 React 跟 Vue 這種大型框架!沒必要! 除此之外,維護一大堆現有的程式碼,難免已經用到 jQuery,還是能看懂 API 比較好 所以,還是稍微教大家一些 jQuery 的用法。至於什麼場合要使用,你就自行判斷吧 --- 官網 https://jquery.com/ API 用法 https://api.jquery.com/ CDN 連結 https://releases.jquery.com/ 請自行逛一逛,大概知道 jQuery 有哪些 API 就好,不用花太多時間學習 jQuery 你應該會發現,一大堆功能,你自己就寫得出來,而且寫起來也不複雜,例如 `.hide()` `.show()`,你之前的作業就寫過,根本不需要用 jQuery 剩下的一大堆功能,目前看不懂沒關係、覺得自己做不出來沒關係,未來的課程會教你 --- 簡單地說,jQuery 選擇器就是使用金錢符號來呼叫函示 `$()` 其實是 `jQuery()` 的簡寫而已 ``` <h1 class="title"> Hide me </h1> <p class="para"> Hide me </p> <p class="para"> Hide me </p> <p class="para"> Hide me </p> ``` ``` document.querySelector('.title').style.display = 'none'; for (var p of document.querySelectorAll('.para')) { p.style.display = 'none'; } ``` 像這樣的程式,隱藏了畫面上多個元素 使用 jQuery 的寫法會變成 ``` $('.title').hide(); $('.para').hide(); ``` 很多人覺得,jQuery 只剩一些少打字的功能,卻讓網頁多載入整個 jQuery 套件,很沒意義、不值得 我倒是覺得,還是滿方便的。快速開發時,少打很多字。而且 jQuery 可以自動處理多個元素,可以少寫 for 迴圈 當然了,上面的程式碼,跟下面這段是完全一樣的 ``` jQuery('.title').hide(); jQuery('.para').hide(); ``` jQuery 基本上就這樣而已,你喜歡嗎? 實務上,使用時,如果翻文件,還是不知怎麼寫,就去搜尋引擎找關鍵字 `jquery 改變顏色` `jquery change color` 之類的 別忘了,軟體工程師在工作時,會花很多時間在翻文件、上網到處看文章、搜尋範例程式碼,所以要習慣這件事 --- 坊間很多課程,會在一開始就教 jQuery。這跟直接教前端框架的問題一樣:學生的基本功,因此變得很差 但是本課程已讓你知道最基本的原生 DOM 寫法,所以你在用 jQuery 時,會知道背後發生什麼事,也知道刪掉 jQuery 的話,要怎麼用原生語法改寫 所以,我認為在本課程的安排下,jQuery 並不會耽誤你的學習旅程 喜歡 jQuery 的話,就把 API 網頁,多逛一逛,工作上想用的話,就大方使用吧! ## 課後作業 請使用 https://jsfiddle.net 這次的作業要交兩份 請建立兩份 jsfiddle,並使用以下 html ``` <h1 class="title"> Make me green </h1> <p class="para"> Make me red </p> <p class="para"> Me red too </p> <p class="para"> Also me </p> ``` 在第一份,不使用 jQuery,把 h1 文字變為綠色,p 文字變為紅色 在第二份,請使用 jQuery,把 h1 文字變為綠色,p 文字變為紅色 寫完之後,你自行比較一下,網頁多加一個肥大的套件,但是可以少打這些字,你覺得值得嗎? 這是一個主觀問題,你就根據情況決定你的答案吧! 做出以上功能,你就完成這次的課程目標了!

JavaScript 系列二:結語

簡單複習一下,在這份教材中,我們學會了 - DOM 樹基本觀念 - DOM 樹新增、刪除 - DOM 樹找到元素的方法 - 基本的除錯技巧 - 動態加上 onclick 事件 - 操作 onchange 事件 - 基本的 for 迴圈用法 - 在 DOM 樹存取、修改元素的 class - 在 DOM 樹存取、修改元素的 style - 學會 `.querySelector()` `.querySelectorAll()` 的用法(Selector API) - 學會 `.closest()` 的用法 - 初步認識「重構」的觀念 利用本課程學到的技巧,你已能夠對 DOM 樹進行很多操作,也能夠處理工作上很多功能需求! DOM 的操作函式有非常多,本課只教了最基本的幾個,實務上你會看到超多尋找 DOM 元素的函式 你就隨便找、隨便用,都可以,能順利找到、處理元素就好! --- 觀察本課內容,你會發現完全沒有用到第三方套件,通通是寫原生 JavaScript 本課所學內容,其實就是所有前端框架的基礎。不管你用了任何複雜的工具或框架,它們的背後,其實就只是這樣操作 DOM 而已,並沒有很難 本課內容所教的開發方法,大概是西元 2000 - 2010 年代的開發方式,很傳統,現在比較少這樣寫 實務上,現代前端工程師,工作時主要在使用「框架」來開發,例如 Vue 或者 React 因此,坊間補習班,大多是直接從「現代前端框架」開始教 然而,我觀察到,大多數畢業學生,因此對於 DOM 基本觀念一知半解、覺得框架很黑箱,並且基本功非常不好 所以我課程設計先從老方法開始教,讓大家基本功比較好,接著再學工具與框架,會更有踏實的感覺 --- 消化、研究完本課程之後,關於 JavaScript 更多必學的基本觀念 請接著前往「自學網頁の嬰兒教材:JavaScript(三)」開始學習吧! https://codelove.tw/@howtomakeaturn/course/gqveaW

JavaScript 系列二:第7課 ── 用 Selector API 選取元素

## 課程目標 學會基本的 Selector API 用法 學會基本的 `.closest()` 的用法 ## 課程內容 課程到目前為止,要存取元素,都是使用 `document.getElementById` `.parentElement` `.children` 然後上上下下到處爬來爬去、找到目標元素 在網頁結構簡單的時候還好,一旦內容複雜起來,你會發現這樣寫,有點麻煩 其實,在學習 css 的時候,就有一套指定元素的方法了,如果能直接用 css 那套設定樣式的方法,來找到元素,那不是很方便嗎? ``` <div> <div id="wrapper"> 我想跟您說: <p> Hi, <span id="target">早上好</span> </p> <p> Hi, <span>中午好</span> </p> <p> Hi, <span>晚上好</span> </p> </div> </div> ``` ``` document.querySelector('#wrapper p span').style.color = 'red'; ``` 在 jsfiddle 試試看,會發現「早上好」變成紅字了 使用 `.querySelector()` 可以很方便的找到元素!如果找到多個元素,只會回傳第一個元素 接著試試這樣 ``` var spans = document.querySelectorAll('#wrapper p span'); for (span of spans) { span.style.color = 'red'; } ``` 在 jsfiddle 試試看,會發現三塊文字,都變成紅字了 使用 `.querySelectorAll()` 可以很方便的找到多個元素!接著就用陣列來處理即可! 以上兩種用法,是不是比之前的老方法方便許多呢? --- 有件事要提一下,老方法的 `.getElementById()` 只能用在 `document` 物件上 新方法的 `.querySelector()` `.querySelectorAll()` 除了可以用在 `document` 之外,還能用在一般 DOM 元素上喔! ``` var wrapper = document.querySelector('#wrapper') wrapper.querySelector('p span').style.color = 'red'; ``` 所以這樣寫也可以!是不是覺得更彈性、更強大、更好用了呢? 有了這些,可以完全取代 `document.getElementById` 與 `children` 的寫法! --- 接著來看看有什麼新方法可以取代 `.parentElement` 吧 ``` var target = document.querySelector('#target') target.closest('span').style.color = 'red'; ``` ``` var target = document.querySelector('#target') target.closest('p').style.color = 'red'; ``` ``` var target = document.querySelector('#target') target.closest('div').style.color = 'red'; ``` 在 jsfiddle 分別試試看,這三種程式碼,會讓哪些文字變紅色吧! `.closest()` 會回傳第一個找到的「祖先元素」 也就是順序為父元素、祖父元素、曾祖父元素,依此類推,不斷往上尋找,到找到第一個為止 實務上這個函式非常好用,可以完全取代 `.parentElement` 的寫法! ## 課後作業 接續前一課的作業,現在要來重構(refactor)程式碼 所謂的「重構」程式碼,就是程式的功能完全不變,但是讓程式碼更好讀、好維護 --- 請把作業中出現的 `.getElementById()` `.parentElement` `.children` 全部拿掉 通通使用本課教導的函式來改寫 改寫完之後,你會發現,原本的程式碼,如果不看 html,只看 JavaScript,只會看到 parentElement、children、跟一堆索引,到處爬,不知道在幹嘛 而在改寫之後,至少看起來比較像在寫 css 樣式的時候,會用 `span` `li` `button` 這些元素名稱來上下查找元素 光看 JavaScript 程式碼,會比原本好讀一些些! 單看這次作業,可能感覺還好。但在專案很大的時候,你不會想在程式碼看到全是 parentElement、children、跟一堆索引,你會希望有更多額外資訊 你會希望程式碼能更清楚表達:「目前到底是在找什麼元素」。所以實務上都是以新寫法為主的 不過呢,這依然是主觀問題。如果你喜歡整個職業生涯都用老寫法來做,應該也可以。高興就好囉! --- 完成這次重構,你就完成這次的課程目標了!

JavaScript 系列二:第3課 ── 認識 for 迴圈

## 課程目標 學習基本的 for 迴圈用法 ## 課程內容 之前的課程中,我們學過陣列&索引的基本用法 實務上,使用陣列時,通常會需要寫一些 for 迴圈搭配使用 for 的寫法有很多種,我們先學 for of 的寫法就好 ``` var fruits = ["Apple", "Banana", "Orange"]; var text = ""; for (var x of fruits) { text = text + x; } alert(text); ``` 像這樣,就能依序存取到陣列內的每個內容 for 迴圈後面是大括號 `{}` 把任務包起來 就跟 if 一樣,裡面當然也可以放多行程式碼 ``` var fruits = ["Apple", "Banana", "Orange"]; var num = 1; var text = ""; for (var x of fruits) { alert(num.toString() + ') ' + x ); text = text + x; num = num + 1; } alert(text); ``` 在上面的範例,也同時示範了,如果想要同時知道「當前內容在陣列內的順序」 只要宣告一個整數的變數,每次迴圈內都幫它 +1 即可 到 jsfiddle 試試看,就會清楚實際效果囉! ## 課後作業 接續前一課的作業,現在待辦清單基本功能有了 你希望可以把清單內容自動轉變為純文字,方便貼到 LINE 群組之類的地方,分享給別人看 這次要來實作「匯出為純文字」的功能 --- 請在清單的下方,新增一個「匯出為純文字」的按鈕 假設清單內目前有三個事項「洗衣服」、「買文具」、「去健身房」 按下匯出按鈕之後,就用 alert 跳出訊息「今日待辦:1. 洗衣服 2. 買文具 3. 去健身房」 alert 的內容,滑鼠移上去,應該是可以選取&複製的(如果您的瀏覽器不支援,也沒關係,反正就是 alert 出來就對了) 請稍微替這個匯出按鈕加一點 css 屬性,弄得漂亮一點,看起來才專業 做出這個功能,你就完成這次的課程目標了!

給自學 JavaScript 的初學者:7 個可以學習基本觀念的 Github 專案

使用這些 github repo 成為更好的前端開發人員。 原文出處:https://dev.to/hy_piyush/7-github-repositories-that-every-front-end-developer-must-know-300l ## Clean Code JavaScript 一些能幫助您程式碼更簡潔的開發觀念。 GitHub 連結:https://github.com/ryanmcdermott/clean-code-javascript ## JavaScript Algorithms and Data Structure 用 JavaScript 實作的演算法和資料結構,有解釋和進一步閱讀的連結 包含許多流行演算法和資料結構的 JavaScript 範例。 每個演算法和資料結構都有自己單獨的 README,帶有相關的解釋和進一步閱讀的連結。 GitHub 連結:https://github.com/trekhleb/javascript-algorithms ## You Don’t Know JavaScript 這是一個關於 JavaScript 的系列叢書。這是一系列深入探討 JavaScript 語言核心機制的書籍。 GitHub 連結:https://github.com/getify/You-Dont-Know-JS ## NodeJS Best Practice 這個存儲庫是對 Node.js 最佳實踐的總結和管理。這將幫助許多開發人員獲得有關 NodeJS 後端開發的進階知識。 GitHub 連結:https://github.com/goldbergyoni/nodebestpractices ## Frontend Checklist 適用於現代網站和專業開發人員的完美前端清單。它基於前端開發人員多年的經驗,並加入了一些其他開源清單。 GitHub 連結:https://github.com/thedaviddias/Front-End-Checklist ## Free For Dev 對 DevOps 和基礎設施開發,具有免費方案的 SaaS、PaaS 和 IaaS 產品列表。 不過,此列表的內容只對基礎架構開發人員(系統管理員、DevOps 從業者等)有用。 GitHub 連結:https://github.com/jixserver/free-for-dev ## DSA in JavaScript 解釋和實作的資料結構和演算法。 GitHub 連結:https://github.com/amejiarosario/dsa.js-data-structures-algorithms-javascript

給網站開發者:7 個值得在 2023 年用看看的免費工具

想要在 2023 年的 **Web 開發** 旅程中一帆風順嗎?參考看看這些免費工具吧! 原文出處:https://dev.to/ruppysuppy/7-free-tools-for-the-modern-web-developers-of-2023-4lhh ## 1. [Omatsuri](https://omatsuri.app/) 一個**開源 Web 應用程式**,有 **12 個令人難以置信的前端工具**,供日常開發使用。包含的工具有: 1. 三角形生成器 2. 顏色陰影生成器 3. 梯度產生器 4. 分頁器 5. SVG壓縮器 6. SVG → JSX 轉換器 7. base64編碼 8. 假資料生成器 9. 符號收錄 10. 假文字生成器 11. CSS 游標 12. 鍵盤事件程式碼 ![omatsuri](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ubhgroj9j4butoto73r.png) ## 2. [Coolers](https://coolors.co/) **Coolers** 是為您的網站生成 **調色板** 的最佳工具。 ![Coolers](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q40qayjwocnseojux08a.png) ## 3. [Keyframes](https://keyframes.app/) 就跟名字一樣,它是: > 基於瀏覽器的、適合手機的、可以讓 **CSS** 變得不那麼糟糕的工具。 它有幾個工具,例如**動畫**、**陰影**和**顏色生成器**。 ![Keyframes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s6f1h2a0caeb0yzx1hsg.png) ## 4. [Roadmap.sh](https://roadmap.sh/) **Roadmap**是一系列職涯路線圖,涵蓋了**前端**、**後端**、**區塊鏈**、**網路安全**等多個路徑。 他們也有**相關資源的連結**可供學習! ![Roadmap](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ppbw4ej1fvsbc8mzpjrr.png) ## 5. [FreeCodeCamp](https://www.freecodecamp.org/) **FreeCodeCamp** 是一個**非營利組織**,由**互動式學習網路平台**、**線上社群論壇**、**聊天室**、**線上出版物**、 **本地組織**組成,旨在讓任何人都可以學習 Web 開發。 ![FreeCodeCamp](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qh7mlh9jxlui5kq6755t.png) ## 6. [Postman](https://www.postman.com/) **Postman** 是一個用於建置和使用 **API** 的 **API 平台**。它是**後端工程師**工具庫中的必備工具,對**前端開發人員**也非常有用 ![Postman](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t2q0c4046o2rrux6534y.png) ## 7. [CSS Layout](https://csslayout.io/) 它是**數百個元件**的集合,您可以將其複製貼上到您的專案中,並根據您的需要進行客製化! ![css-layout](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/owuoadb9p06wqnvg7136.png) --- **以上供您參考!**

自學網頁の嬰兒教材:第5課 ── 用力送出表單

# 第5課 課程目標 認識各種常見的輸入欄位 能夠用表單送出資料 # 第5課 課程內容 用jsfiddle來練習: https://jsfiddle.net 這次要寫HTML區塊 請閱讀這份教材: [HTML Forms](http://www.tutorialspoint.com/html/html_forms.htm) 不習慣看英文,可以改看這裡: [HTML 表单和输入](http://www.w3school.com.cn/html/html_forms.asp) 把教學裡面的HTML貼到 jsfiddle 裡面做練習,貼好之後按上面的 RUN 按鈕,就會在右下角的 Result 看到結果了。 讀完、練習完這份教學裡面的程式碼,就算是學會 HTML 表單的用法,可以用表單來讓使用者輸入、選擇,接著送出各種資料了 # 第5課 作業 這次作業的情境如下: 你決定網路創業、開始網拍生意、線上賣衣服,並且自己設計購物網站 在後台管理面板中,需要有地方讓你新增商品項目 請利用本週學到的表單,將這個新增商品項目的表單做出來。 這個表單至少要能輸入以下欄位,(括號內代表建議的欄位類型): - 商品名稱 (text) - 價格 (text) - 是否免運費 (checkbox) - 性別 男/女 (radio) - 類別:上衣類 外套類 下身類 配件類 (select) - 商品備註 (textarea) 請讓這個表單用 POST 的方式將資料送出到 ‘/add-product’ (注意:網址’/add-product’並不存在,所以表單資料無法真的送過去。本週課程只談論表單製作。伺服器程式接收、處理表單資料,不在本週課程範圍) 完成這些,你就完成這次的課程目標了!

給軟體工程師的各類好用工具清單

向您介紹這個開發人員工具列表。它是一個開源專案,由社群整理。 讓我們開始吧! 🚀 原文出處:https://dev.to/dostonnabotov/ultimate-tools-for-developers-2aj2 --- ## 程式碼編輯器和 IDE 💻 - [Visual Studio Code](https://code.visualstudio.com/) 作為免費的開源程式碼編輯器,Visual Studio Code 是開發人員的絕佳工具。它帶有許多功能和外掛,使其成為開發人員的絕佳選擇。 - [CodeSandbox](https://codesandbox.io/) 簡單來說,CodeSandbox 就是 Visual Studio Code 的在線版本。 - [Dev - Visual Studio Code](https://github.dev/) github.dev 基於網絡的編輯器是一種輕量級的編輯體驗,完全在您的瀏覽器中執行。 有兩種方法可以打開基於 Web 的編輯器 1. 在任何存儲庫或拉取請求上按 `.` 鍵 2. 將 URL 中的 .com 替換為 .dev。例如。 `https://github.dev/username/repo` - [CodePen](http://codepen.io/) CodePen 是網絡前端的遊樂場。這是一個試驗、測試和展示您的前端工作的地方。此外,您還可以從其他開發人員那裡找到許多靈感。 - [Replit](https://repl.it/) Replit 是一個簡單、強大且協作的在線 IDE。這是編碼、協作和託管專案的好地方。 - [StackBlitz](https://stackblitz.com/) 面向前端和全棧開發人員的 Web IDE。 - [TypeScript Playground](https://www.typescriptlang.org/play/) 想玩玩看 TypeScript 嗎? TypeScript Playground 是一個適合你的地方。 ## 圖片 🖼 - [Unsplash](https://unsplash.com/) 為您的下一個專案輕鬆找到精美、高質量的照片。所有照片均可免費用於商業和個人用途。 - [Pexels](https://www.pexels.com/) Pexels 是免費庫存照片的重要來源。所有照片均可免費用於商業和個人用途。 - [Carbon](https://carbon.now.sh/) Carbon 是一個很棒的平台,可以建立和共享程式碼的精美圖像,允許您使用語法突出顯示、主題、字體等自定義圖像。 ## 顏色 🎨 - [Color Space](https://mycolor.space/) 再也不會浪費時間尋找完美的調色板!只需輸入顏色!並生成漂亮的調色板 - [Coolors](https://coolors.co/) 建立完美的調色板或從數千種美麗的配色方案中汲取靈感。 - [Color Wheel](https://www.canva.com/colors/color-wheel/) 想知道什麼顏色搭配起來好看嗎? Canva 的色輪讓色彩組合變得簡單。 ## 排版 📝 - [Google Fonts](https://fonts.google.com/) Google Fonts 是一個包含免費授權字體系列的庫。只需選擇您想要的字體,將它們下載到您的計算機或使用提供的 CSS 或 HTML 鏈接將它們嵌入您的網頁。 - [Fontsource](https://fontsource.org/) 如果您不想從 CDN 獲取字體,則可以使用整齊打包的 NPM 包中的自託管開源字體。 - [Nerd Fonts](https://www.nerdfonts.com/) Nerd Fonts 使用大量字形(圖標)修補針對開發人員的字體。 ## 設計 🎨 - [Figma](https://www.figma.com/) 一個免費的線上協作界面設計工具和原型製作工具。 - [Pinterest](https://www.pinterest.com/) Pinterest 是一種視覺發現工具,可用於為您的所有專案和興趣尋找創意。 ## 文檔 📚 - [MDN 網絡文檔](https://developer.mozilla.org/en-US/) 學習Web開發的最佳平台。每當您對 HTML、CSS、JavaScript 或任何其他網絡技術有疑問時,請務必先查看 MDN。 - [W3Schools](https://www.w3schools.com/) 幾乎所有您能想到的程式語言的參考。 - [CSS 技巧](https://css-tricks.com/) 提供使用 CSS(層疊樣式表)的提示、技巧和技術的最佳平台之一。 ## 工具 🛠 等一會兒!工具中的工具?是的,你沒有聽錯。這裡有一些工具可以幫助您找到更多工具。 😃 - [Stack Overflow](https://stackoverflow.com/) Stack Overflow 是一個面向專業和狂熱工程師的問答網站。這是提出問題和獲得答案的好地方。 - [Micro Digital Tools](https://mdigi.tools/) 一組對開發人員有用的工具。 - [Small Dev Tools](https://smalldev.tools/) 一組對開發人員有用的工具。 - [Can I Use](https://caniuse.com/) Can I Use 提供了最新的瀏覽器支持表,以支持桌面和移動 Web 瀏覽器上的前端 Web 技術。 - [網站圖標生成器](https://favicon.io/) 您是否曾經為了替自己的網站建立網站圖標而苦惱?不同的尺寸,不同的格式,不同的平台。 從文本、圖像或從數百個表情符號中選擇快速生成您的網站圖標。 - [Font Awesome](https://fontawesome.com/) 免費和高級圖標庫。 - [OverAPI.com](https://overapi.com/) 以有組織的格式查找大量不同技術的備忘單。 - [Transform](https://transform.tools/) 多語言網絡轉換器。輕鬆將 HTML 轉換為 Pug、將 TypeScript 轉換為 JavaScript、將 Markdown 轉換為 HTML 等等... - [Frontend Tools](https://murtazajoo.github.io/tools/) 一個網站,您可以在其中找到具有更好用戶體驗的所有工具。 - [GitProtect](https://gitprotect.io/) 適用於所有 GitHub、GitLab、Bitbucket 和 Jira 資料的 DevOps 備份和災難恢復軟體。 - [Linear](https://linear.app/) 在團隊中組織問題和拉取請求的好工具。 ## 結論 🎉 希望您覺得這個列表有用。

20 個冷門、但很實用的 git 指令:值得你稍微認識一下

如果您曾經瀏覽過 [git 手冊](https://git-scm.com/docs)(或執行 `man git`),那麼您會發現 git 指令比我們每天在用的多很多。很多指令非常強大,可以讓你的生活更輕鬆(有些比較小眾,但知道一下還是不錯)。 > 這篇文章整理了我最喜歡的 20 個冷門 git 功能,您可以使用來改善您的開發流程、給您的同事留下深刻印象、幫助您回答 git 面試問題,最重要的是 - 可以玩得很開心! 原文出處:https://dev.to/lissy93/20-git-commands-you-probably-didnt-know-about-4j4o --- ## Git Web > 執行 [`git instaweb`](https://git-scm.com/docs/git-instaweb) 可以立即瀏覽 gitweb 中的工作存儲庫 Git 有一個內建的[基於網路可視化工具](https://git-scm.com/docs/gitweb) 可以瀏覽本地存儲庫,它允許您通過瀏覽器中的 GUI 查看和管理您的存儲庫。它包含許多有用的功能,包括: - 瀏覽和單步執行修訂並檢查差異、文件內容和元資料 - 可視化查看提交日誌、分支、目錄、文件歷史和附加資料 - 生成提交和存儲庫活動日誌的 RSS 或 Atom 提要 - 搜尋提交、文件、更改和差異 要打開它,只需從您的存儲庫中執行 `git instaweb`。您的瀏覽器應該會彈出並讀取 http://localhost:1234 。如果您沒有安裝 Lighttpd,您可以使用“-d”標誌指定一個備用 Web 伺服器。其他選項可以通過標誌配置(例如 `-p` 用於端口,`-b` 用於打開瀏覽器等),或在 git 配置中的 `[instaweb]` 塊下配置。 還有 `git gui` 命令,它可以打開一個基於 GUI 的 git 應用程式 ![](https://i.ibb.co/0DrmcWG/Screenshot-from-2022-12-17-20-26-30.png) --- ## Git Notes > 使用 [`git notes`](https://git-scm.com/docs/git-notes) 向提交加入額外訊息 有時您需要將其他資料附加到 git 提交(除了更改、訊息、日期時間和作者訊息之外)。 註釋存儲在 .git/refs/notes 中,由於它與提交對像資料是分開的,因此您可以隨時修改與提交關聯的註釋,而無需更改 SHA-1 哈希。 您可以使用 `git log`、使用大多數 git GUI 應用程式或使用 `git notes show` 命令查看筆記。一些 git 主機還在提交視圖中顯示註釋(儘管 [GH 不再顯示註釋](https://github.blog/2010-08-25-git-notes-display/))。 --- ## Git Bisect > 使用 [`git bisect`](https://git-scm.com/docs/git-bisect) 你可以使用二進制搜尋找到引入錯誤的提交 這是最強大又好用的 git 命令之一 - bisect 在除錯時絕對是救命稻草。開始對分後,它會為您檢查提交,然後您告訴它提交是“好”(沒有錯誤)還是“壞”(引入錯誤),這可以讓您縮小最早提交的錯誤。 請執行 `git bisect start`,然後使用 `git bisect good <commit-hash>` 向其傳遞一個已知的良好提交,並使用 `git bisect bad <optional-hash>` 傳遞一個已知的錯誤提交(預設為當前)。然後它會檢查好提交和壞提交之間的提交,然後你用 `git bisect good` 或 `git bisect bad` 指定錯誤存在與否。然後它會重複這個過程,在好與壞的中心檢查一個提交,一直到你找到引入錯誤的確切提交。隨時使用 `git bisect reset` 取消。 bisect 命令還有更多功能,包括回放、查看提交、跳過,因此下次除錯時值得查看文檔。 --- ## Git Grep > 使用 [`git grep`](https://git-scm.com/docs/git-grep) 在您的存儲庫中搜尋程式碼、文件、提交或任何其他內容 有沒有發現自己需要在 git 專案中的任何地方搜尋字串?使用 git grep,您可以輕鬆地在整個專案中和跨分支搜尋任何字串或 RegEx(例如更強大的 <kbd>Ctrl</kbd> + <kbd>F</kbd>!)。 `git grep <regexp> <ref>` 它包括大量 [選項](https://git-scm.com/docs/git-grep#_options) 來縮小搜尋範圍,或指定結果格式。例如,使用 `-l` 僅返回文件名,`-c` 指定每個文件返回的匹配數,`-e` 排除匹配條件的結果,`--and` 指定多個條件,` -n` 以行號搜尋。 由於 git grep 與正則表達式兼容,因此您可以使用搜尋的字串獲得更多進階訊息。 您還可以使用它來指定文件擴展名,例如 `git grep 'console.log' *.js`,它將顯示 JavaScript 文件中的所有 console.logs 第二個參數是一個 ref,可以是分支名稱、提交、提交範圍或其他任何內容。例如。 `git grep "foo" HEAD~1` 將搜尋之前的提交。 --- ## Git Archive > 使用 [`git archive`](https://git-scm.com/docs/git-archive) 將整個 repo 合併到一個文件中 共享或備份存儲庫時,通常首選將其存儲為單個文件。使用 git archive 將包括所有 repo 歷史記錄,因此可以輕鬆將其提取回其原始形式。該命令還包括許多附加選項,因此您可以準確自定義存檔中包含和不包含的文件。 ``` git archive --format=tar --output=./my-archive HEAD ``` --- ## Git Submodules > 使用 [`git submodule`](https://git-scm.com/docs/git-submodule) 將任何其他存儲庫拉入您的存儲庫 在 git 中,[submodules](https://git-scm.com/docs/gitsubmodules) 讓您可以將一個存儲庫掛載到另一個存儲庫中,通常用於核心依賴項或將組件拆分到單獨的存儲庫中。有關詳細訊息,請參閱[這篇文章](https://notes.aliciasykes.com/17996/quick-tip-git-submodules)。 執行以下命令會將模塊拉到指定位置,並建立一個 .gitmodules 文件,以便在複製 repo 時始終下載它。複製 repo 時使用 `--recursive` 標誌來包含子模塊。 ``` git submodule add https://github.com/<user>/<repo> <path/to/save/at> ``` 還有 [`git subtree`](https://www.atlassian.com/git/tutorials/git-subtree),它做類似的事情,但不需要元資料文件。 --- ## Git Bug Report > 使用 [`git bugreport`](https://git-scm.com/docs/git-bugreport) 編寫錯誤票,包括 git 和系統訊息 此命令將捕獲系統訊息,然後打開一個標準錯誤模板(重現步驟、實際 + 預期輸出等)。完成的文件應該是一個非常完整的錯誤報告,包含所有必要的訊息。 如果您是開源包的維護者並要求用戶(開發人員)提出錯誤報告,這將非常方便,因為它確保包含所有必要的資料。 如果您向核心 git 系統提交錯誤報告,您還可以執行 [`git diagnostic`](https://git-scm.com/docs/git-diagnose) 命令,然後提出您的問題 [這裡](https://github.com/git/git)。 --- ## Git Fsck > 使用 [`git fsck`](https://git-scm.com/docs/git-fsck) 檢查所有物件,或恢復無法存取的物件 雖然不常需要,但有時您可能必須驗證 git 存儲的物件。這就是 fsck(或文件系統檢查)發揮作用的地方,它測試對像資料庫並驗證所有物件的 SHA-1 ID 及其建立的連接。 它還可以與 `--unreachable` 標誌一起使用,以查找不再可以從任何命名引用存取的物件(因為與其他命令不同,它包括 `.git/objects` 中的所有內容)。 --- ## Git Stripspace > 使用 [`git stripspace`](https://git-scm.com/docs/git-stripspace) 格式化給定文件中的空格 最佳做法是避免在行尾尾隨空格,避免有多個連續的空行,避免輸入的開頭和結尾出現空行,並以新行結束每個文件。有很多特定於語言的工具可以自動為您執行此操作(例如 prettier),但 Git 也內置了此功能。 它用於元資料(提交訊息、標籤、分支描述等),但如果您將文件通過管道傳輸給它,然後將響應通過管道傳輸回文件,它也可以工作。例如。 `cat ./path-to-file.txt | git stripspace` 或 `git stripspace < dirty-file.txt > clean-file.txt` 您還可以使用它來刪除註釋(使用 `--strip-comments`),甚至註釋掉行(使用 `--comment-lines`)。 --- ## Git Diff > 使用 [`git diff`](https://git-scm.com/docs/git-diff) 你可以比較 2 組程式碼之間的差異 您可能知道您可以執行 `git diff` 來顯示自上次提交以來的所有更改,或者使用 `git diff <commit-sha>` 來比較 2 次提交或 1 次提交到 HEAD。但是您可以使用 diff 命令做更多的事情。 您還可以使用它來比較任意兩個任意文件,使用 `diff file-1.txt file-2.txt`(不再存取 [diffchecker.com](https://www.diffchecker.com/compare/)! ) 或者使用 `git diff branch1..branch2` 相互比較 2 個分支或引用 請注意,雙點 (`..`) 與空格相同,表示 diff 輸入應該是分支的尖端,但您也可以使用三點 (`...`) 來轉換第一個參數進入兩個差異輸入之間共享的共同祖先提交的引用 - 非常有用!如果只想跨分支比較單個文件,只需將文件名作為第三個參數傳遞。 您可能希望查看在給定日期範圍內所做的所有更改,為此使用 `git diff HEAD@{7.day.ago} HEAD@{0}`(上週),同樣可以將其與文件名、分支名稱、特定提交或任何其他參考。 還有 [`git range-diff`](https://www.git-scm.com/docs/git-range-diff) 命令,它提供了一個用於比較提交範圍的簡單界面。 git diff 工具還有更多功能(以及使用您自己的差異檢查器的選項),因此我建議查看 [文檔](https://git-scm.com/docs/git-diff#_description) . --- ## Git Hooks > 使用 [`hooks`](https://git-scm.com/docs/githooks) 在給定的 get 操作發生時執行命令或執行腳本 Hooks 可以讓你自動化幾乎所有的事情。例如:確保滿足標準(提交訊息、分支名稱、補丁大小)、程式碼質量(測試、lint)、將附加訊息附加到提交(用戶、設備、票證 ID)、呼叫 webhook 來記錄事件或執行管道等 對於大多數 git 事件,如 commit, rebase, merge, push, update, applypatch 等,都有前後 [hooks available](https://git-scm.com/docs/githooks)。 鉤子存儲在 `.git/hooks` 中(除非您使用 `git config core.hooksPath` 在其他地方配置它們),並且可以使用 [`git hook`](https://git-scm.com/docs) 進行測試/git-hook) 命令。由於它們只是 shell 文件,因此可用於執行任何命令。 掛鉤不會推送到遠程存儲庫,因此要在您的團隊中共享和管理它們,您需要使用 [掛鉤管理器](https://github.com/aitemr/awesome-git-hooks#tools) ,例如 [lefthook](https://github.com/evilmartians/lefthook) 或 [husky](https://github.com/typicode/husky)。還有幾個[3rd-party tools](https://githooks.com/#projects),這使得管理鉤子更容易,我推薦[overcommit](https://github.com/sds/overcommit)。 請記住,掛鉤總是可以跳過(使用 `--no-verify` 標誌),所以永遠不要純粹依賴掛鉤,尤其是對於任何與安全相關的事情。 --- ## Git Blame > 使用 [`git blame`](https://git-scm.com/docs/git-blame) 顯示特定修訂版和行的作者訊息 一個經典的,快速找出誰寫了特定程式碼行(也就是你的哪個同事應該為這個錯誤負責!)。但它也有助於確定在哪個時間點發生了某些更改並檢查該提交和關聯的元資料。 例如,要查看 index.rs 第 400 到 420 行的作者和提交訊息,您可以執行: ``` git blame -L 400,420 index.rs ``` --- ## Git LFS > 使用 [`git lfs`](https://git-lfs.github.com/) 存儲大文件,以免拖慢您的存儲庫 您的專案通常會包含較大的文件(例如資料庫、二進制資產、檔案或媒體文件),這會減慢 git 工作流程並使使用限制達到最大。這就是 [大型文件存儲](https://git-lfs.github.com/) 的用武之地 - 它使您能夠將這些大型資產存儲在其他地方,同時使它們可以通過 git 進行跟踪並保持相同的存取控制/權限。 LFS 的工作原理是將這些較大的文件替換為在 git 中跟踪的文本指針。 要使用它,只需執行 `git lfs track <file glob>`,這將更新您的 `.gitattributes` 文件。您可以通過擴展名(例如“*.psd”)、目錄或單獨指定文件。執行 git lfs ls-files 以查看跟踪的 LFS 文件列表。 --- ## Git GC > 使用 [`git gc`](https://git-scm.com/docs/git-gc) 優化您的存儲庫 隨著時間的推移,git repos 會積累各種類型的垃圾,這些垃圾會佔用磁盤空間並減慢操作速度。這就是內置垃圾收集器的用武之地。執行 `git gc` 將刪除孤立的和不可存取的提交(使用 [`git prune`](https://git-scm.com/docs/git-prune)),壓縮文件修訂和存儲的 git 物件,以及一些其他一般的內務管理任務,如打包引用、修剪引用日誌、尊重元資料或陳舊的工作樹和更新索引。 加入 `--aggressive` 標誌將 [積極優化](https://git-scm.com/docs/git-gc#_aggressive) 存儲庫,丟棄任何現有的增量並重新計算它們,這需要更長的時間執行但如果你有一個大型存儲庫可能需要。 --- ## Git Show > 使用 [`git show`](https://git-scm.com/docs/git-show) 輕鬆檢查任何 git 物件 以易於閱讀的形式輸出物件(blob、樹、標籤或提交)。要使用,只需執行 `git show <object>`。您可能還想附加 `--pretty` 標誌,以獲得更清晰的輸出,但還有許多其他選項可用於自定義輸出(使用 `--format`),因此此命令對於準確顯示非常強大你需要什麼。 這非常有用的一個實例是在另一個分支中預覽文件,而無需切換分支。只需執行 `git show branch:file` --- ## Git Describe > 使用 [`git describe`](https://git-scm.com/docs/git-describe) 查找可從提交中存取的最新標記,並為其指定一個人類可讀的名稱 執行 `git describe`,您將看到一個人類可讀的字串,該字串由最後一個標籤名稱與當前提交組合而成,以生成一個字串。您還可以將特定標籤傳遞給它, 請注意,您必須已建立標籤才能使其正常工作,除非您附加了 `--all` 標誌。默認情況下,Git describe 也只會使用帶註釋的標籤,因此您必須指定 `--tags` 標誌以使其也使用輕量級標籤。 --- ## Git Tag > 使用 [`git tag`](https://git-scm.com/docs/git-tag) 在你的 repo 歷史中標記一個特定點 能夠[標記](https://git-scm.com/book/en/v2/Git-Basics-Tagging) 存儲庫歷史記錄中最常用於表示發布版本的特定重要點通常很有用。建立標籤就像 `git tag <tagname>` 一樣簡單,或者您可以使用 `git tag -a v4.2.0 <commit sha>` 標記歷史提交。與提交一樣,您可以使用“-m”在標籤旁邊包含一條訊息。 不要忘記使用 `git push origin <tagname>` 將您的標籤推送到遠程。 要列出所有標籤,只需執行 `git tag`,並可選擇使用 `-l` 進行通配符搜尋。 然後,您將能夠使用 `git checkout <tagname>` 檢出特定標籤 --- ## Git Reflog > 使用 [`git reflog`](https://git-scm.com/docs/git-reflog) 列出對您的存儲庫所做的所有更新 Git 使用稱為參考日誌或“reflogs”的機制跟踪分支尖端的更新。跟踪各種事件,包括:克隆、拉取、推送、提交、檢出和合併。能夠找到事件引用通常很有用,因為許多命令都接受引用作為參數。只需執行 `git reflog` 即可查看 `HEAD` 上的最近事件。 reflog 真正有用的一件事是恢復丟失的提交。 Git 永遠不會真正丟失任何東西,即使是在重寫歷史時(比如變基或提交修改)。 Reflog 允許您返回提交,即使它們沒有被任何分支或標記引用。 默認情況下,reflog 使用 `HEAD`(您當前的分支),但您可以在任何 ref 上執行 reflog。例如 `git reflog show <branch name>`,或者使用 `git reflog stash` 查看隱藏的更改。或者使用 `git reflog show --all` 顯示所有引用 --- ## Git Log > 使用 [`git log`](https://git-scm.com/docs/git-log) 查看提交列表 您可能已經熟悉執行 `git log` 來查看當前分支上最近提交的列表。但是您可以使用 git log 做更多的事情。 使用 `git log --graph --decorate --oneline` 將顯示一個漂亮整潔的提交圖以及 ref 指針。 ![示例 git 日誌輸出](https://i.ibb.co/c1WByg8/Screenshot-from-2022-12-17-20-43-56.png) 您還經常需要能夠根據各種參數過濾日誌,其中最有用的是: - `git log --search="<anything>"` - 搜尋特定程式碼更改的日誌 - `git log --author="<pattern>"` - 只顯示特定作者的日誌 - `git log --grep="<pattern>"` - 使用搜尋詞或正則表達式過濾日誌 - `git log <since>..<until>` - 顯示兩個引用之間的所有提交 - `git log -- <file>` - 顯示僅對特定文件進行的所有提交 或者,只需執行 `git shortlog` 以獲得匯總的提交列表。 --- ## Git Cherry Pick > 使用 [`git cherry-pick`](https://git-scm.com/docs/git-cherry-pick) 通過引用選擇指定的提交並將它們附加到工作 HEAD 有時你需要從其他地方拉一個特定的提交到你當前的分支。這對於應用熱修復、撤消更改、恢復丟失的提交以及在某些團隊協作設置中非常有用。請注意,通常傳統的合併是更好的做法,因為挑選提交會導致日誌中出現重複提交。 用法很簡單,只需執行 `git cherry-pick <commit-hash>`。這會將指定的提交拉入當前分支。 --- ## Git Switch > 使用 [`git switch`](https://git-scm.com/docs/git-switch) 在分支之間移動是我們經常做的事情,`switch` 命令就像是`git checkout` 的簡化版本,它可以用來建立和在分支之間導航,但不像 checkout 在分支之間移動時不會復制修改的文件. 類似於 `checkout -b`,使用 switch 命令你可以附加 `-c` 標誌來建立一個新分支,然後直接跳入其中,例如`git switch -c <新分支>`。執行 `git switch -` 將放棄您所做的任何實驗性更改,並返回到您之前的分支。 --- ## Git Standup > 使用 [`git standup`](https://github.com/kamranahmedse/git-standup) 回憶你在最後一個工作日做了什麼,基於 git 提交 我把它放在最後,因為它不包含在大多數 git 客戶端中,但是您可以使用系統包管理器[輕鬆安裝](https://github.com/kamranahmedse/git-standup#install) ,使用 1 行 curl 腳本,或從源程式碼建置。 如果您的老闆要求您每天站立一次,以更新昨天的工作,但您永遠記不起自己到底做了什麼——這個適合您!它將顯示一個格式良好的列表,列出在給定時間範圍內完成的所有事情。用法很簡單,只需執行 `git standup`,或使用 [這些選項](https://github.com/kamranahmedse/git-standup#options) 指定應顯示哪些資料(作者、時間範圍、分支機構等)。 --- ## 結論 希望對您有幫助!

寫文件基本技巧:如何替專案寫一份優質 README 文件

為您的開源專案提供良好的文檔是一項重要(且經常被忽視)的功能,可以促進採用並展示您的軟體的全部潛力。 不幸的是,文檔的增長速度通常比程式碼慢得多,主要是因為一些看起來相當簡單的實現,會產生大量可能的用例和變化。不可能涵蓋所有可能的場景,這就是為什麼技術作家的首要工作是確定範圍和確定優先級。關注基本知識非常重要,必須首先記錄以支持最常見的用例。 在這篇文章,我將分享一些技巧,為您的專案打造一個好的 README 文件。 原文出處:https://dev.to/erikaheidi/documentation-101-creating-a-good-readme-for-your-software-project-cf8 ## README 檔案 專案的 README 文件通常是用戶與您的專案的第一次接觸,因為這是他們在訪問您的專案時首先看到的內容。這就是為什麼優先考慮將好的 README 作為專案文檔的起點很重要。 自然地,不同的專案在 README 中有不同的東西要展示,但這些技巧應該作為大多數軟體專案的良好起點。 ## 1. 少即是多 你可能想把所有東西都放在你的 README 中,比如如何安裝和使用項目,如何部署,如何調試......更詳細地涵蓋這些主題的更完整文檔的鏈接。 當您開始時,只有一個 README 就可以了。很長的 README 沒有吸引力,因為沒有目錄或菜單可供導航,因此更難找到訊息,這最終不利於良好的用戶體驗。鏈接到相關資源的較短的自述文件使專案看起來更有條理且不那麼複雜。 如果我不想為這個專案創建一個專門的文檔網站怎麼辦?那麼,在這種情況下,您可以考慮在根目錄中創建一個 `docs` 文件夾,您可以在其中保存額外的 markdown 文檔,這些文檔可以直接從您的代碼託管平台(假設是 GitHub)瀏覽。 ## 2. 將 README 拆分為其他文檔 對於存儲庫中的文檔,您可以在應用程式的根目錄中創建一個“/docs”目錄,並使用“/docs/README.md”文件作為文檔的入口點或索引。 此文件夾的內容大概就像: - installation.md - 詳細顯示如何安裝項目的文檔。 - usage.md - 項目使用情況和主要命令的更詳細視圖。 - advanced.md - 包含一些進階使用選項和用例的文檔。 這些只是一些可以作為起點的想法。如果您覺得需要創建一個包含子文件夾的更複雜的結構,您應該認真考慮為您的項目創建一個專門的文檔網站(我們將在本系列的後續文章中介紹)。 ## 3. README 文件要點 以下是您的 README 文件中絕對應該包含的一些內容: - 項目的大致概述,包括編寫它的語言、它的作用、它為什麼有用; - 安裝要求; - 安裝文檔的鏈接; - 使用概述,讓用戶簡要了解如何執行它; - 故障排除或測試提示(可以是指向單獨文檔的鏈接); - 連接到其他資源以了解更多訊息。 理想情況下,這些應該是簡短的說明,可在必要時鏈接到更全面的文檔。 根據項目的規模和目標,您應該考慮將其他內容放在那裡: - 指向 CONTRIBUTING.md 文檔的鏈接,其中包含有關用戶如何為您的專案做出貢獻的詳細訊息 - 指向包含項目行為準則的 CODE_OF_CONDUCT.md 文檔的鏈接。 如果您的項目託管在 GitHub 上,這些將顯著顯示在右側欄的項目頁面中,就在“關於”部分的正下方。 ### 示例結構 以下是 markdown 的一般結構,您可以將其用作構建專案自述文件的基礎: ``` # Project Name A paragraph containing a high-level description of the project, main features and remarks. ## Requirements Here you should give a general idea of what a user will need in order to use your library or application. List requirements and then link to another resource with detailed installation or setup instructions. - Requirement one - Another requirement Check the [installation notes]() for more details on how to install the project. ## Usage Include here a few examples of commands you can run and what they do. Finally link out to a resource to learn more (next paragraph). For more details, check the [getting started guide](). ## Useful Resources Include here any other links that are relevant for the project, such as more docs, tutorials, and demos. ``` ## 4. 使用徽章 您可以使用徽章通過自動從專案中提取的快速訊息來豐富您的 README,例如最新構建的狀態、最新的穩定版本、專案許可證等。 有不同的服務可以為開源專案提供徽章。正如@mohsin 在這篇文章的評論部分所指出的,您可以直接從 GitHub Actions 中提取徽章,方法是轉到您的工作流程頁面,單擊右上角顯示的三個點,然後從中選擇“創建狀態徽章”菜單: ![屏幕截圖顯示在哪裡可以找到菜單以從 github 操作創建狀態徽章](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bpb6g6xofhwm8vctwcem.png) 這將向您顯示一個帶有降價代碼的對話框,您可以將其複製並貼上到您的 README 文件中。 另一個不錯的選擇是使用網站 [Shields.io](https://shields.io/),它提供了幾種不同的徽章,您可以在您的開源項目中免費使用。 例如,這是顯示最新版本 [yamldocs](https://github.com/erikaheidi/yamldocs) 的圖像 URL: ``` https://img.shields.io/github/v/release/erikaheidi/yamldocs?sort=semver&style=for-the-badge ``` 這會生成以下徽章,顯示最新版本: ![yamldocs 的最新穩定版本](https://img.shields.io/github/v/release/erikaheidi/yamldocs?sort=semver&style=for-the-badge) 這是帶有多個徽章的 README 示例: ![顯示來自 yamldocs 項目自述文件的徽章](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5frlxoex4fyke8ra1avf.png) ## 結論 文檔是任何軟體專案的重要組成部分,應該從一開始就認真對待。最好的開始方式是創建一個好的自述文件,向用戶顯示基本信息,而不是用他們可能不需要的內容來淹沒他們,以便開始使用您的專案。

2023 前端框架比較:Svelte vs React,該學哪一個呢?

在 Web 開發世界中,有時感覺就像每天都有新的前端框架問世!大多數來去匆匆,但有一件事是肯定的:Svelte 將繼續存在。 不過,這並不意味著您應該放下一切並在今天學習!追逐最新潮流會讓您分心和不知所措。 這篇文章將一勞永逸地回答:**我應該學習 React 還是 Svelte?**。 您將看到一些程式碼範例,這些範例解釋了為什麼 React 開發人員會為 Svelte 瘋狂,但我們也必須實際一點。 React 已經存在了很長時間。有更多的套件、支援、職缺。 Svelte 還能取代 React 嗎?讓我們找出答案! - 原文出處:https://dev.to/mikehtmlallthethings/svelte-vs-react-which-framework-to-learn-in-2023-50gf --- * 📍 什麼是 React? * 📍 什麼是 Svelte? * 📍 React 和 Svelte 的 5 個區別 * Svelte 的捆綁包尺寸更小 * Svelte 更容易學習 * Svelte 使用純 HTML、CSS 和 JavaScript 進行編譯 * React 有更多的套件 * React 有 React Native * 📍 React 是庫還是框架? * 📍逐行比較 React 和 Svelte 專案 * 📍 Svelte 比 React 快嗎? * 📍 何時從 React 切換到 Svelte * 📍 結論 ### **What is React?** 讓我們從 React 開始。 React 是一個漸進式 JavaScript 前端框架(或函式庫,具體取決於您詢問的對象),可幫助您構建複雜的 Web UI。 它由 Facebook(現為 Meta)於 2013 年創建,能夠很快在前端 Web 開發領域站穩腳跟。 React 的核心是狀態和渲染狀態,這意味著要使用它,您必須添加其他庫來處理客戶端功能和路由。 ### **What is Svelte?** Svelte 也是一個前端 JavaScript 框架,但採用了更加一體化的方法。 Svelte 具有內建的狀態管理、路由和客戶端 (DOM) 功能。 ![](https://scrimba.com/articles/content/images/size/w1600/2022/12/React-vs-Svelte-functionalities.png) React 需要第三方庫和工具,如 Redux、React Router、JSX,而 Svelte 內建了很多這樣的功能。它不太靈活,但更方便和一致。 它採用更幕後(魔術)風格的方法,它直譯非常基本的 JavaScript 程式碼並為您處理 UI 和狀態管理: ``` <script> let count = 0; function handleClick() { count += 1; } </script> <button on:click={handleClick}> Clicked {count} {count === 1 ? 'time' : 'times'} </button> ``` Svelte 由紐約時報的開發人員 Rich Harris 於 2016 年創建,用於以高效的方式處理複雜的圖表和圖形。它從那裡成長為 React 和 Vue 之類的備受喜愛的競爭對手。 ### **React 和 Svelte 之間的 5 個區別** ### **1。 Svelte 的構建包大小要小得多** 我們在下面構建的相同(功能)應用程序。部署包大小在 React 是 41.2 kB,在 Svelte 是 2.1 kB。這幾乎減少了 **20x** 🤯 為了獲得這些數字,我構建了一個在 Svelte 和 React 中具有相同功能的應用程序。我們將在 React 與 Svelte 代碼分解部分深入研究這些應用程序。 ![](https://scrimba.com/articles/content/images/size/w1600/2022/12/React-vs-Svelte-bundle-size-2.png) 我用 React 和 Svelte 構建了一個相同的應用程序。看看 Svelte 包小了多少! ### **2。 Svelte 更容易學習,因為它的語法簡單** Svelte 採用更幕後的魔術方法,允許您編寫非常少量的樣板或語法糖來完成複雜的綁定。模板語法只是帶有一些額外內容的 HTML,這與 JSX(React 等價物)有很大不同並且更容易學習。 React 變數宣告: ![](https://scrimba.com/articles/content/images/size/w1600/2022/12/React-_-React-vs-svelte_-reactive-variable-declaration.png) Svelte 變數宣告: ![](https://scrimba.com/articles/content/images/size/w1600/2022/12/Svelte-_-React-vs-svelte_-reactive-variable-declaration.png) Svelte 看起來像純 JavaScript,但它具有與 React 完全相同的功能。更新 Svelte 變數將自動更新它所在的 UI 元素。 ### **3。 Svelte 符合純 HTML、CSS 和 JavaScript** Svelte 將您編寫的程式碼編譯成基本的 HTML、CSS 和 JavaScript。它不需要像 React 那樣與你的代碼捆綁在一起! React.js 需要存在於一個 bundle 中以完成所有正確的虛擬 DOM 比較和創建,Svelte 不使用虛擬 DOM 來處理 UI。相反,它選擇了基本的 JavaScript 元素創建函數,例如 document.createElement。 ### **4。 React 擁有更多為它構建的庫和包** React 已經存在了 3 年多,也是目前 JavaScript 框架事實上的王者👑。正因為如此,它擁有大量用戶和公司創建的軟件包。 用戶創建的包通常只是為了使路由和狀態管理更容易,或者添加滑塊、燈箱等。這些並不重要,因為 Svelte 具有可靠的選項,並且兼容/適應大多數 JavaScript 套件。 有點困難的是,要跟任何其他框架之前創建的 React 套件整合時不容易。我在 Solana 和以太坊上從事 Web3 專案時經常遇到這個問題。 ### **5。 React 有 React Native** React Native 是使用率最高和受支持最多的跨平台框架之一。它提供了使用 React 創建 iOS 和 Android 應用程式的能力。全部來自同一個代碼庫。由於其成熟度,它擁有大量的庫、支援和學習資源。 儘管有 Svelte 的替代方案,例如稱為 Svelte-native 的 NativeScript 改編版,但它們不具有與 React-native 相同的可靠性和功能。 ### **React 是函示庫還是框架?** 儘管 React 通常被稱為框架,但可以說,由於其範圍,它更像是一個函式庫。它專門負責管理 UI 的狀態並使其與應用程式中的資料狀態保持同步。 因此,它需要第 3 方函式庫來處理應用程式路由 (React Router)、UI 創建 (JSX) 和元件之間的狀態管理 (Redux)。 另一方面,Svelte 內建了上述所有功能,因此更像是一個完整的 UI 管理解決方案。 你可以看到大多數人都同意這是一個函式庫,但仍有一些爭論👇 https://twitter.com/htmleverything/status/1597574223148765185 ### **逐行比較 React 和 Svelte 專案** 比較兩種 Web 技術的最佳方法是深入研究並使用它們進行構建。構建完全相同的應用程序有助於了解每個庫/框架如何處理不同的功能。 讓我們看看: * 條件渲染 * 模板循環 * 更新狀態 * 事件掛鉤 ### **我們在建造什麼?** 編碼是一項口渴的工作,因此我們將構建一個簡單的網絡應用程序,允許用戶跟踪他們全天喝了多少杯水(或🍺)。 額外的好處是顯示每杯喝醉的歷史和時間。 我們將保持 UI 簡單,以更多地關注底層框架。 (見下面的用戶界面) https://codesandbox.io/embed/react-water-example-scrimba-ny5q0m?fontsize=14&hidenavigation=1&theme=dark ### **React** 為了分解代碼,首先讓我們深入了解一些 React 概念和術語👇 React 有幾種類型的語法你需要學習。鉤子、狀態和模板 (JSX) 是主要的。 鉤子 - 允許您進入應用程序的生命週期 State - 允許您根據數據的變化更新 UI 元素。它將“狀態”(或更簡單的變量)更改與 UI 更新聯繫起來 模板 - 允許您直接在 HTML 中使用變量和 JavaScript React 組件的樣式通常由單獨的 .css(或 .scss)文件處理。 ### **React 代碼分解** https://codesandbox.io/embed/react-water-example-scrimba-ny5q0m?fontsize=14&hidenavigation=1&theme=dark&view=editor 變數是使用 useState 掛鉤設置的,它允許更新變量並讓 UI 動態呈現這些更新。 `useEffect` 用於在加載應用程序時設置今天的日期。 JSX 模板使用基本的“{}”符號以及 HTML 中的標準 JavaScript 函數,允許顯示變量和循環數組(使用“.map”)。 ### **Svelte** Svelte 採用不同的方法,採用更“幕後魔術”的風格。邏輯看起來很像純 JavaScript。在後台,代碼做的事情幾乎與 React 代碼做的一樣。 Svelte 仍然有像 `onMount` 和 `onDestroy` 這樣的鉤子,但是簡單地分配一個變量並讓它完全響應並在模板 (HTML) 中可訪問不需要任何特殊的語法糖。 另一個很大的區別是您可以直接在 Svelte 組件中編寫 CSS/SCSS。這只是一個選項,因為您仍然可以像在 React 中一樣導入樣式,但我注意到大多數 Svelte 項目都使用樣式內組件。 ### **Svelte 代碼分解** https://codesandbox.io/embed/svelte-water-example-scrimba-2vsoid?fontsize=14&hidenavigation=1&module=%2FApp.svelte&theme=dark&view=editor 上面的代碼實例化了一個 cupsOfWater 數組,將新的日期變量設置為當前日期。 聲明一個函數來創建一個新日期並將其存儲在一個名為 cup 的變量中,然後將其添加到 cupsOfWater 數組中。 模板部分更接近 HTML 並增加了一些功能。再次使用“{}”表示法,您可以從“<script>”部分引用任何聲明的變量。您還可以使用事件偵聽器(如 `on:click`)、條件(如 `{#if}`)和使用 `{#each}` 循環。 ### **Svelte 比 React 快嗎?** 是的,從快速的 HTML 生成到更快的構建和開發環境,Svelte 的性能都大大優於 React。 * 生成 HTML * 根據狀態更新 UI * 第一次內容豐富的渲染 * 互動時間 * 速度指數 所有這些都看到了可衡量的差異,而 Svelte 具有優勢。您的應用程序越大越複雜,差異就越明顯。 在 Zeitspace 的一篇文章中可以看到性能比較 https://www.zeitspace.com/blog/we-built-an-app-with-svelte.-heres-what-we-learned ### **Svelte 比 React 好嗎?** 當開始一個新專案時,Svelte 有足夠的優勢,它應該始終是一個考慮因素。 話雖如此,React 在使用率方面仍然絕對勝過 Svelte。這可能會導致專案的第 3 方插件支持、僱用和壽命問題。 不過,為了應對這一點,Svelte 語法的易用性使其非常容易上手,尤其是對於 React 開發人員而言。這是公司在招聘 Svelte 項目時可以藉鑑的東西(不要將自己局限於 Svelte 開發人員)。 ### **何時從 React 切換到 Svelte** Svelte 是構建複雜網站或 Web 應用程序的絕佳選擇。許多老牌公司已經開始將 Svelte 用於內部和外部應用程序: * 1Password * Avast * Chess.com * Alaska Airlines * Fusion Charts * Rakuten * GoDaddy * IBM * Square * 紐約時報 * 飛利浦 但這並不意味著您必須將當前的 React 應用程序放入垃圾桶! 那麼什麼時候是接觸 Svelte 的合適時機? 如果您的應用/網站: * 由於頻寬限制,需要較小的包大小 * 需要盡可能快 * 需要快速建造 When is not the right time to reach for Svelte? 什麼時候不適合使用 Svelte? 如果您的應用/網站: * 嚴重依賴第 3 方集成/工具 * 需要轉換為移動應用程序 這些很快就不會成為問題,但在投入之前確實需要進行一些研究和盡職調查。 ### **結論** 建議投入其中並嘗試在 Svelte 中構建一些東西。如果你來自 React,我幾乎可以向你保證你會喜歡它的簡單性和速度。

寫 React 時必備的幾個 VS Code Extensions:新手推薦

來看看一些對 React 開發人員最有用的 VS Code 外掛吧! - 原文網址:https://dev.to/devland/vs-code-extensions-you-should-use-as-a-react-developer-2f6i ## ES7 React/Redux/GraphQL/React-Native snippets ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qoxlb7rz6gzkx906xfr5.jpg) 最流行的外掛之一,由 React 開發人員提供,也由 React-Native 開發人員參與。它帶有許多速記前綴,您可以輕鬆使用它來加快開發過程。 這個外掛提供了很多你可能不知道的功能。一旦你安裝了這個驚人的外掛,創建一個新文件並輸入 rfce 然後按回車鍵,這將生成一個 React 功能組件,導入 React 並導出元件。 ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8m942g0szndpv3bwprrb.jpg) 它還允許您在幾秒鐘內創建不同的 es7 片段,只需輸入前綴簡寫並按 enter。 此外,如果您使用的是 Redux 或 GraphQL,此外掛也為它們提供了程式碼片段。 ## VSCode React Refactor ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aa1etaf6lasubpmsjxgf.jpg) 簡單,但非常有用。允許您將 JSX 部分提取到新元件、文件等。使用類別、函數和箭頭函數並支持 TypeScript 和 TSX。 ## Prettier ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7tddr5birva6pja6ygoa.jpg) 經過多年使用 Prettier,我認為它是任何專案的都好用的外掛。這是一個自動為你格式化程式碼的工具。它有助於保持程式庫的一致性,因為無論團隊中的開發人員有什麼個人偏好,所有程式碼都將以相同的方式格式化。 ## Eslint ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6l039819s4qx6ngf0e8i.jpg) 用於查找程式碼中的錯誤和缺陷。它可以幫助開發人員編寫沒有錯誤和警告的優質程式碼。 此外,它可以自動修復錯誤和警告。 ## Stylelint ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ufskyyg4id7ets3rcjnt.jpg) 和ESLint類似,也是一個linter,但是針對樣式。它可以檢測並突出顯示不正確的樣式,並有助於保持樣式一致和有序。更重要的是,它適用於純 CSS 以及 SCSS 和 LESS 等預處理器。 ## GitLens ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6wmh3we9qrykvxari4mo.jpg) 增強了 Visual Studio Code 中內置的 Git 功能。它可以幫助您通過 Git 責備註釋和 code lens 一目了然地可視化代碼作者身份,無縫導航和探索 Git 存儲庫。 ## Git History ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nzsboqxicv3bs8f0n7p1.jpg) 允許您查看 git 日誌和文件歷史記錄,並比較分支或提交。 ## Settings sync ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iphz26rbvb85pnuzcijf.jpg) 您是否曾經重新安裝作業系統或更改您編寫程式碼的設備、繼續安裝 VS Code、然後發現您需要重新安裝所有外掛?它可以自動保存你的外掛和 VS Code 設置,然後在另一台設備上安裝和配置它們。 ## Bracket Pair Colorization Toggler ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xw0embc8ohxzmaw54fq.jpg) 非常簡單但有用的擴展。突出顯示匹配的括號對。 ## Auto Close Tag ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yda8pr1303sn1kdzwoz8.jpg) 一個簡單但最有用的 React 外掛之一。它所做的是一件非常簡單的事情。 Auto close tag,顧名思義,為元素創建一個結束標籤,這意味著開發人員不需要編寫結束標籤。這可能看起來很簡單,但實際上,自動關閉標籤非常有用。 ## Auto Rename Tag ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7kjq4bz8u1ccgxgk2w9t.jpg) 自動重命名成對的 HTML/XML 標籤。 ## Auto Import ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zy56itc3bb5jvecscf2v.jpg) 自動為所有可用導入查找、解析並提供代碼操作和代碼完成。適用於 TypeScript 和 TSX。 ## Import Cost ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4wxw0io8difxgthdan5c.jpg) 在 React 中,安裝和導入套件是非常常見和必要的。導入大量套件可能會導致性能問題,因為其中一些包可能很重。此外掛在編輯器中顯示套件的大小。 ## Jumpy ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cp8cldekpyxyesyz1o8j.jpg) 您通常如何從一行程式碼轉到幾行和空格之外的特定關鍵字?多次使用鍵盤箭頭或單擊滑鼠?使用 Jumpy,您可以更有效率,因為它可以讓您快速跳轉到特定單詞。 ## i18n Ally ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jmqx39hkds4lbeoytb1p.jpg) 如果您的應用程序支持多種語言,就非常好用。 Formatting toggle ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fhhj774y6xeapll2tomq.jpg) 在某些情況下,我們希望暫時禁用像 Prettier 這樣的代碼格式化程序。這可以通過 Formatting toggle 外掛來完成,無需修改編輯器設置。 ## Npm intellisense ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/75wl3nmlkporzfsnxl6g.jpg) 為導入語句中的 npm 模塊提供自動完成功能。 ## Web Accessibility ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i3lni8zqwdh4ngwyk1rm.jpg) 用於提高 Web 應用程序可訪問性的出色插件。它突出顯示了您應該考慮更改的元素,還提供了有關如何更新它們的提示。 ## Live Share ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/74okun8atu01lphpjo7c.jpg) 您願意與其他人協作編寫您的代碼嗎? 此外掛使您能夠與他人實時編輯和調試代碼。 ## Better comments ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/odj7yo1a5sntmhkl4x57.jpg) 用於在您的代碼中創建更人性化的註釋。它可以將評論分類為警報、查詢、待辦事項和突出顯示,並以不同的顏色顯示它們。 ## Docker ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/patpizcxw2hs6gu823em.jpg) 如果您的應用程序是使用 Docker 部署的,您可以考慮使用來簡化構建、管理和部署來自 VS Code 的容器化應用程序。 ## Remote — SSH ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kk6amn6yubsmio7uen68.jpg) 您是否需要訪問服務器才能遠程編輯文件?遠程 SSH 讓您可以使用任何帶有 SSH 服務器的遠程機器作為您的開發環境。您可以輕鬆地在遠程和本地開發環境之間切換。 ## WSL ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2kd4n337eomix1ba0tn7.jpg) 如果您更喜歡在 Linux 上開發您的應用程序,但您的主要操作系統是 Windows,您可以考慮使用 Windows 子系統 Linux (WSL)。如果這樣做,那麼您可能會發現 WSL 擴展很有用,因為它可以讓您在 Windows 上使用 Vs Code構建 Linux 應用程序。在使用基於 Linux 的工具、運行時和實用程序進行開發時,您可以獲得 Windows 的所有生產力。 ## 實時服務器 ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rzaylae1618ndvty1agf.jpg) 如果您需要在文件更改時通過實時瀏覽器重新加載來快速啟動實時服務器,很推薦。 ## Debugger for Chrome and Debugger for Firefox ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5hqzk58hdihl2syoctg5.jpg) 調試器提供了許多有用的功能,例如在斷點處暫停代碼執行、變量檢查等。這些擴展提供了 VS Code 編輯器內部的調試功能。 ## Change-case ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qeoqoevy2a6d646ht1ir.jpg) 顧名思義,此擴展允許您更改當前選擇或當前單詞的大小寫。如果您有很長的文本或想將多個變量轉換為相同的大小寫,這將非常有用。 ## Regex Previewer ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pr4eesyhl5bpj0afhhll.jpg) 大多數開發人員很少編寫 Regex 表達式。但是,如果必須,此擴展可能會非常方便。它在並排文檔中顯示當前正則表達式的匹配項。 ## DotENV ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/19cpgt5rvygiysu87qi8.jpg) _.env_ 文件的語法突出顯示。 ## 結論 希望對您有幫助!

德國資深架構師:給新手工程師的幾點建議

一名資深的德國軟體架構師 Jeroen De Dauw,寫了一篇很好的文章,給新手工程師一些寫程式的建議。 - 原文出處:https://dev.to/jeroendedauw/advice-for-junior-developers-30am --- ## 給新手工程師的一般建議 ### 1. 程式碼不是重點 作為開發者,我們喜歡寫程式。大多數工程師希望收到的任務明確,可以不用管技術之外的事情,專心解決有趣的技術挑戰。 請花足夠的心力去確認,您正在解決正確的問題。引用管理學大師 Peter Drucker 的話:高效率地去做一件根本沒必要的事情,結果依然是完全沒意義。儘早、經常去搜集回饋,透過「持續交付」來向真正的用戶互動,成為敏捷(Agile)的工程師。 軟體開發成本高昂,現實世界專案的絕大部份工作都是在維護而已。再加上目標應該是對用戶、對生意有幫助,所以結論就是:寫程式最好的方法,經常是完全不寫。引用比爾蓋茲的話:用程式碼有幾行來衡量工程進度,就像用重量來衡量飛機的製造進度。 另請參閱:YAGNI 原則、KISS 原則、The Last Responsible Moment 文章。 ### 2. 軟體設計很重要 在我開發生涯的前五年,我以為軟體設計是架構師或其他特殊職位的人在做的事。我以為開發者專注在完成任務即可,以為軟體設計、最佳實踐、寫測試這些,都不關我的事。我的程式能跑,我的生產力很高,我以為這樣就對了。 直到我閱讀了 Robert C. Martin 的 Clean Code,這書刺激了我對軟體設計的關注,並包含許多範例與啟發。其中最啟發我的是:走得快的唯一方法,就是走得好。也就是說,如果你把事情搞得一團糟,結果只會讓你速度更慢。 學習寫出設計良好的乾淨程式碼,需要時間和精力。而且剛開始的時候,會寫比較慢,並且會犯錯誤。 ### 3. 使用最佳實踐 寫測試通常會有幫助。雖有例外,但大多數時候,寫自動化測試會大有幫助。寫測試就是一種最佳實踐。 如果你不太會寫測試,請遵循最佳實踐並為所有內容寫測試。**開始時,盲目遵循最佳實踐比遵循自己弱弱的判斷要好**。一段時間之後,您將知道怎麼寫測試比較有效,並能夠區分您搞砸了和不值得編寫測試的情況。因為 bug 變少了、重構起來更輕鬆了,您將開始理解測試帶來的深入的價值。**到有了自己的判斷力後,您將能夠超越最佳實踐**。 此建議適用於您在學習任何最佳實踐的新手時期。自動化測試只是一個例子。 有個陷阱要注意,明智的最佳實踐,與荒謬、適得其反的做法之間,只有一線之隔。因為大多數程式碼都很亂,而且大多數開發者(包括資深人員)不了解軟體設計的基礎知識,因此事情就更複雜了。有一個好的指導者很重要。除此之外,根據我自己的經驗,要小心只存在您的語言、框架社群的最佳實踐。尋找那些已經存在了幾十年的長青建議比較好。 --- ## 給新手工程師的技術建議 ### 4. 寫測試 寫自動化測試。也許在寫程式之前先寫測試,例如運用測試驅動開發(TDD)。這讓您可以輕鬆反覆驗證幾段程式是否正確,而不用一直手動跑測試、除錯。 > 你覺得先寫測試很煩嗎?但之後再忙著抓 bug 有比較好? 更重要的是,測試為您重構時提供了額外保障。你需要持續重構來保持程式乾淨。沒有可靠的測試保障,程式碼就可能越變越亂。 如果您的程式碼設計不佳,例如使用繼承進行重用,或使用靜態函數,則編寫測試會很困難。另一方面,如果您有遵循 SOLID 原則、沒有全局依賴項,那麼寫出好的測試並不困難。 設計好測試也很重要,因為糟糕的測試只會拖慢開發速度。避免將測試綁定到被測程式碼的實作細節或系統結構。 ### 5. 不要用繼承來做到程式碼重用 這是讓人以為是最佳實踐的其中一個反例。我的建議是:剛開始時,根本就不要用繼承來做到程式碼重用。這通常都幫助有限,而且帶來一大堆麻煩。請多用組合、少用繼承(關鍵字:composition over inheritance)。 ### 6. 寫出 OOP 程式碼 學習 SOLID 原則,避免寫出 STUPID 原則的程式碼 ( https://williamdurand.fr/2013/07/30/from-stupid-to-solid-code/ )。理解這些原則和反模式非常有價值。 創造一些真正的物件。只有靜態方法的類別,根本不算是物件導向。盡量避免完全使用靜態寫法。 ### 7. 寫出函數式程式碼 不要把函數式程式設計,跟指令式程式設計搞混了。 重點不是完全切換到函數式語言。而是學習使用函數式風格的優點。例如減少狀態、讓函數專心一件事。另請參閱:https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell ### 8. 程式碼稍微重複沒關係 將一大塊程式碼到處複製貼上當然很不好。有尊嚴的開發者很快就發現這一點,並開始遵循某種形式的:不重複自己原則 Don't Repeat Yourself (DRY)。不幸的是,對 DRY 的追求往往會導致過度工程和額外的複雜性。所以會有一條新原則:寫兩次原則 Write Everything Twice(WET)。也就是僅在第三次出現重複時,才動手改善重複段落。 ### 9. 型別、命名、註解 試著寫一些能夠表達自我的程式碼,避免寫註解。 > 每次寫註解時,都應該要皺一下眉頭,感受到自己的表達能力有點失敗。 —— Robert C. Martin 註解很危險,因為有可能說謊。程式碼可以不更新註解就修改,那一開始的註解就變錯誤了。這種情況下,註解不但沒幫助,還會誤導到別人。 要寫出能夠表達自我的程式碼: - **一個函數只做一件事** 因為只做一件事,就能給一個清楚的命名。 - **減少狀態** - **使用型別** 定義清楚的型別,加上跑測試,能讓系統更穩定。 - **減少混合型別** 避免可以同時是整數、布林值或字串的參數或回傳值。如果讓每個函數專心一件事,這自然會做到。 - **寫測試** 良好的全面測試,也同時會是程式碼的使用說明範例。 Robert C. Martin 的書 Clean Code 在命名和寫註解方面有提供一些很好的經驗法則。 --- 以上,希望對大家有幫助!