介紹完整的工具鏈

在本系列文章的最後幾篇中,我們將透過指導您構建一個示例案例研究工具鏈來鞏固您的工具知識。我們將從設定合理的開發環境和部署轉換工具,直到實際部署您的應用程式。在本文中,我們將介紹案例研究、設定開發環境並設定程式碼轉換工具。

預備知識 熟悉核心 HTMLCSSJavaScript 語言。
目標 透過完整的工具鏈案例研究來鞏固我們目前所學到的知識。

工具的組合和使用方式是無限的,您在本文和下一篇文章中看到的只是所介紹的工具可用於專案的一種方式。

注意: 值得重申的是,並非所有這些工具都需要在命令列上執行。如今的許多程式碼編輯器(例如 VS Code)都透過外掛支援大量工具。

介紹我們的案例研究

我們將在本文中建立的工具鏈將用於構建和部署一個微型網站,該網站顯示有關 mdn/content 儲存庫的資料,其資料來源於 GitHub API

我們工具鏈中使用的工具

在本文中,我們將使用以下工具和功能

  • JSX,一組與 React 相關的語法擴充套件,允許您在 JavaScript 中定義元件結構。您無需瞭解 React 即可遵循本教程,但我們將其包含在內,以便讓您瞭解非原生 Web 語言如何整合到工具鏈中。
  • 最新的內建 JavaScript 功能(撰寫本文時),例如 import
  • 有用的開發工具,例如用於格式化的 Prettier 和用於 Linting 的 ESLint
  • PostCSS 提供 CSS 巢狀功能。
  • Vite 用於構建和縮小程式碼,並自動為我們編寫大量配置檔案內容。
  • GitHub 用於管理我們的原始碼控制,並最終部署我們的網站(使用 GitHub Pages)。

您可能不熟悉上述所有功能和工具或它們的作用,但請不要驚慌——我們將在這篇文章中逐一解釋每個部分。

工具鏈及其固有的複雜性

與任何鏈條一樣,工具鏈中的連結越多,它就越複雜,也越脆弱——例如,它可能更復雜,更容易損壞。反之,連結越少,工具鏈就越有彈性。

所有 Web 專案都將有所不同,您需要考慮工具鏈的哪些部分是必要的,並仔細考慮每個部分。

最小的工具鏈是沒有連結的工具鏈。您將手動編寫 HTML,使用“原生 JavaScript”(這意味著沒有框架或中間語言),並手動將所有內容上傳到伺服器進行託管。

然而,更復雜的軟體需求可能會受益於使用工具來幫助簡化開發過程。此外,您應該在部署到生產伺服器之前進行測試,以確保您的軟體按預期工作——這聽起來已經是一個必要的工具鏈了。

對於我們的示例專案,我們將使用專門設計的工具鏈來輔助我們的軟體開發並支援軟體設計階段做出的技術選擇。但是,我們將避免任何多餘的工具,旨在將複雜性降到最低。

檢查先決條件

如果您一直遵循前面的章節,那麼您應該已經擁有大部分軟體。在進行實際設定步驟之前,您應該具備以下條件。它們只需要執行一次,將來不需要為其他專案重複。

建立 GitHub 帳戶

除了我們將要安裝的構成工具鏈的工具之外,如果您希望完成本教程,還需要建立一個 GitHub 帳戶。但是,您仍然可以在沒有它的情況下進行本地開發。如前所述,GitHub 是一種原始碼儲存庫服務,它增加了諸如問題跟蹤、關注專案釋出等社群功能。在下一章中,我們將推送到 GitHub 程式碼儲存庫,這將導致級聯效應,(應該)將所有軟體部署到 Web 上的一個家。

如果您還沒有帳戶,請單擊主頁上的 Sign Up 連結註冊 GitHub,然後按照說明進行操作。

安裝 Git

我們將安裝另一個軟體 Git,以幫助進行版本控制。

您可能以前聽說過“Git”。Git 是目前開發人員最流行的原始碼版本控制工具——版本控制提供了許多優勢,例如在遠端位置備份工作的方式,以及在同一個專案上以團隊形式工作而無需擔心覆蓋彼此程式碼的機制。

