我目前正在开发一个其他人构建的项目,我被要求实现服务器端渲染,这是一个巨大的项目,它使用基于“构建器 JSON”的自定义路由系统,该主组件选择要渲染的组件基于路线,它旨在保持应用程序动态并适应多个客户的需求。
我一直在到处寻找答案,但我对 SSR 很陌生,这是一个很大的挑战。
我目前正在测试一种使用 express 的方法,如下所示:
import 'babel-polyfill';
import express from 'express';
import React from 'react';
import ReactDOMServer from 'react-dom/server';
import { StaticRouter } from 'react-router';
import bodyParser from 'body-parser';
import { App } from '../src/App';
const app = express();
const PORT = process.env.PORT || 8000;
app.use(bodyParser.json());
app.use(express.static('ssrBuild'))
app.get('*', (req, res) => {
const context = {}
const content = ReactDOMServer.renderToString(
<StaticRouter location={req.url} context={context}>
<App />
</StaticRouter>
);
const html = `
<html>
<head>
</head>
<body>
<div id="root">
${content}
</div>
</body>
</html>
`;
res.send(html);
});
app.listen(PORT, () => {
console.log(`App running on port ${PORT}`);
});
我目前遇到的问题是 App 组件从 node_modules 中的另一个存储库调用“复杂路由组件”(也由它们构建),我的 webpack 配置正在获取 App 组件并找到 jsx,这显然不能在服务器。
网络包配置:
const path = require('path');
const webpackNodeExternals = require('webpack-node-externals');
module.exports = {
target: 'node',
entry: {
server: './ssr/server.js',
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, '..', 'ssrBuild'),
publicPath: '/ssrBuild'
},
module: {
rules: [
{
test: /\js$/,
loader: 'babel-loader',
exclude: '/node_modules/',
options: {
presets: [
'@babel/react',
['@babel/preset-env', {
targets: { browsers: ['last 2 versions'] }
}]
],
plugins: [
['@babel/plugin-proposal-decorators', { 'legacy': true }],
'@babel/plugin-proposal-class-properties',
'@babel/plugin-syntax-function-bind',
'@babel/plugin-transform-async-to-generator',
'@babel/plugin-proposal-export-default-from',
'babel-plugin-jsx-control-statements',
'react-hot-loader/babel',
'lodash',
]
}
}
]
},
externals: [webpackNodeExternals()]
}
有没有办法告诉webpack“随时随地”转换node_modules文件夹中的jsx?还有什么其他的解决方案?
此外,这个项目的重点是改进这些应用程序的 SEO,我只需要 SSR 索引页面和指向其中内容的任何直接链接。不需要对整个应用程序进行 SSR 有没有办法可以实现?
我还想知道,如果这仅适用于索引页面和任何直接链接,那么重构整个应用程序以使用 Next.js 是否值得。
先感谢您!