React

Parcel 非常适合构建单页或多页 React 应用程序。它包含一流的开发体验,包括快速刷新,并开箱即用地支持 JSX、TypeScript、Flow 和许多样式方法。

入门

#

首先,将 reactreact-dom 安装到您的项目中

yarn add react react-dom

大多数 Parcel 应用程序都从一个 HTML 文件开始。Parcel 从那里跟踪依赖项(例如 <script> 标签)来构建您的应用程序。

src/index.html
<!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>
src/index.js
import { createRoot } from "react-dom/client";
import { App } from "./App";

const container = document.getElementById("app");
const root = createRoot(container)
root.render(<App />);
src/App.js
export function App() {
return <h1>Hello world!</h1>;
}

如您所见,我们在 HTML 文件中的 <script> 元素中引用了 index.js。它导入了 react-dom 并使用它将我们的 App 组件渲染到页面中的 <div id="app"> 元素中。

有关使用 Parcel 启动新项目的更多详细信息,请参阅 使用 Parcel 构建 Web 应用程序

JSX

#

当 Parcel 检测到您正在使用 React 时,它会自动支持 JSX。如果您使用的是 React 17 或更高版本,它还会自动启用 现代 JSX 转换,这意味着您甚至不需要导入 React 就可以使 JSX 工作,如上面示例中的 App.js 所示。

要了解有关 JSX 的更多信息,请参阅 React 文档中的 介绍 JSX深入了解 JSX,以及 Parcel 的 JavaScript 文档中的 JSX 部分,了解有关如何配置一些处理细节的详细信息。

快速刷新

#

Parcel 对 React 快速刷新 提供一流的支持,它在您编辑代码时提供快速反馈,而无需重新加载页面。在大多数情况下,它可以保留组件状态,即使您在编辑代码时出错。有关其工作原理的详细信息,请参阅 热重载 文档。

提示

#

有关更多提示,请参阅官方 React 快速刷新文档

TypeScript

#

TypeScript 开箱即用地受支持。您可以从 HTML 页面中引用 .ts.tsx 文件,Parcel 将按预期编译它。

要为 React 添加 TypeScript 定义,请将以下包安装到您的项目中

yarn add @types/react @types/react-dom --dev

有关使用 Parcel 的 TypeScript 的更多详细信息,请参阅 TypeScript 文档。

Flow

#

Flow 在安装后会自动得到支持。要将其添加到现有项目中,首先将 flow-bin 作为依赖项安装

yarn add flow-bin --dev

然后,在您要类型检查的文件顶部使用 // @flow 指令。这也会向 Parcel 信号哪些文件可以包含 Flow 类型,这些类型在编译到浏览器时应该被剥离。

有关使用 Parcel 的 Flow 的更多详细信息,请参阅 Flow 文档。

样式

#

Parcel 支持许多不同的方法来为使用 React 编写的应用程序设置样式。

CSS

#

您可以将 CSS 文件导入 JavaScript 或 TypeScript 文件,以将其与组件一起加载。

Button.js
import './Button.css';

export function Button({ children }) {
return (
<button className="button">
{children}
</button>
);
}
Button.css
.button {
background: hotpink;
}

您也可以使用 HTML 文件中的标准 <link rel="stylesheet"> 元素加载 CSS,但是从组件中引用 CSS 有助于清楚地表明哪些组件依赖于哪些 CSS。这也有助于代码分割,因为只有您渲染的组件所需的 CSS 才会被加载。

Parcel 还支持 SASSLessStylus 等 CSS 语言。有关 Parcel 如何处理 CSS 的更多详细信息,请参阅 CSS

CSS 模块

#

默认情况下,从 JavaScript 导入的 CSS 是全局的。如果两个 CSS 文件定义了相同的类名,它们可能会发生冲突并相互覆盖。为了解决这个问题,Parcel 支持 CSS 模块