對某些人來說可能很明顯,但值得重申:Git 與 GitHub 不是一回事。Git 是版本控制工具,而 GitHub 是 Git 倉庫的線上商店(以及許多用於處理它們的有用工具)。請注意,儘管我們在本章中使用 GitHub,但還有其他幾種替代方案,包括 GitLabBitbucket,您甚至可以託管自己的 Git 倉庫。

在您的專案中使用版本控制並將其作為工具鏈的一部分,將有助於管理程式碼的演變。它提供了一種在您進行過程中“提交”工作塊的方式,並附有諸如“實現了 X 新功能”或“由於 Y 更改,錯誤 Z 現已修復”之類的註釋。

版本控制還可以讓您將專案程式碼“分支”出來,建立一個單獨的版本,並在其上嘗試新功能,而這些更改不會影響您的原始程式碼。

最後,如果某個地方出現了錯誤並且您難以修復它,它可以幫助您撤消更改或將程式碼恢復到“正常工作”的時間——這是所有開發人員都需要偶爾做的事情!

Git 可以透過 git-scm 網站下載和安裝——下載適用於您系統的相關安裝程式,執行它,然後按照螢幕上的提示操作。目前您只需要做這些。

您可以透過多種不同的方式與 Git 互動,從使用命令列發出命令,到使用 Git GUI 應用程式透過按鈕發出相同的命令,甚至可以直接在程式碼編輯器中進行,如下面的 Visual Studio Code 示例所示

Git integration shown in VS Code

現有專案

我們將在上一章中已經開始的專案基礎上進行構建,因此請務必首先按照 包管理 中的說明設定專案。回顧一下,您應該擁有

  • 已安裝 Node.js 和 npm。
  • 一個名為 npm-experiment(或其他名稱)的新專案。
  • Vite 已作為開發依賴項安裝。
  • plotly.js-dist-min 包已作為依賴項安裝。
  • package.json 中定義了一些自定義指令碼。
  • index.htmlsrc/main.jsx 檔案已建立。

正如我們在 第 1 章 中討論的那樣,工具鏈將分為以下幾個階段

  • 開發環境:執行程式碼最基本的工具。此部分已在上一章中設定。
  • 安全網:使軟體開發體驗穩定高效。我們也可以稱之為我們的開發環境。
  • 轉換:允許我們在開發過程中使用語言(例如 JavaScript)的最新功能或完全不同的語言(例如 JSX 或 TypeScript)的工具,然後轉換我們的程式碼,以便生產版本仍然可以在各種瀏覽器(現代和舊版)上執行。
  • 開發後:在您完成大部分開發後投入使用的工具,以確保您的軟體能夠釋出到網路並持續執行。在這個案例研究中,我們將研究如何向程式碼新增測試,並使用 GitHub Pages 部署您的應用程式,以便所有網路使用者都可以看到它。

讓我們開始著手這些,從我們的開發環境開始。我們將遵循與真實專案設定相同的步驟,因此將來,如果您要設定新專案,可以參考本章並再次遵循這些步驟。

建立開發環境

工具鏈的這一部分有時被視為延遲實際工作,而且很容易陷入工具的“兔子洞”,花費大量時間試圖讓環境“恰到好處”。

但您可以將其視為設定您的物理工作環境。椅子需要舒適,並設定在有助於您姿勢的良好位置。您需要電源、Wi-Fi 和 USB 埠!可能還有重要的裝飾或音樂有助於您的精神狀態——這些對於盡力而為至關重要,而且如果做得好,它們也應該只需要設定一次。

同樣,如果做得好,您的開發環境只需要設定一次,並且可以在許多未來的專案中重複使用。您可能希望定期審閱工具鏈的這一部分,並考慮是否應該引入任何升級或更改,但這不應該太頻繁地需要。

您的工具鏈將取決於您自己的需求,但對於這個相當完整的工具鏈示例,將預先安裝/初始化的工具將是

  • 庫安裝工具 — 用於新增依賴項。
  • 程式碼版本控制。
  • 程式碼整理工具 — 用於整理 JavaScript、CSS 和 HTML。
  • 程式碼 Linting 工具 — 用於 Linting 我們的程式碼。

