Orion
Orion

Reputation: 144

How do I get Babel and React to work with my Express Application?

Apologies for probably a noob question but I've been reading a lot of articles to try and get this to work but I haven't had success.

I love building my apps in express and want to start using React for some of my reusable components.

I want to be able to use JSX for a cleaner syntax and have been trying to get Babel to work on my basic Express application. Any help would be appreciated!

I have a basic express application up after using express CLI:

express example_app --pug

I also installed the following dependencies:

npm install --save-dev babel-cli babel-preset-es2015 babel-preset-react babel-preset-env react react-dom

I then added my presets to .babelrc

{
  "presets": ["es2015", "env", "react"]
}

My package.json looks like so:

{
  "name": "sample-app",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "babel-node app.js --presets es2015,env,react",
    "devstart": "nodemon ./bin/www"
  },
  "dependencies": {
    "async": "^2.6.0",
    "babel-preset-env": "^1.6.1",
    "body-parser": "~1.18.2",
    "compression": "^1.7.2",
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.9",
    "express": "~4.15.5",
    "express-jsx": "0.0.4",
    "express-validator": "^5.0.3",
    "hbs": "~4.0.1",
    "helmet": "^3.12.0",
    "moment": "^2.21.0",
    "mongoose": "^5.0.11",
    "morgan": "~1.9.0",
    "pug": "^2.0.2",
    "react": "^16.2.0",
    "react-dom": "^16.2.0",
    "serve-favicon": "~2.4.5"
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "nodemon": "^1.17.2",
    "rimraf": "^2.6.2"
  }
}

Here is my Express app.js file:

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var index = require('./routes/index');
var users = require('./routes/users');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', index);
app.use('/users', users);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

app.listen(3000, function () {
console.log('Example app listening on port 3000!')
});

module.exports = app;

This is the index.pug layout that is my view:

doctype html
html
  head
    title= title
    script(src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js')
    script(type = "module" src='javascripts/script.js')
    link(rel='stylesheet', href='/stylesheets/style.css')
  body
    div#root Hello, React is not working

Finally here is my script.js file that has the React Component that I took from the React tutorial for "Adding React to existing Application" :

import React from 'react';
import ReactDOM from 'react-dom';

$( document ).ready(function() {

ReactDOM.render(
  <h1>Hello, React is now working</h1>,
  document.getElementById('root')
);

});

However, every time I start my application via "npm start" I always get a "Uncaught SyntaxError: Unexpected token <" in my console. I tried changing the script tag type to "text/babel" and "text/jsx", which doesn't generate a console error. However, the React component doesn't render onto the view.

Any help would be appreciated! Thank you!

Upvotes: 0

Views: 330

Answers (1)

Thiago Loddi
Thiago Loddi

Reputation: 2340

It looks like you are missing a transpiler for the React part of your application.

When you run babel-node, it transpiles the code in your backend so Node can understand it. You have to do the same thing with your script.js

It looks like are serving an ES6 syntax javascript to your browser, which only understand vanilla javascript. You probably need a bundler (like webpack) to transpile your code to vanilla and serve the result to the browser.

In a nut shell, you have to tell webpack to read your react files, transpile everything and bundle everything and then 'spit' a single vanilla javascript file (usually called bundle.js) that you browser is actually going to execute.

There are some options out there for you to consider:

  • webpack - Webpack is being largely used to bundle reactjs application and has a very rich API for configuration.

  • gulp - More like a task manager then a bundler per se, but it gets the job done.

  • parcel - As parcel itself likes to put it: "Blazing fast, zero configuration web application bundler". And by zero configuration they mean ZERO configuration. Good for development, but not so great if you want to add plugins or personalize your build for production.

Upvotes: 1

Related Questions