介紹完整的工具鏈
在本系列文章的最後兩篇中,我們將透過引導您完成構建示例案例研究工具鏈的過程,來鞏固您的工具知識。我們將從設定合理開發環境和部署轉換工具,一直到實際部署應用程式。在本文中,我們將介紹案例研究,設定開發環境,並設定程式碼轉換工具。
| 先決條件 | 熟悉核心HTML、CSS和JavaScript語言。 |
|---|---|
| 目標 | 透過完成一個完整的工具鏈案例研究來鞏固我們迄今為止所學到的知識。 |
工具和使用它們的組合方式實際上是無限的,您在本篇文章和下一篇文章中看到的僅僅是一種使用所介紹工具進行專案的方法。
注意:還值得重複的是,並非所有這些工具都需要在命令列上執行。當今許多程式碼編輯器(例如 VS Code)透過外掛對許多工具提供了整合支援。
介紹我們的案例研究
我們將在本文中建立的工具鏈將用於構建和部署一個小型網站,該網站顯示有關mdn/content儲存庫的資料,並從GitHub API獲取其資料。
工具鏈中使用的工具
在本文中,我們將使用以下工具和功能
- JSX,一套與React相關的語法擴充套件,允許您執行諸如在 JavaScript 中定義元件結構之類的事情。您無需瞭解 React 即可學習本教程,但我們已將其包含在內,以讓您瞭解如何將非原生 Web 語言整合到工具鏈中。
- 最新的內建 JavaScript 功能(截至撰寫本文時),例如
import。 - 有用的開發工具,例如Prettier用於格式化,以及ESLint用於程式碼風格檢查。
- PostCSS提供 CSS 巢狀功能。
- Vite用於構建和壓縮我們的程式碼,併為我們自動編寫大量配置檔案內容。
- GitHub用於管理我們的原始碼控制,以及最終部署我們的網站(使用 GitHub Pages)。
您可能不熟悉所有上述功能和工具,或者它們的作用,但不要驚慌——我們將在本文中逐一解釋每個部分。
工具鏈及其固有的複雜性
與任何鏈條一樣,工具鏈中包含的連結越多,它就越複雜,也可能越脆弱——例如,它可能更難配置,也更容易出現故障。相反,連結越少,工具鏈的彈性可能就越大。
所有 Web 專案都將有所不同,您需要考慮工具鏈中哪些部分是必要的,並仔細考慮每個部分。
最小的工具鏈是一個完全沒有連結的工具鏈。您將手動編寫 HTML,使用“原生 JavaScript”(意味著沒有框架或中間語言),並手動將其上傳到伺服器進行託管。
但是,更復雜的軟體需求可能會受益於使用工具來簡化開發過程。此外,您應該在部署到生產伺服器之前包含測試,以確保您的軟體按預期工作——這聽起來已經像一個必要的工具鏈。
對於我們的示例專案,我們將使用專門設計來幫助我們的軟體開發和支援軟體設計階段所做出的技術選擇的工具鏈。但是,我們將避免任何多餘的工具,目的是將複雜性降到最低。
檢查先決條件
如果您一直在關注前幾章,那麼您應該已經擁有大部分軟體。以下是您在繼續執行實際設定步驟之前應該擁有的內容。這些步驟只需執行一次,您無需在以後的專案中重複執行。
建立 GitHub 帳戶
除了我們將安裝的有助於我們工具鏈的工具之外,如果您希望完成本教程,則需要建立一個 GitHub 帳戶。但是,您仍然可以在沒有它的情況下完成本地開發部分。如前所述,GitHub 是一種原始碼儲存庫服務,它添加了社群功能,例如問題跟蹤、專案釋出跟蹤等等。在下一章中,我們將推送到 GitHub 程式碼儲存庫,這將產生級聯效應,(應該)將所有軟體部署到 Web 上的某個位置。
如果您還沒有帳戶,請點選主頁上的註冊連結,註冊GitHub,並按照說明操作。
安裝 git
我們將安裝另一個軟體 git,以幫助進行版本控制。
您可能以前聽說過“git”。Git是目前開發人員可用的最流行的原始碼版本控制工具——版本控制提供了許多優勢,例如將您的工作備份到遠端位置的方法,以及在團隊中協同處理同一個專案而不必擔心覆蓋彼此程式碼的機制。
對於某些人來說,這可能很明顯,但值得重複的是:Git 與 GitHub 不一樣。Git 是版本控制工具,而GitHub是 git 儲存庫的線上儲存庫(以及一些用於處理它們的實用工具)。請注意,雖然我們本章使用的是 GitHub,但還有其他幾種選擇,包括GitLab和Bitbucket,您甚至可以託管自己的 git 儲存庫。
在您的專案中使用版本控制並將其包含為工具鏈的一部分將有助於管理您的程式碼演變。它提供了一種在您進行時“提交”工作塊的方法,以及諸如“X 新功能實現”或“由於 Y 更改,Bug Z 現在已修復”之類的註釋。
版本控制還可以讓您將專案程式碼分支出來,建立一個單獨的版本,並在其上嘗試新功能,而不會影響您的原始程式碼。
最後,它可以幫助您撤消更改或將程式碼恢復到“工作時”的狀態,如果某個地方引入了錯誤,而您無法修復它——這是所有開發人員不時需要做的事情!
Git 可以從git-scm 網站下載並安裝——下載適合您系統的安裝程式,執行它,並按照螢幕上的提示操作。到目前為止,您只需要執行此操作。
您可以透過多種方式與 git 互動,從使用命令列發出命令,到使用git GUI 應用程式透過按按鈕發出相同的命令,甚至直接在程式碼編輯器中,如以下 Visual Studio Code 示例所示
現有專案
我們將基於我們在上一章中已經開始的專案進行構建,因此請確保您按照包管理中的說明進行操作,以先設定專案。概括地說,您應該擁有以下內容
- 已安裝 Node.js 和 npm。
- 一個名為
npm-experiment(或其他名稱)的新專案。 - Vite 作為開發依賴項已安裝。
plotly.js-dist-min包作為依賴項已安裝。- 在 package.json 中定義的一些自定義指令碼。
- 已建立的
index.html和src/main.jsx檔案。
正如我們在第 1 章中談到的,工具鏈將結構化為以下階段
- 開發環境:執行程式碼最基礎的工具。這部分已在上一章中設定。
- 安全網:使軟體開發體驗穩定且更高效。我們也可能將其稱為開發環境。
- 轉換:允許我們在開發過程中使用語言(例如 JavaScript)的最新功能或完全使用另一種語言(例如 JSX 或 TypeScript),然後轉換程式碼,以便生產版本仍然可以在各種瀏覽器(現代和舊版本)上執行的工具。
- 開發後:在您完成開發主體後生效的工具,以確保您的軟體能夠上線並繼續執行。在本案例研究中,我們將研究向您的程式碼新增測試,以及使用 GitHub Pages 部署您的應用程式,以便所有人都可以訪問它。
讓我們開始著手這些工作,從我們的開發環境開始。我們將遵循與實際專案設定相同的步驟,因此在將來,如果您要設定一個新專案,您可以參考本章並再次遵循這些步驟。
建立開發環境
工具鏈的這一部分有時被認為會延遲實際工作,而且很容易陷入工具的“兔子洞”,在那裡您會花費大量時間試圖使環境“完美”。
但您可以將此與設定您的物理工作環境視為一樣。椅子需要舒適,並且設定在一個良好的位置,以幫助您保持姿勢。您需要電源、Wi-Fi 和 USB 介面!可能有一些重要的裝飾或音樂可以幫助您保持精神狀態——這些對於您儘可能出色地完成工作都很重要,並且如果設定得當,它們也只需設定一次。
同樣,如果您設定得當,設定您的開發環境只需執行一次,並且應該可在許多未來的專案中重複使用。您可能需要定期檢視工具鏈的這一部分,並考慮是否需要進行任何升級或更改,但這不是經常需要做的。
您的工具鏈將取決於您自己的需求,但對於這個相當完整的工具鏈的示例,預先安裝/初始化的工具將是
- 庫安裝工具——用於新增依賴項。
- 程式碼版本控制。
- 程式碼整理工具——用於整理 JavaScript、CSS 和 HTML。
- 程式碼風格檢查工具——用於檢查我們的程式碼。
庫安裝工具
您已經完成了此操作,但為了便於參考,以下是(在 npm-experiment 目錄的根目錄下執行)初始化 npm 包並安裝必要的依賴項的命令
npm init
npm install --save-dev vite
npm install plotly.js-dist-min
程式碼版本控制
輸入以下命令以啟動 git 的原始碼控制功能,使其在目錄上執行
git init
預設情況下,git 會跟蹤所有檔案的更改。但是,有些生成的 檔案我們不需要跟蹤,因為它們不是我們編寫的程式碼,並且可以隨時重新生成。我們可以透過在專案目錄的根目錄中建立.gitignore檔案來告訴 git 忽略這些檔案。將以下內容新增到檔案中
node_modules dist
程式碼整理工具
我們將使用 Prettier,我們在第 2 章中首次遇到它,在本專案中整理我們的程式碼。我們將在本專案中再次安裝 Prettier。使用以下命令安裝它
npm install --save-dev prettier
再次注意,我們使用--save-dev將其新增為開發依賴項,因為我們只在開發過程中使用它。
與許多最近製作的工具一樣,Prettier 附帶“合理的預設值”。這意味著您可以使用 Prettier 而不必進行任何配置(如果您對預設值感到滿意)。這可以讓您專注於重要的事情:創意工作。為了演示,我們將新增一個配置檔案。在您的npm-experiment目錄的根目錄中建立一個名為.prettierrc.json的檔案。新增以下內容
{
"bracketSameLine": true
}
使用此設定,Prettier 將在最後一行的末尾列印多行 HTML(HTML、JSX、Vue、Angular)開始標記的>,而不是單獨放在下一行。這是 MDN 本身使用的格式。您可以在其文件中找到有關配置 Prettier的更多資訊。
預設情況下,Prettier 會格式化您指定的 所有檔案。但是,我們再次不需要格式化生成的檔案,或者可能存在我們不想觸碰的某些遺留程式碼。我們可以透過在專案目錄的根目錄中建立.prettierignore檔案來告訴 Prettier 始終忽略這些檔案。將以下內容新增到檔案中
node_modules dist
它與.gitignore的內容相同,但在實際專案中,您可能希望為 Prettier 忽略與為 git 忽略的檔案不同的檔案。
現在 Prettier 已安裝並配置,可以在命令列上執行和整理程式碼,例如
npx prettier --write ./index.html
注意:在上面的命令中,我們使用--write標誌使用 Prettier。Prettier 理解這意味著“如果我的程式碼格式有任何問題,請立即修復它們,然後儲存我的檔案”。這對於我們的開發過程來說很好,但我們也可以在沒有標誌的情況下使用prettier,它只會檢查檔案。檢查檔案(而不儲存它)對於釋出前的檢查等目的很有用,例如“不要釋出任何未正確格式化的程式碼”。
您還可以將./index.html替換為任何其他檔案或資料夾以格式化它們。例如,.將格式化當前目錄中的所有內容。如果您可能忘記了語法,也可以將其新增為package.json中的自定義指令碼
"scripts": {
// ...
"format": "prettier --write ."
},
現在您可以執行以下命令來格式化目錄
npm run format
每次更改內容時執行該命令仍然很繁瑣,並且有幾種方法可以自動執行此過程
- 使用特殊的“git hook”來測試在提交之前程式碼是否已格式化。
- 使用程式碼編輯器外掛在每次儲存檔案時執行 Prettier 命令。
注意:什麼是 git hook?Git(而不是 GitHub)提供了一個系統,讓我們可以將前後操作附加到我們使用 git 執行的任務(例如提交程式碼)。雖然 git hook 可能有點過於複雜(在本作者看來),但一旦到位,它們就非常強大。如果您有興趣使用 hook,Husky 是使用 hook 的一個非常簡化的途徑。
對於 VS Code,一個有用的擴充套件是Esben Petersen 的 Prettier 程式碼格式化程式,它可以讓 VSCode 在儲存時自動格式化程式碼。這意味著我們正在處理的專案中的任何檔案都將被格式化得很好,包括 HTML、CSS、JavaScript、JSON、markdown 等等。編輯器只需要啟用“儲存時格式化”。
程式碼 linting 工具
Linting 有助於提高程式碼質量,但也是在開發過程中儘早捕獲潛在錯誤的一種方法。它是良好工具鏈的關鍵組成部分,許多開發專案預設情況下會包含它。
Web 開發 linting 工具主要用於 JavaScript(儘管有一些用於 HTML 和 CSS)。這是有道理的:如果使用了未知的 HTML 元素或無效的 CSS 屬性,由於這兩種語言的彈性性質,不太可能出現任何問題。JavaScript 更加脆弱——例如,錯誤地呼叫一個不存在的函式會導致您的 JavaScript 崩潰;因此,對 JavaScript 進行 linting 非常重要,尤其是在大型專案中。
JavaScript linting 的首選工具是ESLint。它是一個非常強大且通用的工具,但配置正確可能很棘手,您很容易花費很多時間嘗試獲得恰到好處的配置!
ESLint 透過 npm 安裝,因此根據第 2 章中的討論,您可以選擇在本地或全域性安裝此工具,但強烈建議您進行本地安裝,因為無論如何您都需要為每個專案建立一個配置檔案。請記住要執行的命令
npm install --save-dev eslint@8 @eslint/js globals
注意:esling@8安裝了 ESLint 的版本 8,而最新版本是 v9。這是因為eslint-plugin-react(我們將在後面使用)尚不支援 v9。
@eslint/js包提供了預定義的 ESLint 配置,而globals包提供了每個環境中已知全域性名稱的列表。我們將在後面的配置中使用它們。開箱即用,如果您使用npx eslint執行 ESLint,它會抱怨找不到配置檔案
Oops! Something went wrong! :( ESLint: 8.57.0 ESLint couldn't find a configuration file. To set up a configuration file for this project, please run: ...
這是一個有效的最小示例(在一個名為eslint.config.js的檔案中,位於專案的根目錄)
import js from "@eslint/js";
import globals from "globals";
export default [
js.configs.recommended,
{
ignores: ["node_modules", "dist"],
},
{
files: ["**/*.{js,jsx}"],
languageOptions: {
globals: {
...globals.browser,
},
},
},
];
上面的 ESLint 配置
- 啟用“推薦”的 ESLint 設定
- 告訴 ESLint 忽略生成的 檔案,就像我們對其他工具所做的那樣
- 告訴 ESLint 在 linting 中包含
.js和.jsx檔案 - 告訴 ESLint 關於瀏覽器全域性變數的存在(用於 linting 規則,例如用於檢查不存在的變數的
no-undef)。
ESLint 解析器預設情況下不理解 JSX,並且其推薦的規則不處理 React 特定的語義。因此,我們將新增一些配置以使其正確支援 JSX 和 React。首先,安裝eslint-plugin-react和eslint-plugin-react-hooks,它們提供了編寫正確且慣用的 React 的規則
npm install --save-dev eslint-plugin-react eslint-plugin-react-hooks
然後,更新 ESLint 配置檔案以包含這些外掛的推薦配置,它們都載入推薦的規則併為 JSX 設定解析器選項
import js from "@eslint/js";
import globals from "globals";
import reactRecommended from "eslint-plugin-react/configs/recommended.js";
import reactJSXRuntime from "eslint-plugin-react/configs/jsx-runtime.js";
import reactHooksPlugin from "eslint-plugin-react-hooks";
export default [
js.configs.recommended,
{
ignores: ["node_modules", "dist"],
},
{
files: ["**/*.{js,jsx}"],
languageOptions: {
globals: {
...globals.browser,
},
},
settings: {
react: {
version: "detect",
},
},
},
reactRecommended,
reactJSXRuntime,
{
plugins: {
"react-hooks": reactHooksPlugin,
},
rules: reactHooksPlugin.configs.recommended.rules,
},
];
注意:與eslint-plugin-react配置的一行新增相比,我們對eslint-plugin-react-hooks的配置有點笨拙。這是因為eslint-plugin-react-hooks尚不支援新的 ESLint 配置格式。有關更多資訊,請參見facebook/react#28313。
您可以隨意調整和配置ESLint 規則的完整列表,許多公司和團隊釋出了他們自己的 ESLint 配置,這些配置有時可能會有用,無論是為了獲得靈感還是選擇一個您認為符合您自己標準的配置。但請注意,ESLint 配置是一個非常深的兔子洞!
為了簡單起見,在本章中,我們不會探索 ESLint 的所有功能,因為此配置適用於我們的特定專案及其要求。但是,請記住,如果您想改進和執行有關程式碼外觀(或驗證)的規則,很可能可以透過正確的 ESLint 配置來實現。
與其他工具一樣,程式碼編輯器整合支援通常對 ESLint 很有效,而且可能更有用,因為它可以在問題出現時為我們提供即時反饋
到目前為止,我們的開發環境設定已完成。現在,我們終於(幾乎)可以編寫程式碼了。
構建和轉換工具
JavaScript 轉換
對於此專案,如上所述,將使用 React,這也意味著將使用 JSX 在原始碼中。該專案還將使用最新的 JavaScript 功能。一個直接的問題是,沒有瀏覽器原生支援 JSX;它是一種中間語言,旨在編譯成瀏覽器在生產程式碼中理解的語言。如果瀏覽器嘗試執行源 JavaScript,它會立即報錯;該專案需要一個構建工具將原始碼轉換為瀏覽器可以輕鬆消費的內容。
有很多轉換工具可供選擇,儘管 Babel 尤其受歡迎,但在 Vite 中,我們將使用一個整合外掛:@vitejs/plugin-react。使用以下命令安裝它
npm install --save-dev @vitejs/plugin-react
我們還沒有 Vite 配置!在專案目錄的根目錄中的vite.config.js處新增一個
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
base: "/npm-experiment/",
});
有關如何配置 Vite 的更多資訊,請閱讀Vite 文件。由於我們的網站部署在 GitHub Pages 上,它將在https://your-username.github.io/your-repo-name處託管,因此您應該根據您的 GitHub 儲存庫的名稱設定base選項——但您始終可以在我們開始部署時進行調整。
CSS 轉換
我們的 CSS 也可能使用瀏覽器無法理解的語法。例如,您可能使用僅在最近幾個瀏覽器版本中實現的語法,這意味著較舊的瀏覽器會在此處失敗並顯示損壞的樣式。我們可以使用工具將我們的 CSS 轉換為所有我們目標瀏覽器可以理解的格式。
PostCSS 是一種 CSS 後處理器工具。與Sass等構建工具相比,PostCSS 旨在編寫標準CSS(即將來可能進入瀏覽器的 CSS 語法),而 Sass 是一種獨立的自定義語言,它編譯為 CSS。PostCSS 更接近網路,學習曲線更低。 Vite 預設支援 PostCSS,因此如果您想編譯任何功能,只需要配置 PostCSS即可。檢視cssdb,瞭解支援哪些功能。
出於我們的目的,我們將演示另一種 CSS 轉換:CSS 模組。它是實現CSS 模組化的方法之一。請記住,CSS 選擇器都是全域性的,因此如果您有一個像.button這樣的類名,所有具有類名button的元素都將以相同的方式進行樣式化。這通常會導致命名衝突——想象一下,所有 JavaScript 變數都在全域性範圍內定義!CSS 模組透過使類名對使用它們的頁面唯一來解決此問題。要了解它的工作原理,在您下載原始碼後,您可以檢視我們如何使用.module.css檔案,還可以閱讀CSS 模組文件。
雖然我們工具鏈的這一階段可能非常痛苦,因為我們選擇了一種故意嘗試減少配置和複雜性的工具,但在開發階段我們實際上不需要做更多的事情。模組已正確匯入,巢狀 CSS 已正確轉換為“常規 CSS”,並且我們的開發不受構建過程的阻礙。
現在我們的軟體已經準備好編寫了!
編寫原始碼
現在我們已經設定好了完整的開發工具鏈,通常是時候開始編寫真正的程式碼了——這部分是你應該投入最多時間的部分。不過,為了我們的目的,我們將直接複製一些現有的原始碼,並假裝是我們自己寫的。我們不會教你它們是如何工作的,因為這不是本章的重點。它們只是為了執行這些工具,教你它們是如何工作的。
要獲取程式碼檔案,請訪問 https://github.com/mdn/client-toolchain-example,下載並解壓縮此倉庫的內容到您本地驅動器上的某個位置。您可以透過選擇克隆或下載 > 下載 ZIP 來將整個專案下載為 zip 檔案。
現在將專案src目錄的內容複製出來,並用它替換您當前的src目錄。您不必擔心其他檔案。
還要安裝原始碼使用的一些依賴項
npm install react react-dom @tanstack/react-query
我們已經將專案檔案準備就緒。現在我們只需要做這些了!
執行轉換
要開始使用我們的專案,我們將在命令列上執行 Vite 伺服器。在預設模式下,它會監視您的程式碼更改並重新整理伺服器。這很好,因為我們不必在程式碼和命令列之間來回切換。
- 要在後臺啟動 Vite,請轉到您的終端並執行以下命令(使用我們之前定義的自定義指令碼)您應該看到類似於這樣的輸出(一旦依賴項已安裝)bash
npm run dev> client-toolchain-example@1.0.0 dev > vite Re-optimizing dependencies because lockfile has changed VITE v5.2.13 ready in 157 ms ➜ Local: https://:5173/ ➜ Network: use --host to expose ➜ press h + enter to show help
伺服器現在正在列印的 URL 上執行(在本例中為 localhost:5173)。 - 在瀏覽器中轉到此 URL,您將看到示例應用程式正在執行!
現在我們可以做一些更改並即時檢視它們的效果。
- 在您最喜歡的文字編輯器中載入檔案
src/App.jsx。 - 將所有
mdn/content替換為您喜歡的 GitHub 倉庫,例如facebook/react。 - 儲存檔案,然後直接返回到瀏覽器中執行的應用程式。您會注意到瀏覽器已自動重新整理,並且圖表已更改!
您也可以嘗試使用 ESLint 和 Prettier——嘗試故意從您的某個檔案中刪除大量空格並執行 Prettier 來清理它,或者在您的某個 JavaScript 檔案中引入語法錯誤,看看在您執行eslint命令或在您的編輯器中時 ESLint 會給您什麼錯誤。