庫安裝工具

您已經完成了此操作,但為了方便參考,以下是在 npm-experiment 目錄的根目錄中執行的命令,用於初始化 npm 包並安裝必要的依賴項

bash
npm init
npm install --save-dev vite
npm install plotly.js-dist-min

程式碼版本控制

輸入以下命令以啟動 Git 的原始碼控制功能在目錄中工作

bash
git init

預設情況下,Git 跟蹤所有檔案的更改。但是,有些生成的檔案我們不需要跟蹤,因為它們不是我們編寫的程式碼,並且可以隨時重新生成。我們可以透過在專案目錄的根目錄中建立一個 .gitignore 檔案來告訴 Git 忽略這些檔案。將以下內容新增到檔案中

node_modules
dist

程式碼整理工具

我們將使用 Prettier(我們首次在第 2 章中遇到)來整理此專案中的程式碼。我們將在此專案中再次安裝 Prettier。使用以下命令安裝它

bash
npm install --save-dev prettier

再次注意,我們使用 --save-dev 將其新增為開發依賴項,因為我們只在開發期間使用它。

像許多最近製作的工具一樣,Prettier 帶有“合理的預設值”。這意味著您無需配置任何東西即可使用 Prettier(如果您對 預設值 感到滿意)。這讓您可以專注於重要的事情:創意工作。為了演示,我們將新增一個配置檔案。在 npm-experiment 目錄的根目錄下建立一個名為 .prettierrc.json 的檔案。新增以下內容

json
{
  "bracketSameLine": true
}

透過此設定,Prettier 會將多行 HTML(HTML、JSX、Vue、Angular)開始標籤的 > 列印在最後一行的末尾,而不是單獨放在下一行。這是 MDN 自己使用的格式。您可以在其文件中找到有關 配置 Prettier 的更多資訊。

預設情況下,Prettier 會格式化您指定的所有檔案。但是,我們同樣不需要格式化生成的檔案,或者可能有一些我們不想觸碰的舊程式碼。我們可以透過在專案目錄的根目錄下建立一個 .prettierignore 檔案來告訴 Prettier 始終忽略這些檔案。將以下內容新增到檔案中

node_modules
dist

它的內容與 .gitignore 相同,但在真實專案中,您可能希望 Prettier 忽略的檔案與 Git 忽略的檔案不同。

現在 Prettier 已安裝並配置,可以在命令列上執行和整理您的程式碼,例如

bash
npx prettier --write ./index.html

注意: 在上面的命令中,我們使用帶有 --write 標誌的 Prettier。Prettier 將其理解為“如果我的程式碼格式有任何問題,請修復它們,然後儲存我的檔案”。這對於我們的開發過程來說很好,但我們也可以在沒有標誌的情況下使用 prettier,它只會檢查檔案。檢查檔案(而不儲存它)對於釋出前執行的檢查等目的很有用——即“不要釋出任何未正確格式化的程式碼。”

您還可以將 ./index.html 替換為任何其他檔案或資料夾以對其進行格式化。例如,. 將格式化當前目錄中的所有內容。如果您忘記了語法,您也可以將其作為自定義指令碼新增到您的 package.json 中

json
{
  "scripts": {
    // …
    "format": "prettier --write ."
  }
}

現在您可以執行以下命令來格式化目錄

bash
npm run format

每次我們更改某些內容時都執行該命令仍然很麻煩,並且有幾種方法可以自動化此過程

  • 使用特殊的“git 鉤子”在提交前測試程式碼是否已格式化。
  • 使用程式碼編輯器外掛在每次儲存檔案時執行 Prettier 命令。

注意: 什麼是 Git 鉤子?Git(不是 GitHub)提供了一個系統,允許我們將前置和後置操作附加到我們使用 Git 執行的任務(例如提交程式碼)。雖然 Git 鉤子可能有點過於複雜(在本文作者看來),但一旦它們就位,它們就會非常強大。如果您有興趣使用鉤子,Husky 是使用鉤子的一個大大簡化的途徑。

