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 ReactDOM from "react-dom";
import { App } from "./App";
const app = document.getElementById("app");
ReactDOM.render(<App />, app); export function App() {
return <h1>Hello world!</h1>;
} 正如你所看到的,我们已经从 HTML 文件中的<script>元素中引用了index.js。这个导入的react-dom并用它将我们的App组件渲染到我们页面中的<div id="app">元素中。
有关开始使用新项目的更多详细信息,请参阅Building a web app with Parcel。
JSX
#Parcel 在检测到您正在使用 React 时会自动支持 JSX。如果您使用的是 React 17 或更高版本,它还会自动启用modern JSX transform,这意味着您甚至不需要导入 React 即可使 JSX 工作,正如您 App.js 在上面的示例中所见。
要了解有关 JSX 的更多信息,请参阅 React 文档中的Introducing JSX,JSX In Depth以及 Parcel 的 JavaScript 文档JSX部分,以获取有关如何配置其处理方式的一些详细信息的详细信息。
快速刷新
#Parcel 对React Fast Refresh有一流的支持,在编辑代码时不需要重新加载页面就可以得到快速反馈。在大多数情况下,它可以在编辑代码时保留组件状态,即使您出错。参见Hot reloading文档了解详细的工作原理。
提示
#- 避免类组件 – 快速刷新仅适用于函数组件(和 Hooks)。
- 仅导出 React 组件 – 如果一个文件混合了 React 组件和其他类型的值,则其状态将在其更改时重置。要保留状态,请仅导出 React 组件并尽可能将其他导出移动到不同的文件。
- 避免未命名的默认导出 – 使用默认导出箭头函数声明组件将导致状态在更改时被重置。使用命名函数,或将箭头函数分配给变量。
- 将入口组件保存在它们自己的文件中 – 入口组件应该与调用
ReactDOM.render的文件分开放置,否则每次更改都会重新挂载它们。
有关更多提示,请参阅官方React Fast Refresh docs。
TypeScript
#TypeScript支持开箱即用。您可以从您的 HTML 页面引用.ts或.tsx文件,Parcel 将按照您的预期编译它。
要为 React 添加 TypeScript 定义,请将以下包安装到您的项目中:
yarn add @types/react @types/react-dom --dev 有关将 TypeScript 与 Parcel 一起使用的更多详细信息,请参阅TypeScript。
Flow
#安装时自动支持Flow。要将其添加到现有项目,首先安装flow-bin为依赖项:
yarn add flow-bin --dev 然后,使用// @flow您要输入检查的文件顶部的指令。这也向 Parcel 发出信号,哪些文件可以具有在为浏览器编译时应该剥离的 Flow 类型。
有关将 Flow 与 Parcel 一起使用的更多详细信息,请参阅Flow。
Styling
#Parcel 支持多种使用 React 编写的样式应用程序的不同方式。
CSS
#您可以将 CSS 文件导入 JavaScript 或 TypeScript 文件以将其与组件一起加载。
import './Button.css';
export function Button({ children }) {
return (
<button className="button">
{children}
</button>
);
} .button {
background: hotpink;
} 您还可以使用<link rel="stylesheet">HTML 文件中的标准元素加载 CSS,但从组件中引用 CSS 有助于明确哪些组件依赖于哪些 CSS。这也有助于代码拆分,因为只会加载您呈现的组件所需的 CSS。
Parcel 还支持 CSS 语言,如SASS, Less, 和Stylus。有关 Parcel 如何处理,请参阅 CSS。CSS。
CSS modules
#默认情况下,从 JavaScript 导入的 CSS 是全局的。如果两个 CSS 文件定义了相同的类名,它们可能会发生冲突并相互覆盖。为了解决这个问题,Parcel 支持CSS modules。
CSS modules 将每个文件中定义的类视为唯一的。每个类名都被重命名以包含唯一的哈希,并且映射被导出到 JavaScript 以允许引用这些重命名的类名。
要使用 CSS modules,请创建一个带有.module.css扩展名的文件,然后从带有namespace import的 JavaScript 文件中导入它。然后,您可以在 JSX 中渲染元素时使用 CSS 模块的导出。
import * as classes './Button.module.css';
export function Button({ children }) {
return (
<button className={classes.button}>
{children}
</button>
);
} .button {
background: hotpink;
} 请参阅CSS modules以了解有关 Parcel 如何处理 CSS 模块的更多信息。
CSS-in-JS
#CSS-in-JS 库,如Styled Components, Emotion和许多其他库都可以很好地与 Parcel 配合使用。有些可能需要构建配置,例如Babel插件。要启用它,请在您的项目中创建一个 Babel 配置,Parcel 会自动选择它。
例如,要使用 Emotion,请安装 Babel 插件并在您的项目中创建一个:.babelrc:
yarn add @emotion/babel-plugin --dev
yarn add @emotion/react {
"plugins": ["@emotion/babel-plugin"]
} 您还需要在tsconfig.json或jsxImportSource中设置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 mode通过仅编译您使用的类来加速构建。确保修改传递给content选项的 glob,使其与您将使用 Tailwind 类的所有源文件匹配。
{
"plugins": {
"tailwindcss": {}
}
} module.exports = {
content: ["./src/*.{html,js}"],
theme: {
extend: {},
},
variants: {},
plugins: [],
}; 最后,你可以从任何匹配tailwind.config.js中列出的contentglob 文件中引用 Tailwind 类。
export function Button({ children }) {
return (
<button className="p-2 rounded bg-blue-500 hover:bg-blue-600 transition">
{children}
</button>
);
} 图片 Images
#您可以使用URL构造函数引用 JSX 的外部图像。Parcel 还支持使用query parameters调整图像大小并将其转换为不同的格式。它还处理图像优化,并在输出文件名中包含一个content hash,用于长期的浏览器缓存。
const logo = new URL('logo.svg', import.meta.url);
export function Logo() {
return <img src={logo} alt="logo" />;
} 请参阅 JavaScript 文档中的URL dependencies了解更多关于这种语法的细节,参阅Image文档了解更多关于 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 文档中的 Importing as a React component。
有关 Parcel 如何转换和优化 SVG 文件的更多信息,请参阅 SVG 文档。
代码拆分 Code splitting
#代码拆分通过延迟加载应用程序的各个部分来帮助减少初始页面加载大小。这可以通过使用动态 import() 语法以及 React.lazy 来完成。
此示例在用户单击按钮时延迟加载“配置文件”组件。当它看到动态的 import() 时,Parcel 将 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 中代码拆分的更多详细信息,请参阅 代码拆分 Code Splitting 文档,以及 React 中的 代码拆分 Code Splitting更多关于 Suspense 和 React.lazy 的文档。