在 Deno 中编写 React SSR 应用程序 安装 入门 运行我们的 React SSR 应用程序 后续步骤

2025-06-04

在 Deno 中编写 React SSR 应用程序

安装

入门

运行我们的 React SSR 应用程序

后续步骤Next steps

正如Ryan Dahl在Open JS World 2020中所介绍的那样。

Deno v1 已经发布并在 JavaScript 社区引起了轰动。

对于那些还没有接触过 Deno 的人来说,它是 Web 浏览器之外的 JavaScript 和 TypeScript 的新运行时。它基于 V8 JavaScript 引擎,用 Rust 编写,由 Node.js 的创始人 Ryan Dahl 创建。

如果您想了解有关 Deno 及其使命的更多信息,请查看由创建者撰写的Deno 1.0 发布博客文章。

背景介绍完毕,让我们开始在 Deno 中编写我们的 React SSR 应用程序!

安装

Deno 可以使用所有主要的软件包安装程序以及官方安装程序脚本进行安装。以下是一些主要的安装方法:

Shell(Mac、Linux):

curl -fsSL https://deno.land/x/install/install.sh | sh
Enter fullscreen mode Exit fullscreen mode

PowerShell(Windows):

iwr https://deno.land/x/install/install.ps1 -useb | iex
Enter fullscreen mode Exit fullscreen mode

自制(Mac):

brew install deno
Enter fullscreen mode Exit fullscreen mode

巧克力味(Windows):

choco install deno
Enter fullscreen mode Exit fullscreen mode

前往Deno 安装页面了解其他安装方法和更多详细信息!

入门

请注意,Deno 正在快速发展,这可能会导致像本文这样的文章很快过时。请务必检查所用模块是否有更新版本,以确保代码适用于最新版本的 Deno。

安装 Deno 后,您现在可以运行 make use ofdeno命令了!使用它deno help来探索所提供的命令。稍后我们将使用此命令来运行我们的 React SSR 应用。

但首先让我们创建一个项目!

在新的项目目录中,让我们创建三个文件:

.
├── app.tsx
├── client.tsx
└── server.tsx
Enter fullscreen mode Exit fullscreen mode

app.tsx将包含我们的 React 组件代码,server.tsx将保存我们所有的服务器代码,client.tsx并将作为客户端 bundle 的入口点。请注意获取正确的文件扩展名!

编写我们的客户端包

client.tsx文件中,添加以下代码来设置我们的客户端入口点:

import React from "https://dev.jspm.io/react@16.13.1";
import ReactDOM from "https://dev.jspm.io/react-dom@16.13.1";
import App from "./app.tsx";

(ReactDOM as any).hydrate(
  <App />,
  //@ts-ignore
  document.getElementById("root"),
);
Enter fullscreen mode Exit fullscreen mode

首先,我们像在任何 React 应用程序中一样导入 React 和 React DOM,但不是从导入"react",而是从 url 导入...!?

没错,在 Deno 中,你可以从任何 URL 以及导出模块的相对或绝对文件路径导入模块。这意味着你可以轻松地从网络上拉取任何代码,例如 Gist、GitHub 代码,而不再受限于已发布的版本——如果main你迫不及待地想尝试某个分支上的内容,可以直接导入!

这里我们从JSPM导入了 React 和 React DOM ,但你也可以使用任何提供 React 作为 ES 模块的 CDN。查看Deno 网站了解 CDN 替代方案。

导入 React 库之后,我们导入 App 组件(尚未编写!)并最终使用 React DOM hydrate方法设置代码来呈现我们的应用程序。

现在让我们在 Deno 中编写我们的第一个 React 组件!

编写 React 组件

我们的app.tsx

// @deno-types="https://raw.githubusercontent.com/Soremwar/deno_types/4a50660/react/v16.13.1/react.d.ts"
import React from "https://dev.jspm.io/react@16.13.1";