對於 VS Code,一個有用的擴充套件是 Esben Petersen 的 Prettier Code Formatter,它允許 VS Code 在儲存時自動格式化程式碼。這意味著我們正在處理的專案中的任何檔案都會被很好地格式化,包括 HTML、CSS、JavaScript、JSON、Markdown 等。編輯器只需要啟用“儲存時格式化”。

程式碼 Linting 工具

Linting 有助於程式碼質量,也是在開發早期發現潛在錯誤的一種方式。它是良好工具鏈的關鍵組成部分,也是許多開發專案預設會包含的工具。

Web 開發 Linting 工具主要用於 JavaScript(儘管也有一些適用於 HTML 和 CSS)。這是有道理的:如果使用了未知的 HTML 元素或無效的 CSS 屬性,由於這兩種語言的彈性特性,不太可能出現問題。JavaScript 要脆弱得多——例如,錯誤地呼叫不存在的函式會導致您的 JavaScript 崩潰;因此 Linting JavaScript 非常重要,尤其是對於大型專案。

用於 JavaScript Linting 的首選工具是 ESLint。它是一個極其強大和通用的工具,但配置起來可能很棘手,您很容易花費數小時試圖獲得“恰到好處”的配置!

ESLint 透過 npm 安裝,因此根據第 2 章中的討論,您可以選擇在本地或全域性安裝此工具,但強烈建議進行本地安裝,因為您無論如何都需要為每個專案提供一個配置檔案。記住要執行的命令

bash
npm install --save-dev eslint@8 @eslint/js globals

注意: eslint@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 檔案中有效

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 瀏覽器全域性變數的存在(Lint 規則(例如 no-undef)用於檢查不存在的變數)。

ESLint 解析器預設不理解 JSX,其推薦規則也不處理 React 特定的語義。因此,我們將新增更多配置以使其正確支援 JSX 和 React。首先,安裝 eslint-plugin-reacteslint-plugin-react-hooks,它們提供用於編寫正確和地道的 React 的規則

bash
npm install --save-dev eslint-plugin-react eslint-plugin-react-hooks

然後,更新 ESLint 配置檔案以包含這些外掛的推薦配置,它既載入推薦規則又為 JSX 設定解析器選項

js
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-hooks 配置與 eslint-plugin-react 配置的一行新增相比有點尷尬。這是因為 eslint-plugin-react-hooks 尚不支援新的 ESLint 配置格式。有關更多資訊,請參閱 facebook/react#28313

有一份完整的 ESLint 規則列表,您可以隨意調整和配置,許多公司和團隊都發布了他們自己的 ESLint 配置,這有時可能有助於獲取靈感或選擇一個您認為符合您自己標準的配置。不過,請注意:ESLint 配置是一個非常深的兔子洞!

為簡單起見,在本章中,我們不會探討 ESLint 的所有功能,因為此配置適用於我們特定的專案及其要求。但是,請記住,如果您想改進和強制執行有關程式碼外觀(或驗證)的規則,很可能可以透過正確的 ESLint 配置來完成。

與其他工具一樣,ESLint 的程式碼編輯器整合支援通常很好,並且可能更有用,因為它可以在出現問題時為我們提供即時反饋

ESLint error integration shown in VS Code

至此,我們的開發環境設定已完成。現在,我們(幾乎)準備好編碼了。

構建和轉換工具

JavaScript 轉換

對於這個專案,如上所述,將使用 React,這也意味著在原始碼中將使用 JSX。專案還將使用最新的 JavaScript 功能。一個直接的問題是,沒有瀏覽器原生支援 JSX;它是一種中間語言,旨在編譯成生產程式碼中瀏覽器能夠理解的語言。如果瀏覽器嘗試執行原始碼 JavaScript,它會立即報錯;專案需要一個構建工具來將原始碼轉換為瀏覽器可以毫無問題地使用的內容。

有多種轉換工具可供選擇,雖然 Babel 是一個特別流行的工具,但在 Vite 中,我們將使用一個整合外掛:@vitejs/plugin-react。使用以下命令安裝它

bash
npm install --save-dev @vitejs/plugin-react

