Help
Support Us

开始上手

Preact 新人?初见虚拟 DOM?先去看看教程吧!

此教程会教您开发 Preact 应用的三种方式。如果您是 Preact 新人,我们推荐您使用 Vite



无构建工具方式

Preact 可在浏览器中直接使用,无需构建或任何工具:

<script type="module">
  import { h, Component, render } from 'https://esm.sh/preact';

  // Create your app
  const app = h('h1', null, 'Hello World!');

  render(app, document.body);
</script>

🔨 在 Glitch 上编辑

此方法的一大缺点是缺少需要构建的 JSX。我们会在下一小节中提供既符合人体工程学,又性能极高的 JSX 替代选项。

JSX 的替代选项

手写 hcreateElement 调用单调乏味。JSX 类似 HTML,这一优势让开发者能轻松理解其语法,但其需要构建步骤。所以,我们强烈推荐 HTM 作为替代选项。

HTM 是可在标准 JavaScript 中使用的类 JSX 语法,此语法于 2015 年添加且支持所有主流浏览器。它通过使用 JavaScript 自带的标记模板语法替代构建步骤。这是一种正在变得热门的 Preact 应用编写方式,减轻了理解传统前端构建工具配置的负担。

<script type="module">
  import { h, Component, render } from 'https://esm.sh/preact';
  import htm from 'https://esm.sh/htm';

  // 为 Preact 初始化 htm
  const html = htm.bind(h);

  function App (props) {
    return html`<h1>Hello ${props.name}!</h1>`;
  }

  render(html`<${App} name="World" />`, document.body);
</script>

🔨 在 Glitch 上编辑

小提示:HTM 还提供了一键 import 的 Preact 版本:

import { html, render } from 'https://esm.sh/htm/preact/standalone'

要了解有关 HTM 的更多信息,请参阅其文档

使用 Vite 快速搭建 Preact 应用

在近几年中,Vite 作为一款多功能框架的应用构建工具,广受欢迎,其中包括用于 Preact 开发。Vite 基于诸如 ES 模块、Rollup 和 ESBuild 等先进技术构建。通过我们的初始化工具 create-preact 或 Vite 提供的 Preact 模板,无需任何配置或了解即可上手,因此它成为了开发 Preact 应用一个非常流行的选择。

顾名思义,create-preact 是一款能在你的电脑终端上运行的命令行工具(Command-Line Interface)。通过执行以下简单命令,你就能轻松创建一个全新的 Preact 应用:

npm init preact

此操作会引导你完成一个全新的 Preact 应用程序的创建过程,并提供一些选项,例如支持 TypeScript、路由(通过 preact-iso)以及 ESLint。

小提示: 你所做的选择并非固定不变。如果将来你改变了想法,总是可以随时在项目中添加或删除这些功能。

准备开发

现在,我们准备好启动应用了。要开启开发服务器,您需要在新生成的项目文件夹内(本例中为 my-preact-app)运行以下命令:

# 切换到项目目录
cd my-preact-app

# 开启开发服务器
npm run dev

服务器启动后,终端会显示一个本地开发用的 URL 地址。现在,您可以开始编写应用代码了!

生产模式构建

当您准备将应用部署到服务器时,Vite 提供了一个实用的 build 命令,用于生成高效的生产模式构建。

npm run build

构建完成后,您将获得一个名为 dist/ 的新文件夹,可直接部署到您的服务器上。

要了解所有可用命令及其选项,您可以参阅 Vite CLI 文档

整合进现有工具

如果您的项目已经有一些前端工具的话,那么您也可能安装了打包工具,可能是 webpackrollupparcel。Preact 原生支持它们,无需您做出任何改动!

配置 JSX

您需要一款 Babel 插件才能将 JSX 转译为 JavaScript 代码。我们使用的是 @babel/plugin-transform-react-jsx。安装后,您需要为 JSX 指定该使用的函数:

