我一直在阅读很多关于React Server Side Rendering的文章和研究,使用Webpack,Express等常见设置。大多数人使用React + ES6作为组件,将babel-register放在express入口点的开头,以允许在客户端和服务器之间共享用ES6编写的React Routes。其他人,运行宝贝节点来解决这个问题。不幸的是,不建议将babel-register或babel-node用于生产用途,显然建议将其编译为单独的文件进行生产。
// As an example, demonstrating that `production` should not
// require babe-register, but development
if (['staging', 'production'].indexOf(process.env.NODE_ENV) > -1) {
require('./dist/server.prod.js')
} else {
require('babel-register')
require('./server.dev.js')
}
据我所知和测试(除非我错过了我的设置),客户端工作正常(一个捆绑的js文件包含所有路由等);由于语法错误,服务器端呈现失败。构建器将快速ES6代码(服务器)转换为ES5,但不会事先将所有路径组件转换为动态命中的组件!
对于没有Routes的项目,请参阅以下示例,这不是问题,因为App组件是事先导入的,因此构建作业会将其转换为:
router.get('*', (req, res, next) => {
const preloadedState = {'foobar': 1}
const store = configureStore(preloadedState)
const myAppHtml = renderToString(
<Provider store={store}>
<App />
</Provider>
)
const finalState = store.getState()
let html = htmlTemplateString.replace('<div id="app">', '<div id="app">' + myAppHtml)
const preloadedStateScript = `<script>window.__PRELOADED_STATE__ = ${JSON.stringify(finalState).replace(/</g, '\\x3c')}</script>`
html = html.replace('</head>', preloadedStateScript)
res.send(html)
})
虽然服务器中的动态路由发生了变化,但import
会反应ES6组件并导致语法错误。例如:
router.get('*', (req, res) => {
match({routes, location: req.url}, (error, redirectLocation, renderProps) => {
const myAppHtml = renderToString(<RouterContext {...renderProps}/>);
...
})
})
我的问题是关于如何转换所有React ES6组件以避免在制作中使用babel-register或babel-node?
Webpack有一个ExtractTextPlugin,用于将输出中的CSS提取到单个文件中,是否可以对组件执行相同的操作?
我们是否必须运行babel才能将所有React App目录结构转换为一个新目录,该目录仅用于生产中的服务器端呈现?
这些是我在使用路由和匹配路由时发现的关于React Server端渲染的大多数文章中没有找到任何答案的一些问题。
任何提示或建议都表示赞赏!
答案 0 :(得分:0)
您可以在构建过程中转换所有文件,并从转换后的文件中运行服务器。您可以使用webpack。
检查此初始化项目的执行方式:https://github.com/ctrlplusb/react-universally