我們還沒有 Vite 配置!在專案目錄的根目錄下新增一個 vite.config.js

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 更接近 Web,學習曲線也更低。Vite 預設支援 PostCSS,因此您只需要配置 PostCSS 即可編譯任何功能。檢視 cssdb 瞭解支援哪些功能。

出於我們的目的,我們將演示另一個 CSS 轉換:CSS 模組。它是實現 CSS 模組化 的方法之一。請記住,CSS 選擇器都是全域性的,所以如果您有一個像 .button 這樣的類名,所有帶有類名 button 的元素都將以相同的方式進行樣式設定。這通常會導致命名衝突——想象一下您所有的 JavaScript 變數都在全域性作用域中定義!CSS 模組透過使類名對於使用它們的頁面是唯一的來解決這個問題。要了解它是如何工作的,在您下載原始碼後,您可以檢視我們如何使用 .module.css 檔案,並閱讀 CSS 模組文件

儘管我們工具鏈的這個階段可能會相當痛苦,但由於我們選擇了一個故意嘗試減少配置和複雜性的工具,所以在開發階段我們真的不需要做更多的事情。模組被正確匯入,巢狀的 CSS 被正確轉換為“常規 CSS”,我們的開發不會受到構建過程的阻礙。

現在我們的軟體可以編寫了!

編寫原始碼

現在我們已經建立了完整的開發工具鏈,通常是時候開始編寫真正的程式碼了——您應該投入最多時間的部分。但出於我們的目的,我們只是複製一些現有的原始碼,假裝是我們編寫的。我們不會教您它們是如何工作的,因為這不是本章的重點。它們只是為了在其上執行工具,以教您它們是如何工作的。

要獲取程式碼檔案,請訪問 https://github.com/mdn/client-toolchain-example 並將此儲存庫的內容下載並解壓縮到您本地驅動器的某個位置。您可以透過選擇 Clone or download > Download ZIP 來下載整個專案作為 zip 檔案。

The GitHub example repo

現在複製專案 src 目錄的內容,並用它替換您當前的 src 目錄。您無需擔心其他檔案。

另外安裝原始碼使用的一些依賴項

bash
npm install react react-dom @tanstack/react-query

我們的專案檔案已經就位。目前我們只需要做這些!

執行轉換

要開始使用我們的專案,我們將在命令列上執行 Vite 伺服器。在預設模式下,它將監視程式碼中的更改並重新整理伺服器。這很好,因為我們不必在程式碼和命令列之間來回切換。

  1. 要在後臺啟動 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)。

  2. 在瀏覽器中訪問此 URL,您將看到示例應用程式正在執行!

現在我們可以進行一些更改並即時檢視它們的效果。

  1. 在您喜歡的文字編輯器中載入檔案 src/App.jsx
  2. 將所有出現的 mdn/content 替換為您最喜歡的 GitHub 儲存庫,例如 facebook/react
  3. 儲存檔案,然後立即返回瀏覽器中執行的應用程式。您會注意到瀏覽器已自動重新整理,並且圖表已更改!

您還可以嘗試使用 ESLint 和 Prettier——嘗試故意從您的一個檔案中刪除大量空格,然後執行 Prettier 來清理它,或者在您的一個 JavaScript 檔案中引入語法錯誤,然後檢視執行 eslint 命令或在編輯器中 ESLint 會給您帶來什麼錯誤。

總結

在本章中,我們已經取得了很大的進步,建立了一個相當不錯的本地開發環境來建立應用程式。

在 Web 軟體開發的這個階段,您通常會為要構建的軟體精心編寫程式碼。由於本模組是關於學習 Web 開發的工具,而不是 Web 開發程式碼本身,因此我們不會教您任何實際的編碼——您將在 MDN 的其餘部分找到這些資訊!

相反,我們為您編寫了一個示例專案,供您使用您的工具。我們建議您使用我們的示例程式碼完成本章的其餘部分,然後您可以嘗試將 src 目錄的內容更改為您自己的專案,並將其釋出到 GitHub Pages 上!實際上,部署到 GitHub Pages 將是下一章的最終目標!