5

{
  "name": "shopping-cart-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "karma start",
    "start": "node server.js"
  },
  "author": "",
  "license": "MIT",
  "dependencies": {
    "axios": "^0.9.1",
    "babel-plugin-transform-object-rest-spread": "^6.23.0",
    "body-parser": "^1.17.1",
    "express": "^4.13.4",
    "faker": "^4.1.0",
    "marked": "^0.3.6",
    "mongoose": "^4.9.6",
    "nodemon": "^1.11.0",
    "react": "^0.14.7",
    "react-addons-test-utils": "^0.14.7",
    "react-bootstrap": "^0.31.0",
    "react-dom": "^0.14.7",
    "react-router": "^2.0.0"
  },
  "devDependencies": {
    "babel-core": "^6.5.1",
    "babel-loader": "^6.2.2",
    "babel-plugin-transform-object-rest-spread": "^6.23.0",
    "babel-preset-es2015": "^6.5.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-stage-0": "^6.5.0",
    "css-loader": "^0.23.1",
    "expect": "^1.14.0",
    "foundation-sites": "6.2.0",
    "jquery": "^2.2.1",
    "karma": "^0.13.22",
    "karma-chrome-launcher": "^0.2.2",
    "karma-mocha": "^0.2.2",
    "karma-mocha-reporter": "^2.0.0",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-webpack": "^1.7.0",
    "mocha": "^2.4.5",
    "node-sass": "^3.4.2",
    "sass-loader": "^3.1.2",
    "script-loader": "^0.6.1",
    "style-loader": "^0.13.0",
    "webpack": "^1.12.13"
  }
}

I am trying to implement server side routing for a react app i am working on. I am using react-router for this purpose. Here is part of my server.js code

const renderToString   = require ('react-dom/server');
let match, RouterContext = require('react-router');
const routes = require ('/app/router');
const React = require('react');

app.get('*', (req, res) => {
    match(
        { routes, location: req.url },
        (err, redirectLocation, renderProps) => {

            // in case of error display the error message
            if (err) {
                return res.status(500).send(err.message);
            }

            // in case of redirect propagate the redirect to the browser
            if (redirectLocation) {
                return res.redirect(302, redirectLocation.pathname + redirectLocation.search);
            }

            // generate the React markup for the current route
            let markup;
            if (renderProps) {
                // if the current route matched we have renderProps
                markup = renderToString(<RouterContext {...renderProps}/>);
            } else {
                // otherwise we can render a 404 page
                markup = renderToString(<NotFoundPage/>);
                res.status(404);
            }

            // render the index template with the embedded React markup
            return res.render('index', { markup });
        }
    );
});



//my webpack config file 

var webpack = require('webpack');
var path = require('path');

module.exports = {
  entry: [
    'script!jquery/dist/jquery.min.js',
    'script!foundation-sites/dist/foundation.min.js',
    './app/app.jsx'
  ],
  externals: {
    jquery: 'jQuery'
  },
  plugins: [
    new webpack.ProvidePlugin({
      '$': 'jquery',
      'jQuery': 'jquery'
    })
  ],
  output: {
    path: __dirname,
    filename: './public/bundle.js'
  },
  resolve: {
    root: __dirname,
    modulesDirectories: [
      'node_modules',
      './app/components'
    ],
    extensions: ['', '.js', '.jsx']
  },
  module: {
    loaders: [
      {
        loader: 'babel-loader',
        query: {
          presets: ['react', 'es2015', 'stage-0']
        },
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/
      }
    ]
  },
  sassLoader: {
    includePaths: [
      path.resolve(__dirname, './node_modules/foundation-sites/scss')
    ]
  },
  devtool: 'cheap-module-eval-source-map'
};

I get an unexpected token < at < RouterContext {...renderProps}/>.

I have looked over the tutorial am am working of off, but i am not so sure what i have done wrong. Any suggestion would be really appreciated

inhaler
  • 415
  • 2
  • 7
  • 20

1 Answers1

0

You are using the Babel presets react, es2015 and stage-0.

None of those presets includes the plugin you need to make the object spread syntax you are using work – this part of your code:

<RouterContext {...renderProps} />

You can fix your problem by adding the transform-object-rest-spread plugin to your Babel config like this:

module: {
    loaders: [
        {
            loader: 'babel-loader',
            query: {
                presets: ['react', 'es2015', 'stage-0'],
                plugins: ['transform-object-rest-spread']
            },
            test: /\.jsx?$/,
            exclude: /(node_modules|bower_components)/
        }
    ]
}

Don't forget to install the plugin using

npm install --save-dev babel-plugin-transform-object-rest-spread
Patrick Hund
  • 19,163
  • 11
  • 66
  • 95
  • Thanks Partrick for the response. I added the plugins to my webpack config, installed babel-plugin-transform-object-rest-spread, restarted webpack and restarted my server, but i still get the same error. Could this be because of a mismatch in versions i am using? i will add my package.json file to the question – inhaler Apr 29 '17 at 22:59
  • Hmm... I see your webpack build only creates a file public/bundle.js. That sounds like a client side bundle, right? If you want to render React on the server, you have to set up another webpack build that bundles your server code. It looks like you are using Babel only for the code that runs in the frontend, not the backend code – Patrick Hund Apr 29 '17 at 23:03
  • That seems to be the solution. I will use this as a guide http://stackoverflow.com/questions/31102035/how-can-i-use-webpack-with-express Is this a good starting point? – inhaler Apr 29 '17 at 23:11