const App = () => {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <h1>Hello Deno Land!</h1>
      <button onClick={() => setCount(count + 1)}>Click the 🦕</button>
      <p>You clicked the 🦕 {count} times</p>
    </div>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

这里发生了很多事情,让我们来分解一下 -

首先,我们React像在任何 React 应用中一样导入,但请注意,我们还使用了@deno-types提示注释。这使我们能够告知 deno 在哪里可以找到导入模块的 TypeScript 类型——是不是很棒?

您可以选择省略此类型提示,但 TypeScript 会要求您自行提供类型(导入或自定义)。或者,您也可以通过将文件扩展名更改为 来完全避免使用 TypeScript。Deno.jsx开箱即用地支持 TypeScript 和 JavaScript!

最后,我们创建一个名为 的小 React 组件App,它使用 hooks 来创建按钮点击计数器——简单!总的来说,这和用 NodeJS 编写 React 组件没什么区别。

编写服务器

对于服务器,我们将使用 Deno Web 框架Opine,它是 NodeJS 中常用的 ExpressJS Web 框架的一个端口。

以下是我们将要使用的代码server.tsx

// @deno-types="https://raw.githubusercontent.com/Soremwar/deno_types/4a50660/react/v16.13.1/react.d.ts"
import React from "https://dev.jspm.io/react@16.13.1";
import ReactDOMServer from "https://dev.jspm.io/react-dom@16.13.1/server";
import { opine } from "https://deno.land/x/opine@0.25.0/mod.ts";
import App from "./app.tsx";

/**
 * Create our client bundle - you could split this out into
 * a preprocessing step.
 */
const [diagnostics, js] = await Deno.bundle(
  "./client.tsx",
  undefined,
  { lib: ["dom", "dom.iterable", "esnext"] },
);

if (diagnostics) {
  console.log(diagnostics);
}

/**
 * Create our Opine server.
 */
const app = opine();
const browserBundlePath = "/browser.js";

const html =
  `<html><head><script type="module" src="${browserBundlePath}"></script><style>* { font-family: Helvetica; }</style></head><body><div id="root">${
    (ReactDOMServer as any).renderToString(<App />)
  }</div></body></html>`;

app.use(browserBundlePath, (req, res, next) => {
  res.type("application/javascript").send(js);
});

app.use("/", (req, res, next) => {
  res.type("text/html").send(html);
});

app.listen({ port: 3000 });

console.log("React SSR App listening on port 3000");
Enter fullscreen mode Exit fullscreen mode

事情是这样的:

  1. 首先,我们导入主要依赖项ReactOpineReactDOMServer Web框架
  2. 然后,我们导入刚刚创建的 React 应用程序,注意包含.tsx扩展名 - 与 NodeJS 不同,Deno 需要文件扩展名。
  3. 首先,我们使用该Deno.bundle()方法从我们的应用程序创建我们的客户端 JavaScript 包。
  4. 接下来,我们创建一个Opine应用程序,就像使用 ExpressJs 一样,并定义一些路由:一个用于提供包含我们渲染的应用程序的简单 HTML 页面,另一个/browser.js用于为我们的应用程序的客户端包提供服务,以便我们可以在客户端上补充 React 应用程序。
  5. listen()最后我们使用port 上的方法启动服务器3000

就这样!现在我们可以运行我们的 React 应用程序了🎉。

运行我们的 React SSR 应用程序

我们现在可以使用以下deno命令运行我们的 React SSR 应用程序:

deno run --allow-net --allow-read --unstable ./server.tsx
Enter fullscreen mode Exit fullscreen mode

注意各种标志的用法!Deno 和 NodeJS 的一个主要区别在于,Deno 在构建时就考虑到了安全性。任何需要访问 Web、读写文件,甚至使用环境变量的操作,都需要获得相应的权限,Deno 才会允许执行。

要了解更多信息,请查看Deno 手册的Deno 权限部分。

对于我们的示例应用程序,我们需要--allow-net允许我们的服务器访问网络,--allow-read这是 Opine 框架所必需的(因此如果使用它的“视图”功能,它可以读取模板),我们还需要--unstable标志来使用Deno.bundle()仍处于预览状态的 API。

前往http://localhost:3000/瞧!现在你应该能看到你的 React SSR 应用在浏览器中运行了。😄

后续步骤Next steps

这只是一个基本的服务器和应用程序设置,但现在您应该明白,将现有应用程序转换为 Deno 并不需要做太多事情。

就这些了!很想听听你们的想法以及你们使用 Deno 的进展——请在下方留言!


2020 年 6 月 29 日更新:Deno 进展迅速,所有上述 JSX 错误均已解决,因此我已删除本文中对它们的引用!

2020年7月20日更新:如果您在 Deno 1.2.0 发布之前遵循了本教程,您会发现升级后会出现几个与 URL 相关的错误。Deno 1.2.0 对标准库进行了重大更改,因此任何使用 0.61.0 之前标准版本的模块都可能出错!通常,请尝试查看您正在使用的模块是否可以升级到更高版本,如果无法解决问题,请尝试在您遇到问题的仓库上提交一个问题!

文章来源:https://dev.to/craigmorten/writing-a-react-ssr-app-in-deno-2m7
PREV
如何使用 Crawlee 在 Python 中创建 LinkedIn 职位爬虫
NEXT
在 React 中使用 TypeScript 的 useReducer Hook