Egoi Cantero Viqueira
Egoi Cantero Viqueira

Reputation: 79

SyntaxError: Unexpected token '<' in Node

I am just trying to set up SSR in Node but when I try to import the React component into the server, I get this error:

SyntaxError: Unexpected token '<'

Tried including "type": "module" in the package.json but nothing changed. This is my server.js file:

const express = require("express");
const mongoose = require('mongoose');
const path = require("path");
import ReactDOMServer from 'react-dom/server';

import Home from './client/src/Home';

const port = process.env.PORT || 5000;
const app = express();
const { API_VERSION } = require('./config');

// Load routings
const userRoutes = require("./routers/user");
const postRoutes = require("./routers/post");
const commentsRoutes = require("./routers/comment");
const policyRoutes = require("./routers/policy");

app.use(express.urlencoded({ extended: true}));
app.use(express.json());

const uri = "MONGO_URL"
mongoose.connect(uri, { useNewUrlParser: true, useUnifiedTopology: true }, (err, res) => {
  if (err) {
    throw err;
  } else {
    console.log("Connected to DB!.");
  }
})

// Configue http
app.use((req, res, next) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header(
        "Access-Control-Allow-Headers",
        "Authorization, X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Allow-Request-Method"
    );
    res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, DELETE");
    res.header("Allow", "GET, POST, OPTIONS, PUT, DELETE");
    next();
});

app.use(`/api/${API_VERSION}`, userRoutes);
app.use(`/api/${API_VERSION}`, postRoutes);
app.use(`/api/${API_VERSION}`, commentsRoutes);
app.use(`/api/${API_VERSION}`, policyRoutes);

if (process.env.NODE_ENV === 'production') {
  app.use(express.static('client/build'));
}

app.use(express.static('./build'));

app.get('/', (req, res) => {
  const home = ReactDOMServer.renderToString(<Home />); //THIS IS THE LINE THAT THROWS THE ERROR

  const indexFile = path.resolve('./build/index.html');
  fs.readFile(indexFile, 'utf8', (err, data) => {
    if (err) {
      console.error('Something went wrong:', err);
      return res.status(500).send('Oops, better luck next time!');
    }

    return res.send(
      data.replace('<div id="root"></div>', `<div id="root">${home}</div>`)
    );
  });
});

app.listen(port, () => {
  console.log(`Servidor funcionando en el puerto ${port}`)
})

Webpack configuration:

const path = require('path');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  entry: './server.js',

  target: 'node',

  externals: [nodeExternals()],

  output: {
    path: path.resolve('server-build'),
    filename: 'index.js'
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader'
      }
    ]
  }
};

Babel configuration:

{
    "presets": [
      "@babel/preset-env",
      "@babel/preset-react"
    ]
  }

Upvotes: 1

Views: 974

Answers (1)

Apoorva Chikara
Apoorva Chikara

Reputation: 8773

You can't use import and require at the same time. These are using different module systems, either use require(CommonJS) or import(ES6).

Also, You need to change the react imports to require like this:

const ReactDOMServer = require('react-dom/server');
const Home = require('./client/src/Home'); // give the correct path

Also, You should change it the things in package.json, remove the "type":"module".

Upvotes: 1

Related Questions