Parcel Bundler 和 React 服务器端渲染
Posted
技术标签:
【中文标题】Parcel Bundler 和 React 服务器端渲染【英文标题】:Parcel Bundler & React Server Side Rendering 【发布时间】:2020-04-22 13:14:15 【问题描述】:当我使用 React 服务器端渲染时,我正在尝试使用 Parcel Bundler 作为客户端文件的捆绑器。
我已使用 Parcel 中间件并为其分配了我的客户端入口点的位置。
当我启动我的脚本时,它显示 Parcel 正在捆绑我的文件,但是我的 ReactDOM.hydrate 方法从未被调用,而且似乎捆绑器根本没有使用该文件。
这是我的 server.js 文件:
import Bundler from 'parcel-bundler';
import express from 'express';
import renderer from './Helpers';
const app = express();
const bundler = new Bundler(__dirname + '/index.js');
app.use(express.static('public'));
app.use(bundler.middleware());
app.get('*', (req, res) =>
const context = ;
const content = renderer(req, context);
if (context.url) return res.redirect(301, context.url);
if (context.notFound) res.status(404);
res.send(content);
);
const listeningPort = 5000;
app.listen(listeningPort, () =>
console.log(`Server is now live on port $listeningPort.`);
这是我的 index.js 文件:
import React from 'react';
import ReactDOM from 'react-dom';
import BrowserRouter from 'react-router-dom';
import routes as Routes from './Routes';
const routes = Routes;
if (process.env.NODE_ENV === 'development')
ReactDOM.render(
<BrowserRouter>
routes
</BrowserRouter>,
document.querySelector('#root'));
else
ReactDOM.hydrate(
<BrowserRouter>
routes
</BrowserRouter>,
document.querySelector('#root'));
这是我的渲染器文件,它基本上渲染了 html 文件:
import React from 'react';
import renderToString from 'react-dom/server';
import StaticRouter from 'react-router-dom';
import routes as Routes from '../Routes';
const routes = Routes;
export default (req, context) =>
const content = renderToString(
<StaticRouter location=req.path context=context>
routes
</StaticRouter>
);
const lang = "en";
return `
<!DOCTYPE html>
<html lang="$lang">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="apple-mobile-web-app-capable" content="yes">
<link href="./public/plugin/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<link href="./public/plugin/font-awesome/css/fontawesome-all.min.css" rel="stylesheet" />
<link href="./public/plugin/et-line/style.css" rel="stylesheet" />
<link href="./public/plugin/themify-icons/themify-icons.css" rel="stylesheet" />
<link href="./public/plugin/owl-carousel/css/owl.carousel.min.css" rel="stylesheet" />
<link href="./public/plugin/magnific/magnific-popup.css" rel="stylesheet" />
<link href="./public/css/style.css" rel="stylesheet" />
<link href="./public/css/color/default.css" rel="stylesheet" id="color_theme" />
</head>
<body>
<div id="root">$content</div>
</body>
</html>
`;
;
应用程序在 StaticRouter 中运行并加载内容,但从不执行 Hydrate。
【问题讨论】:
这里的一个问题是它正在从您的前端代码中读取 process.env 变量,这可能会崩溃。 【参考方案1】:我终于使用以下示例项目解决了我的问题。
https://github.com/reactivestack/parcel-react-s-s-r
基本上解决方案是不使用 Bundler Middleware,而是将客户端和服务器端分别与 Parcel 捆绑,然后运行项目。
【讨论】:
以上是关于Parcel Bundler 和 React 服务器端渲染的主要内容,如果未能解决你的问题,请参考以下文章
parcel-bundler 中的 .cache 文件夹是啥?是不是需要将 .cache 文件夹推送到 Github?
如何修复在 Parcel.js 中运行的服务器上的“未找到条目”
使用终端安装 Parcel Bundler 时如何修复权限错误
Parcel Bundler - 处理 scss 而不解析我的 sass 中的任何 url