CSS 模块将每个文件中定义的类视为唯一的。每个类名都会被重命名以包含一个唯一的哈希值,并且会将一个映射导出到 JavaScript,以允许引用这些重命名的类名。

要使用 CSS 模块,请创建一个扩展名为 .module.css 的文件,并使用 命名空间导入 从 JavaScript 文件中导入它。然后,您可以在 JSX 中渲染元素时使用 CSS 模块的导出。

Button.js
import * as classes from './Button.module.css';

export function Button({ children }) {
return (
<button className={classes.button}>
{children}
</button>
);
}
Button.module.css
.button {
background: hotpink;
}

有关 Parcel 如何处理 CSS 模块的更多信息,请参阅 CSS 模块

CSS-in-JS

#

Parcel 与 Styled ComponentsEmotion 等许多 CSS-in-JS 库配合得很好。有些可能需要构建配置,例如 Babel 插件。要启用它,请在您的项目中创建一个 Babel 配置,Parcel 会自动获取它。

例如,要使用 Emotion,请安装 Babel 插件并在您的项目中创建一个 .babelrc

yarn add @emotion/babel-plugin --dev
yarn add @emotion/react
.babelrc
{
"plugins": ["@emotion/babel-plugin"]
}

您还需要在 tsconfig.jsonjsconfig.json 中设置 jsxImportSource 选项,以便使用 Emotion 的 JSX 标记而不是默认标记。这将使 css 属性能够工作。

jsconfig.json
{
"compilerOptions": {
"jsxImportSource": "@emotion/react"
}
}

现在,您可以使用 CSS-in-JS 渲染元素

Button.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 类的所有源文件。

.postcssrc
{
"plugins": {
"tailwindcss": {}
}
}
tailwind.config.js
module.exports = {
content: ["./src/*.{html,js}"],
theme: {
extend: {},
},
variants: {},
plugins: [],
};

最后,您可以从与 tailwind.config.js 中列出的 content glob 匹配的任何文件中引用 Tailwind 类。

Button.js
export function Button({ children }) {
return (
<button className="p-2 rounded bg-blue-500 hover:bg-blue-600 transition">
{children}
</button>
);
}

图片

#

您可以使用 URL 构造函数从 JSX 中引用外部图片。Parcel 还支持使用 查询参数 来调整图片大小并将其转换为不同的格式。它还处理图片优化,并在输出文件名中包含 内容哈希,以便进行长期浏览器缓存。

Logo.js
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
.parcelrc
{
"extends": "@parcel/config-default",
"transformers": {
"*.svg": ["...", "@parcel/transformer-svg-react"]
}
}

现在,您可以从组件文件中导入 SVG 并像任何其他组件一样渲染它们。

AddButton.js
import AddIcon from "./AddIcon.svg";

export function AddButton() {
return (
<button aria-label="Add">
<AddIcon />
</button>
);
}

上面的示例展示了如何将每个 SVG 文件转换为 JSX,但在某些情况下您可能希望更具选择性。有关更多详细信息,请参阅 SVG 文档中的 导入为 React 组件

有关 Parcel 如何转换和优化 SVG 文件的更多信息,请参阅 SVG 文档。

代码分割

#

代码分割通过延迟加载应用程序的各个部分来帮助减少初始页面加载大小。这可以通过使用动态 import() 语法以及 React.lazy 来实现。

此示例在用户单击按钮时延迟加载 Profile 组件。当它看到动态 import() 时,Parcel 将 Profile 组件移动到与 Home 组件分开的包中,并按需加载它。React.lazy 处理将其转换为组件,Suspense 处理在加载时渲染一个回退。

Home.js
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>
);
}
Profile.js
export default function Profile() {
return <h2>Profile</h2>;
}

有关 Parcel 中代码分割的更多详细信息,请参阅 代码分割 文档,有关 SuspenseReact.lazy 的更多信息,请参阅 React 文档中的 代码分割