{
  "plugins": [
    ["@babel/plugin-transform-react-jsx", {
      "pragma": "h",
      "pragmaFrag": "Fragment",
    }]
  ]
}

Babel 的教程很不错,我们强烈建议您在配置 Babel 或遇到其相关问题时参阅它。

将 React 替名为 Preact

某些时候,您可能会想使用一部分 React 生态。为 React 编写的第三方库或组件可通过兼容层无缝使用。为此,我们需要先将所有的 reactreact-dom 导入指向 Preact。此流程我们称之为替名 (Aliasing)。

小提示:如果您使用 Preact CLI 的话,我们已自动为您处理替名步骤。

Webpack 中的替名

要在 Webpack 中为包替名,您需要在配置中添加 resolve.alias 一节。根据您配置的不同,此配置可能已经存在,但缺少 Preact 的替名。

const config = { 
   //...snip
  "resolve": { 
    "alias": { 
      "react": "preact/compat",
      "react-dom/test-utils": "preact/test-utils",
      "react-dom": "preact/compat",     // 必须放在 test-utils 下面
      "react/jsx-runtime": "preact/jsx-runtime"
    },
  }
}

Node 中的替名

在 Node.JS 服务器 (如 Next.js) 上,Webpack 替名无法正常工作。我们需要在 package.json 中添加替名。

{
  "dependencies": {
    "react": "npm:@preact/compat",
    "react-dom": "npm:@preact/compat",
  }
}

现在,Node 可以正确使用 Preact 取代 React 了。

Parcel 中的替名

Parcel 使用标准的 package.json 文件中的 alias 键来读取替名。

{
  "alias": {
    "react": "preact/compat",
    "react-dom/test-utils": "preact/test-utils",
    "react-dom": "preact/compat",
    "react/jsx-runtime": "preact/jsx-runtime"
  },
}

Rollup 中的替名

要在 Rollup 中替名,您需要先安装 @rollup/plugin-alias。此插件需要放在 @rollup/plugin-node-resolve 前。

import alias from '@rollup/plugin-alias';

module.exports = {
  plugins: [
    alias({
      entries: [
        { find: 'react', replacement: 'preact/compat' },
        { find: 'react-dom/test-utils', replacement: 'preact/test-utils' },
        { find: 'react-dom', replacement: 'preact/compat' },
        { find: 'react/jsx-runtime', replacement: 'preact/jsx-runtime' }
      ]
    })
  ]
};

Jest 中的替名

Jest 可以类似打包器的方式重写模块路径。重写路径可在您的 Jest 配置中通过正则表达式实现。

{
  "moduleNameMapper": {
    "^react$": "preact/compat",
    "^react-dom/test-utils$": "preact/test-utils",
    "^react-dom$": "preact/compat",
    "^react/jsx-runtime$": "preact/jsx-runtime"
  }
}

Snowpack 中的别名

要在 Snowpack 中添加别名,您需要在 snowpack.config.mjs 文件中添加包导入别名。

// snowpack.config.mjs
export default {
  alias: {
    "react": "preact/compat",
    "react-dom/test-utils": "preact/test-utils",
    "react-dom": "preact/compat",
    "react/jsx-runtime": "preact/jsx-runtime",
  }
}

为 preact/compat 配置 TypeScript

您的项目可能需要更广的 React 生态的支持。为了让您的应用得以编译,您可能需要先关闭 node_modules 路径的类型检查,并以类似如下方式添加类型路径。这样,您的别名才能在第三方库导入 React 时正常被替换。

{
  "compilerOptions": {
    ...
    "skipLibCheck": true,
    "baseUrl": "./",
    "paths": {
      "react": ["./node_modules/preact/compat/"],
      "react/jsx-runtime": ["./node_modules/preact/jsx-runtime"],
      "react-dom": ["./node_modules/preact/compat/"],
      "react-dom/*": ["./node_modules/preact/compat/*"]
    }
  }
}