React

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

¥Parcel works great for building single or multi-page React applications. It includes a first-class development experience with Fast Refresh, and supports JSX, TypeScript, Flow, and many styling methodologies out of the box.

入门

#

¥Getting started

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

¥First, install react and react-dom into your project:

yarn add react react-dom

大多数 Parcel 应用都以 HTML 文件开始。Parcel 遵循依赖(例如 <script> 标签)从那里构建你的应用。

¥Most Parcel apps start with an HTML file. Parcel follows the dependencies (such as a <script> tag) from there to build your app.

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"> 元素中。

¥As you can see, we’ve referenced index.js from a <script> element in our HTML file. This imported react-dom and used it to render our App component into the <div id="app"> element in our page.

有关开始新项目的更多详细信息,请参阅 使用 Parcel 构建 Web 应用

¥See Building a web app with Parcel for more details on getting started with a new project.

JSX

#

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

¥Parcel supports JSX automatically when it detects you are using React. If you’re using React 17 or later, it also automatically enables the modern JSX transform, which means you don't even need to import React for JSX to work, as you can see in App.js in the above example.

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

¥To learn more about JSX, see Introducing JSX and JSX In Depth in the React docs, and the JSX section from Parcel's JavaScript docs for details on how you can configure some details of how it's handled.

快速刷新

#

¥Fast Refresh

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

¥Parcel has first-class support for React Fast Refresh, which gives you quick feedback as you edit your code without needing to reload the page. In most cases, it can preserve component state as code is edited, even if you make an error. See the Hot reloading docs for details on how this works.

提示

#

¥Tips

更多提示请参见官方 React 快速刷新文档

¥For more tips, see the official React Fast Refresh docs.

TypeScript

#

开箱即用支持 TypeScript。你可以从 HTML 页面引用 .ts.tsx 文件,Parcel 将按照你的预期对其进行编译。

¥TypeScript is supported out of the box. You can reference a .ts or .tsx file from your HTML page, and Parcel will compile it as you'd expect.

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

¥To add TypeScript definitions for React, install the following packages into your project:

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

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

¥See the TypeScript docs for more details on using TypeScript with Parcel.

Flow

#

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

¥Flow is supported automatically when it is installed. To add it to an existing project, first install flow-bin as a dependency:

yarn add flow-bin --dev

然后,在你想要类型检查的文件顶部使用 // @flow 指令。这也向 Parcel 发送信号,告知哪些文件可以具有在为浏览器编译时应删除的 Flow 类型。

¥Then, use the // @flow directive at the top of the files you'd like to type check. This also signals to Parcel which files can have Flow types that should be stripped when compiling for the browser.

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

¥See the Flow docs for more details on using Flow with Parcel.

样式

#

¥Styling

Parcel 支持使用 React 编写的多种不同的应用样式设计方式。

¥Parcel supports many different ways of styling applications written with React.

CSS

#

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

¥You can import a CSS file into a JavaScript or TypeScript file to load it along with a component.

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。

¥You can also load CSS using a standard <link rel="stylesheet"> element in your HTML file, but referencing CSS from your components helps make it clear which components depend on which CSS. This can also help with code splitting because only the CSS necessary for the components that you render will be loaded.

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

¥Parcel also supports CSS languages like SASS, Less, and Stylus. See CSS for more details on how CSS is processed by Parcel.

CSS 模块

#

¥CSS modules

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

¥By default, CSS imported from JavaScript is global. If two CSS files define the same class names, they will potentially clash and overwrite each other. To solve this, Parcel supports CSS modules.

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

¥CSS modules treat the classes defined in each file as unique. Each class name is renamed to include a unique hash, and a map is exported to JavaScript to allow referencing these renamed class names.

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

¥To use CSS modules, create a file with the .module.css extension, and import it from a JavaScript file with a namespace import. Then, you can use the exports of the CSS module when rendering elements in JSX.

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;
}

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

¥See CSS modules to learn more about how Parcel handles CSS modules.

JS 中的 CSS

#

¥CSS-in-JS

CSS-in-JS 库(例如 样式组件情感 等)可以与 Parcel 配合良好。有些可能需要构建配置,例如 Babel 插件。要启用它,请在项目中创建 Babel 配置,Parcel 将自动选择它。

