【发布时间】:2018-09-24 21:20:45
【问题描述】:
我正在使用 React an Apollo 2 构建一个应用程序,并且我正在尝试编写一个脚本来生成用于服务器端渲染的静态 html 文件。
我目前正在使用这个逻辑在服务器上渲染我的 React 组件,它工作正常:
export default (Page) => (req, res) => {
const App = (
<ApolloProvider client={client(fetch)}>
<Main>
<Page />
</Main>
</ApolloProvider>
);
getDataFromTree(App).then(() => {
const data = {
html: ReactDOMServer.renderToString(App),
seo: { title: "Home", description: "" }
};
res.render("index", { data });
});
}
但我想生成.html 文件,这样我就可以静态地为它们提供服务,而无需每次都运行此方法。我尝试将renderToString 的结果编译为.ejs 文件,然后使用fs 写入文件,但没有成功。这是代码:
const component = ReactDOMServer.renderToString(App);
const template = ejs.compile(fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8'));
const html = template({ component });
fs.writeFile(
path.join(__dirname, "../views/landing.ejs"),
html,
err => {
if(err) console.log(err);
else console.log("done.");
});
文件已成功写入,但如果我打开我的页面源,则编译方法添加的部分显示为灰色,似乎被忽略了:
我也尝试读取文件并使用.replace 替换字符串并插入一个虚拟div,但结果始终相同。
// using compile
const template = ejs.compile(fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8'));
const html = template({ component });
const template = ejs.compile(fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8'));
const html = template({ component: "<div>teste</div>" });
// using readFile
const template = fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8');
const html = template.replace("<%- component %>", component);
const template = fs.readFileSync(path.join(__dirname, 'landing_template.ejs'), 'utf-8');
const html = template.replace("<%- component %>", "<div>teste</div>");
// maybe this is the problem?
fs.writeFile(
path.join(__dirname, "../views/landing.ejs"),
html,
{ encoding: "utf8" },
err => {
if(err) console.log(err);
else console.log("done.");
});
我猜浏览器没有将这个新文本识别为 HTML 并且无法解析它。有谁知道我可以使这项工作的方法吗?
谢谢!
【问题讨论】:
-
我认为 HTML 代码的问题是
-
脚本标签不是自闭合标签。即使
<script></script>之间没有任何内容,您也不能只使用<script/>
标签: javascript html node.js ejs server-side-rendering