我是Apollo和Graph QL的新手,需要弄清楚如何在此项目中使用react-helmet-async。
这些示例对于现有应用的设置方式并没有多大意义。
我的reactMiddleware.js文件代码如下。有人可以帮我弄清楚如何使用此设置来实现反应头盔异步吗?
// @ts-check
const { ApolloClient } = require('apollo-client');
const { createHttpLink } = require('apollo-link-http');
const { InMemoryCache } = require('apollo-cache-inmemory');
const { getLoadableState } = require('loadable-components/server');
const fetch = require('node-fetch').default;
const React = require('react');
const { renderToStringWithData } = require('react-apollo');
const { renderToString } = require('react-dom/server');
const { StaticRouter } = require('react-router');
function serialize(data) {
if (!data) {
return '';
}
const serialized = JSON.stringify(data);
return serialized.replace(/</g, '\\u003c');
}
const isJS = /\.js$/;
const isCSS = /\.css$/;
/**
* @return {import('express').Handler}
*/
module.exports = function reactMiddleware(assets) {
const createApp = require('../server');
// Grab chunks from the Webpack stats
let runtime = assets['runtime~index'];
if (Array.isArray(runtime)) {
runtime = runtime.find(file => isJS.test(file));
}
const styles = assets.styles.filter(
file => isJS.test(file) || isCSS.test(file),
);
const stylesheet = styles.find(file => isCSS.test(file));
const styleScript = styles.find(file => isJS.test(file));
let index = assets.index;
if (Array.isArray(index)) {
index = index.find(file => isJS.test(file));
}
return function(req, res, next) {
// First, set up the prerequisites. We need:
// 1. a router to surround the app with, and
// 2. an Apollo GraphQL client.
// Used to capture information from the route rendering (e.g., 404 status codes)
const context = {};
/** @type {React.SFC} */
const Router = ({ children }) =>
React.createElement(
StaticRouter,
{ context, location: req.path },
children,
);
const client = new ApolloClient({
ssrMode: true,
// @ts-ignore
link: createHttpLink({
uri: 'http://graphql:8080/graphql',
fetch,
}),
cache: new InMemoryCache(),
});
const App = createApp(Router, client);
const root = React.createElement(App);
getLoadableState(root)
.catch(error => {
console.error(error);
return {
getScriptTag() {
return '';
},
};
})
.then(async state => {
let data;
let result;
try {
result = await renderToStringWithData(root);
data = client.extract();
} catch (error) {
console.error(error);
result = renderToString(root);
}
// Send down the custom status code if one was used.
res.status(context.statusCode || 200);
const serialized = serialize(data);
const apolloScriptTag =
serialized &&
`<script>window.__APOLLO_CLIENT_STATE__ = ${serialized}</script>`;
res.header('Content-Type', 'text/html; charset=utf-8');
res.end(`<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/public/${stylesheet}" />
<link rel="print" href="/public/print.css" />
</head>
<body>
<div id="root">${result}</div>
${apolloScriptTag}
${state.getScriptTag()}
<script src="/public/${runtime}"></script>
<script src="/public/${styleScript}"></script>
<script src="/public/${index}"></script>
</body>
</html>`);
})
.catch(error => next(error));
};
};