¥CSS-in-JS libraries like Styled Components, Emotion, and many others work well with Parcel. Some may require build configuration, such as a Babel plugin. To enable it, create a Babel configuration in your project and Parcel will pick it up automatically.

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

¥For example, to use Emotion, install the Babel plugin and create a .babelrc in your project:

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

你还需要在 tsconfig.jsonjsconfig.json 中设置 jsxImportSource 选项,以便使用 Emotion 的 JSX 编译指示而不是默认编译指示。这使得 css 属性能够工作。

¥You’ll also need to set the jsxImportSource option in a tsconfig.json or jsconfig.json so that Emotion's JSX pragma is used instead of the default one. This enables the css prop to work.

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

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

¥Now, you can render elements with 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 文件。

¥Tailwind CSS is a popular utility-first CSS framework. It uses PostCSS to build a CSS file containing only the classes you use in your code.

要使用它,首先安装必要的依赖:

¥To use it, first, install the necessary dependencies:

yarn add tailwindcss postcss autoprefixer --dev

接下来,创建 PostCSS 和 Tailwind 所需的配置文件。此示例将使用 Tailwind 的 即时模式 通过仅编译你使用的类来加速构建。确保修改传递给 content 选项的 glob,以便它与你将使用 Tailwind 类的所有源文件匹配。

¥Next, create the config files needed for PostCSS and Tailwind. This example will use Tailwind’s JIT mode to speed up builds by only compiling the classes you use. Make sure you modify the glob passed to the content option so it matches all of the source files where you'll use Tailwind classes.

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

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

¥Finally, you can reference Tailwind classes from any files that match the content glob listed in tailwind.config.js.

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

图片

#

¥Images

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

¥You can reference external images from JSX using the URL constructor. Parcel also supports using query parameters to resize and convert images to a different format. It also handles image optimization, and includes a content hash in output filenames for long term browser caching.

Logo.js:
const logo = new URL('logo.svg', import.meta.url);

export function Logo() {
return <img src={logo} alt="logo" />;
}

有关此语法的更多详细信息,请参阅 JavaScript 文档中的 URL 依赖,有关 Parcel 如何处理图片的更多信息,请参阅 图片 文档。

¥See URL dependencies in the JavaScript docs for more details about this syntax, and the Image docs for more information about how Parcel handles images.

SVG

#

可以如上所述引用外部 SVG 文件。你还可以导入 SVG 作为 React 组件,这些组件可以直接在 JSX 中渲染。

¥External SVG files can be referenced as described above. You can also import SVGs as React components which can be rendered directly in JSX.

首先,安装 @parcel/transformer-svg-react 插件并将其添加到你的 .parcelrc 中:

¥First, install the @parcel/transformer-svg-react plugin and add it to your .parcelrc:

yarn add @parcel/transformer-svg-react --dev
.parcelrc:
{
"extends": "@parcel/config-default",
"transformers": {
"*.svg": ["...", "@parcel/transformer-svg-react"]
}
}

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

¥Now, you can import SVGs from your component files and render them just like any other component.

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

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

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

¥The above example showed how to convert every SVG file to JSX, but you may want to be more selective in some cases. See Importing as a React component in the SVG docs for more details.

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

¥See the SVG docs for more about how Parcel transforms and optimizes SVG files.

代码分割

#

¥Code splitting

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

¥Code splitting helps reduce initial page load size by lazily loading sections of your app. This can be accomplished by using the dynamic import() syntax, along with React.lazy.

此示例在用户单击按钮时延迟加载 Profile 组件。当看到动态 import() 时,Parcel 会将 Profile 组件移动到与 Home 组件不同的单独包中,并按需加载。React.lazy 负责将其转换为组件,Suspense 负责在加载时渲染后备。

¥This example lazily loads a Profile component when a user clicks a button. When it sees the dynamic import(), Parcel moves the Profile component into a separate bundle from the Home component and loads it on demand. React.lazy handles turning this into a component, and Suspense handles rendering a fallback while it is loading.

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 文档中的 代码分割

¥See the Code Splitting docs for more details about code splitting in Parcel, and Code Splitting in the React docs for more about Suspense and React.lazy.

Parcel 中文网 - 粤ICP备13048890号