Webpack&Babel:服务器端渲染React组件“Unexpected token”<'“

我一直在调查这个问题3天,但不能得到它的工作。

完整的错误是:

C:\Users\XXXXXX\WebstormProjects\XXXX\server\routes\auth.jsx:58 return res.send(ReactDOMServer.renderToString(<LoginPage />)); ^ SyntaxError: Unexpected token < at createScript (vm.js:56:10) at Object.runInThisContext (vm.js:97:10) at Module._compile (module.js:542:28) at Object.Module._extensions..js (module.js:579:10) at Module.load (module.js:487:32) at tryModuleLoad (module.js:446:12) at Function.Module._load (module.js:438:3) at Module.require (module.js:497:17) at require (internal/module.js:20:19) at Object.<anonymous> (C:\Users\XXXXXX\WebstormProjects\XXXX\index.js:10:20) 

这是我的webpack.config.js:

 const path = require('path'); module.exports = { entry: path.join(__dirname, '/client/src/app.jsx'), output: { path: path.join(__dirname, '/client/dist/js'), filename: 'app.js', publicPath: "/" }, module: { loaders: [{ test: /\.jsx?$/, include: [ path.join(__dirname, '/client/src'), path.join(__dirname, '/server/routes') ], loader: 'babel-loader', query: { babelrc: false, presets: ['es2015', 'stage-2', 'react'] } }], }, devServer: { historyApiFallback: true }, watch: true }; 

现在/server/routes/auth.jsx文件:

 const express = require('express'); const validator = require('validator'); const router = new express.Router(); const React = require('react'); const ReactDOMServer = require('react-dom/server'); const LoginPage = require('../../client/src/containers/LoginPage.jsx'); function validateLoginForm(payload) { const errors = {}; let isFormValid = true; let message = ''; if (!payload || typeof payload.email !== 'string' || payload.email.trim().length === 0) { isFormValid = false; errors.email = 'Please provide your email address.'; } if (!payload || typeof payload.password !== 'string' || payload.password.trim().length === 0) { isFormValid = false; errors.password = 'Please provide your password.'; } if (!payload || typeof payload.password !== 'string' || payload.password.trim().length <= 8) { isFormValid = false; errors.password = 'Please provide a password that\'s more than 8 char'; } if (!isFormValid) { message = 'Check the form for errors.'; } return { success: isFormValid, message, errors }; } router.post('/login', (req, res) => { console.log("lol"); const validationResult = validateLoginForm(req.body); if (!validationResult.success) { return res.status(400).json({ success: false, message: validationResult.message, errors: validationResult.errors }); } console.log("Went through validationResult without problems"); return res.status(200).end(); }); router.get('/login', (req, res) => { console.log(req.url); return res.send(ReactDOMServer.renderToString(<LoginPage />)); // THE PROBLEM }); router.get('/', (req, res) => { console.log(req.url); console.log("lmao") }); module.exports = router; 

最后是/client/src/containers/LoginPage.jsx:

 import React from 'react'; import LoginForm from '../components/LoginForm.jsx'; class LoginPage extends React.Component{ /** * Class constructor. */ constructor(props) { super(props); // set the initial component state this.state = { errors: {}, user: { email: '', password: '' } }; this.processForm = this.processForm.bind(this); this.changeUser = this.changeUser.bind(this); } /** * Process the form. * * @param {object} event - the JavaScript event object */ processForm(event) { // prevent default action. in this case, action is the form submission event event.preventDefault(); const email = encodeURIComponent(this.state.user.email); const password = encodeURIComponent(this.state.user.password); const formData = `email=${email}&password=${password}`; // create an AJAX request const xhr = new XMLHttpRequest(); xhr.open('post', '/login'); xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xhr.responseType = 'json'; xhr.addEventListener('load', () => { if (xhr.status === 200) { // success // change the component-container state this.setState({ errors: {} }); console.log('The form is valid'); } else { // failure // change the component state const errors = xhr.response.errors ? xhr.response.errors : {}; errors.summary = xhr.response.message; this.setState({ errors }); } }); xhr.send(formData); } /** * Change the user object. * * @param {object} event - the JavaScript event object */ changeUser(event) { const field = event.target.name; const user = this.state.user; user[field] = event.target.value; this.setState({ user }); } /** * Render the component. */ render() { return ( <LoginForm onSubmit={this.processForm} onChange={this.changeUser} errors={this.state.errors} user={this.state.user} /> ); } } export default LoginPage; 

我首先添加了path.join(__dirname, '/server/routes')以便告诉Webpack和babel也search这个文件夹来传输jsx,但是无论如何它都会失败。

然后我换成了return res.send(ReactDOMServer.renderToString(<LoginPage />)); 在auth.jsx中通过:

 var html = ReactDOMServer.renderToString(React.createElement(LoginPage)); return res.send(ReactDOMServer.renderToString('base', html)); 

但是,通过这样做,节点给了我另一个错误,那就是:

 C:\Users\XXXXXX\WebstormProjects\XXXX\client\src\containers\LoginPage.jsx:1 (function (exports, require, module, __filename, __dirname) { import React from 'react'; ^^^^^^ SyntaxError: Unexpected token import at createScript (vm.js:56:10) at Object.runInThisContext (vm.js:97:10) at Module._compile (module.js:542:28) at Object.Module._extensions..js (module.js:579:10) at Module.load (module.js:487:32) at tryModuleLoad (module.js:446:12) at Function.Module._load (module.js:438:3) at Module.require (module.js:497:17) at require (internal/module.js:20:19) at Object.<anonymous> (C:\Users\XXXXXX\WebstormProjects\XXXX\server\routes\auth.jsx:8:19) 

这又是一个难题。

请注意,如果没有auth.jsx中的路由,则该Web应用程序工作正常,但我无法通过URL访问/login。

我究竟做错了什么 ?

我正在使用Express,React,React路由器和节点的最新版本。 我的操作系统是Windows 7。

提前致谢

我想我知道这里有什么问题。

你真的编译你的jsx文件,你的webpack.config.js似乎是完美的(它包括react预设,所以它应该工作)。

但是,你只是编译client似乎,你正在尝试使用服务器上的未编译的文件。

但是node jsx读取jsx

我会在这里build议的选项,它允许babel也编译服务器端文件。

要做到这一点,你可以使用babel-cli

只需在你的package.json添加这个

 "scripts": { "start": "babel-node index.js --presets es2015,react" } 

像这样启动你的服务器

npm start

然后它应该首先用babel编译文件并启动你的服务器。

这里是一个例子,你可以从https://github.com/babel/example-node-server启&#x53D1;

这应该解决您的问题