React
Parcel 非常適合用於建置單頁或多頁 React 應用程式。它包含一流水準的開發體驗,具備快速更新功能,並支援 JSX、TypeScript、Flow,以及許多造型方法。
入門
#首先,將 react
和 react-dom
安裝到您的專案
yarn add react react-dom
大多數 Parcel 應用程式都從 HTML 檔案開始。Parcel 會從那裡追蹤依賴項(例如 <script>
標籤)來建置您的應用程式。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Parcel App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="index.js"></script>
</body>
</html>
import { createRoot } from "react-dom/client";
import { App } from "./App";
const container = document.getElementById("app");
const root = createRoot(container)
root.render(<App />);
export function App() {
return <h1>Hello world!</h1>;
}
如您所見,我們在 HTML 檔案的 <script>
元素中參照了 index.js
。這會匯入 react-dom
,並使用它將我們的 App
元件呈現在頁面中的 <div id="app">
元素中。
請參閱 使用 Parcel 建置網頁應用程式,以取得有關如何開始新專案的更多詳細資訊。
JSX
#當 Parcel 偵測到您正在使用 React 時,它會自動支援 JSX。如果您使用的是 React 17 或更新版本,它也會自動啟用 現代 JSX 轉換,這表示您甚至不需要匯入 React 就能讓 JSX 運作,如您在上述範例中的 App.js
中所見。
若要深入了解 JSX,請參閱 React 文件中的 JSX 簡介 和 深入探討 JSX,以及 Parcel JavaScript 文件中的 JSX 部分,以取得有關如何設定處理方式的某些詳細資訊。
快速更新
#Parcel 對 React 快速更新 提供一流支援,讓您在編輯程式碼時獲得快速回饋,而無需重新載入頁面。在大部分情況下,即使您出錯,它也能在編輯程式碼時保留元件狀態。請參閱 熱重載 文件,以了解其運作方式的詳細資訊。
提示
#- 避免使用類別元件 – 快速更新僅適用於函式元件(及 Hooks)。
- 僅匯出 React 元件 – 如果檔案匯出 React 元件和其他類型的值,則其狀態將在每次變更時重設。若要保留狀態,請僅匯出 React 元件,並在可能的情況下將其他匯出移至不同的檔案。
- 避免使用未命名預設匯出 – 使用預設匯出的箭頭函式宣告元件,將導致其狀態在變更時重設。請使用命名函式,或將箭頭函式指定給變數。
- 將入口元件保存在其自己的檔案中 – 入口元件應與呼叫
createRoot
的元件分開,否則它們將在每次變更時重新掛載。
如需更多提示,請參閱官方 React 快速更新文件。
TypeScript
#TypeScript 開箱即用。您可以從 HTML 頁面參照 .ts
或 .tsx
檔案,而 Parcel 將會按照您的預期編譯它。
若要為 React 新增 TypeScript 定義,請將下列套件安裝到您的專案中
yarn add @types/react @types/react-dom --dev
請參閱 TypeScript 文件,以取得有關如何將 TypeScript 與 Parcel 搭配使用的詳細資料。
Flow
#安裝 Flow 之後,系統會自動提供支援。若要將其新增至現有專案,請先將 flow-bin
安裝為相依性
yarn add flow-bin --dev
然後,在您想要進行類型檢查的檔案頂端使用 // @flow
指令。這也會向 Parcel 指出哪些檔案可以具有 Flow 類型,這些類型在為瀏覽器編譯時應予移除。
請參閱 Flow 文件,以取得有關如何將 Flow 與 Parcel 搭配使用的詳細資料。
樣式設定
#Parcel 支援許多不同的方式來設定使用 React 編寫的應用程式樣式。
CSS
#您可以將 CSS 檔案匯入 JavaScript 或 TypeScript 檔案中,以與元件一起載入。
import './Button.css';
export function Button({ children }) {
return (
<button className="button">
{children}
</button>
);
}
.button {
background: hotpink;
}
您也可以在 HTML 檔案中使用標準的 <link rel="stylesheet">
元素來載入 CSS,但從元件中參照 CSS 有助於清楚指出哪些元件依賴於哪些 CSS。這也有助於進行程式碼拆分,因為只會載入您要呈現的元件所需的 CSS。
Parcel 也支援 CSS 語言,例如 SASS、Less 和 Stylus。請參閱 CSS,以取得有關 Parcel 如何處理 CSS 的詳細資料。
CSS 模組
#預設情況下,從 JavaScript 匯入的 CSS 是全域性的。如果兩個 CSS 檔案定義相同的類別名稱,它們可能會發生衝突並互相覆寫。為了解決這個問題,Parcel 支援 CSS 模組。
CSS 模組將每個檔案中定義的類別視為唯一。每個類別名稱都會重新命名,以包含唯一的雜湊,並將對應表匯出至 JavaScript,以允許參照這些重新命名的類別名稱。
若要使用 CSS 模組,請建立一個副檔名為 .module.css
的檔案,並使用 命名空間匯入 從 JavaScript 檔案匯入。然後,您可以在 JSX 中呈現元素時使用 CSS 模組的匯出。
import * as classes from './Button.module.css';
export function Button({ children }) {
return (
<button className={classes.button}>
{children}
</button>
);
}
.button {
background: hotpink;
}
請參閱 CSS 模組,以深入了解 Parcel 如何處理 CSS 模組。
CSS-in-JS
#像 Styled Components、Emotion 等 CSS-in-JS 函式庫與 Parcel 相容性良好。有些可能需要建置設定,例如 Babel 外掛程式。若要啟用,請在您的專案中建立 Babel 設定,Parcel 會自動選取。
例如,若要使用 Emotion,請安裝 Babel 外掛程式,並在您的專案中建立 .babelrc
yarn add @emotion/babel-plugin --dev
yarn add @emotion/react
{
"plugins": ["@emotion/babel-plugin"]
}
您還需要在 tsconfig.json
或 jsconfig.json
中設定 jsxImportSource
選項,以便使用 Emotion 的 JSX 實用程式,而非預設的。這會讓 css
道具可以運作。
{
"compilerOptions": {
"jsxImportSource": "@emotion/react"
}
}
現在,您可以使用 CSS-in-JS 呈現元素
import { css } from "@emotion/react";
export function Button({ children }) {
return (
<button
css={css`
background: hotpink;
&:hover {
background: purple;
}
`}
>
{children}
</button>
);
}
Tailwind CSS
#Tailwind CSS 是廣受歡迎的實用優先 CSS 架構。它使用 PostCSS 建立一個僅包含您在程式碼中使用的類別的 CSS 檔案。
若要使用它,請先安裝必要的相依性
yarn add tailwindcss postcss autoprefixer --dev
接下來,建立 PostCSS 和 Tailwind 所需的設定檔。此範例將使用 Tailwind 的 JIT 模式,僅編譯您使用的類別,以加快建置速度。請務必修改傳遞給 content
選項的 glob,使其與您將使用 Tailwind 類別的所有原始檔相符。
{
"plugins": {
"tailwindcss": {}
}
}
module.exports = {
content: ["./src/*.{html,js}"],
theme: {
extend: {},
},
variants: {},
plugins: [],
};
最後,您可以從與 tailwind.config.js
中列出的 content
glob 相符的任何檔案中參照 Tailwind 類別。
export function Button({ children }) {
return (
<button className="p-2 rounded bg-blue-500 hover:bg-blue-600 transition">
{children}
</button>
);
}
圖片
#您可以使用 URL
建構函式從 JSX 參照外部圖片。Parcel 還支援使用 查詢參數 來調整圖片大小並將圖片轉換為不同的格式。它也會處理圖片最佳化,並在輸出檔名中包含 內容雜湊,以利瀏覽器長期快取。
const logo = new URL('logo.svg', import.meta.url);
export function Logo() {
return <img src={logo} alt="logo" />;
}
請參閱 JavaScript 文件中的 URL 相依性 以取得有關此語法的更多詳細資訊,以及 圖片 文件以取得有關 Parcel 如何處理圖片的更多資訊。
SVG
#外部 SVG 檔案可以如上所述參照。您也可以將 SVG 匯入為 React 元件,這些元件可以直接在 JSX 中呈現。
首先,安裝 @parcel/transformer-svg-react
外掛程式,並將其新增到您的 .parcelrc
yarn add @parcel/transformer-svg-react --dev
{
"extends": "@parcel/config-default",
"transformers": {
"*.svg": ["...", "@parcel/transformer-svg-react"]
}
}
現在,您可以從元件檔案匯入 SVG,並像其他任何元件一樣呈現它們。
import AddIcon from "./AddIcon.svg";
export function AddButton() {
return (
<button aria-label="Add">
<AddIcon />
</button>
);
}
上述範例顯示如何將每個 SVG 檔案轉換為 JSX,但在某些情況下您可能希望更具選擇性。請參閱 SVG 文件中的 匯入為 React 元件 以取得更多詳細資訊。
請參閱 SVG 文件以取得更多有關 Parcel 如何轉換和最佳化 SVG 檔案的資訊。
程式碼分割
#程式碼分割有助於透過延遲載入應用程式的區段來減少初始頁面載入大小。這可以使用動態 import()
語法,以及 React.lazy
來完成。
此範例在使用者按下按鈕時會延遲載入 Profile
元件。當 Parcel 看見動態的 import()
時,會將 Profile
元件移至與 Home
元件分開的套件中,並依需求載入。React.lazy
負責將此轉換為元件,而 Suspense
則負責在載入時呈現備用方案。
import React, {Suspense} from 'react';
const Profile = React.lazy(() => import('./Profile'));
export function Home() {
let [showProfile, setShowProfile] = React.useState(false);
return (
<main>
<h1>Home</h1>
<button onClick={() => setShowProfile(true)}>
Show Profile
</button>
{showProfile &&
<Suspense fallback={<div>Loading...</div>}>
<Profile />
</Suspense>
}
</main>
);
}
export default function Profile() {
return <h2>Profile</h2>;
}
請參閱 程式碼分割 文件,以取得 Parcel 中程式碼分割的更多詳細資訊,以及 程式碼分割 React 文件,以取得更多關於 Suspense
和 React.lazy
的資訊。