使用 Deno 进行服务器端渲染 React 应用
简介
我最喜欢的两样东西是 React 和恐龙。
在本文中,我将展示如何将它们组合在一起,使用Deno开发一个服务端渲染的React应用程序。
项目设置
我假设我们都熟悉 React 和 Deno。Deno 比较新,如果你不知道如何安装和使用,我强烈建议你在深入阅读本文之前先阅读一下这篇精彩的介绍。
现在让我们开始创建本教程所需的项目结构和文件。我使用的是Visual Studio Code,但任何编辑器都可以。
打开终端并输入:
mkdir deno-react-ssr && cd $_
code .
这将创建一个名为 的新文件夹deno-react-ssr
,并用 vscode 打开它。
在这个文件夹中,我们需要创建三个文件,app.tsx
分别包含 React 组件的代码、server.tsx
服务器代码以及deps.ts
所有依赖项。你可以将其视为我们的版本package.json
。
最终你将得到如下结构:
.
├── app.tsx
├── deps.ts
└── server.tsx
设置依赖项
我们deps.ts
必须导出此应用程序运行所需的所有依赖项。
复制以下代码并将其添加到您的文件中。
// @deno-types="https://deno.land/x/types/react/v16.13.1/react.d.ts"
import React from 'https://jspm.dev/react@16.13.1';
// @deno-types="https://deno.land/x/types/react-dom/v16.13.1/server.d.ts"
import ReactDOMServer from 'https://jspm.dev/react-dom@16.13.1/server';
export { React, ReactDOMServer }
export { Application, Context, Router } from 'https://deno.land/x/oak@v4.0.0/mod.ts';
如你所见,在 Deno 中,你可以直接从 URL 导入模块。
我决定按照第三方模块文档中的建议,从jspm导入 React 和 ReactDOMServer ,但你也可以使用任何其他提供相同模块的 CDN。
你可能会注意到一个不寻常的事情:// @deno-types="https://deno.land/x/types/react/v16.13.1/react.d.ts"
由于我们使用的是 TypeScript,这行代码会告知 Deno 需要导入的类型的位置,并会影响import
后面的语句。更详尽的解释可以在Deno 类型提示手册中找到。
我还决定使用Oak ,这是 Deno 的 http 服务器的中间件框架,它还提供路由器,因此除了Context
typescript 所需的类型之外,我还导入了我们将在服务器中使用的所有模块。
创建你的 React 组件
app.tsx
我们的组件看起来是这样的:
import { React } from "./deps.ts";
const App = () => {
const [count, setCount] = React.useState(0);
const garden = {
backgroundColor: 'green',
height: 'auto',
fontSize: '30px',
maxWidth: '400px',
padding: '20px 5px',
width: '100%'
};
return (
<div className="pure-g pure-u">
<h2>My DenoReact App</h2>
<button className="pure-button" onClick={() => setCount(count + 1)}>Add a 🦕 in your garden!</button>
<p style={garden}>
{ Array(count).fill(<span>🦕</span>) }
</p>
</div>
);
};
export default App;
与任何标准 React 组件一样,我们首先从deps.ts
文件中导入 React。
然后我们将声明我们的 App 组件,该组件使用钩子来实现一个简单的按钮计数器,让您可以在您的个人花园中添加任意数量的恐龙!
设置服务器
对于服务器,我使用Oak,其中的代码server.tsx
如下所示:
import {
Application,
Context,
React,
ReactDOMServer,
Router,
} from './deps.ts';
import App from "./app.tsx";
const PORT = 8008;
const app = new Application();
const jsBundle = "/main.js";
const js =
`import React from "https://jspm.dev/react@16.13.1";
import ReactDOM from "https://jspm.dev/react-dom@16.13.1";
const App = ${App};
ReactDOM.hydrate(React.createElement(App), document.getElementById('app'));`;
const html =
`<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/purecss@2.0.3/build/pure-min.css">
<script type="module" src="${jsBundle}"></script>
</head>
<body>
<main id="app">${ReactDOMServer.renderToString(<App />)}</main>
</body>
</html>`;
const router = new Router();
router
.get('/', (context: Context) => {
context.response.type = 'text/html';
context.response.body = html;
})
.get(jsBundle, (context: Context) => {
context.response.type = 'application/javascript';
context.response.body = js;
});
app.use(router.routes());
app.use(router.allowedMethods());
console.log(`Listening on port ${PORT}...`);
await app.listen({ port: PORT });
与往常一样,我们需要导入服务器中所需的所有依赖项。
我们还会导入之前创建的应用程序,正如您所见,该扩展.tsx
在 Deno 中是必需的,所以不要忘记它!
下一步是创建 Oak 服务器应用程序,我们还需要定义一些路由:
'/'
将提供包含渲染应用程序的 HTML 页面。'/main.js'
将提供我们需要的应用程序代码,以补充客户端 React 应用程序。
最后,我们告诉应用程序使用刚刚创建的路由,并开始监听端口8008
。你可能注意到我还使用了router.allowedMethods()
,它是一个中间件,用于在路由不被允许时通知客户端。
运行应用程序
运行我们刚刚创建的 SSR React 应用程序非常简单,只需要使用以下命令:
deno run --allow-net ./server.tsx
Deno 默认是安全构建的,这意味着 Deno 应用程序将无法访问你的网络。为了解决这个问题,我们只需要使用 Deno 的--allow-net
flag。
现在,只需打开http://localhost:8008/
并享受你的新应用即可!
结论
我希望您喜欢本文中介绍的简短教程,并且我期待看到接下来会发生什么以及如何使用此堆栈构建更复杂的应用程序。
如果您仍然不清楚我们所做的任何事情或想要完整的代码参考,这里是GitHub 存储库。
文章来源:https://dev.to/akqa_leap/server-side-rendering-react-app-with-deno-14nd