I am currently working on a project that someone else built and I was asked to implement server side rendering, it's a huge project and it uses a custom routing system based on a "builder JSON" taken by a main component that selects which components to render based on the route, it is meant to keep the app dynamic and to adjust to the needs of several customers.
I have been checking everywhere trying to find an answer but im new to SSR and it's a big challenge.
I am currently testing an approach using express that looks like this:
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}`);
});
The problem I am currently having is that the App component calls the "complex routing component" from another repository in the node_modules (also build by them), my webpack config is taking the App component and finding jsx, which cant obviouly be run in the server.
Webpack config:
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()]
}
Is there a way I can tell webpack to transpile the jsx in the node_modules folder "on the go"? What other solutions could there be?
Also, the whole point of this project is to impprove the SEO for these apps, I would only need to SSR the index page and any direct link to content in it. No need to SSR the entire app is there a way this can be achieved?
I was also wondering if refactoring the entire app to use Next.js would be worth it if this were possible only for the index page and any direct link.
Thank you in advance!