Self Education Self Education

ToEatApp Rails-React-Relay-GraphQL Tutorial - Application Setup

In this series of posts we will explore how to render a React based front end that uses Relay and GraphQl to communicate with a Ruby on Rails server. We will be writing ES6 Javascript that gets transpiled by Webpack into ‘regular’ javascript. The applicaton can be viewed at toeatapp.startuplandia.io and the codebase can be viewed at github.com/jcdavison/to_eat_app.

This tutorial is aimed at web developers who are comfortable with relational data storage, http/rest ideology and rails and who want to quickly learn some powerful client-side data caching and state management techniques. If you are new to coding and reading this tutorial and lots of things don’t make sense, that is ok, just work as far as you can get, submit your commits to antipattern.io and I will give you relevant guidance.

Application Setup and Tooling

This app will run a standard rails process and a seperate node process that will utilize webpack to transpile es6 based jsx files into one big javascript file.

  git clone [email protected]:jcdavison/to_eat_app.git
  cd to_eat_app
  bundle install
  npm install
  # in one terminal window 
  bin/rake db:create
  bin/rake db:migrate
  bin/rails server
  # in a different terminal window
  webpack -w
  # then go to your browser and visit
  # http://localhost:3000/

How are WebPack/Babel and Asset Pipeline working together?

Our Rails application server doesn’t know anything about any of the underlying node or javascript transpiling technologies.

Notice the contents of ./app/assets/javascripts/application.js.

  //= require jquery
  //= require packed/transpiled_output

The only file that Rails is requiring that has js application code in it is packed/transpiled_output. This file is created by the WebPack process, which is watching ./app/assets/javascripts/src/app.jsx, anytime a change occurs WebPack converts app.jsx and all includes to one large file packed/transpiled_output that has transpiled the ES6 js to regular internet ready js. Also notice that all the js application logic lives inside /javascripts/src and that app.jsx uses ES6 module imports to require dependencies.

Files to notice.

./package.json

All the javascript dependencies that we need. Notice that we are requiring things like react, relay and graphql here. Our rails server won’t be using anything other than the most vanilla useage of the asset pipeline, ie ‘render this javascript file that webpack just built’.

  {
    "name": "ToEatApp",
    "description": "Got Food Trucks?",
    "version": "1.0.0",
    "repository": "ToEatApp",
    "license": "MIT",
    "dependencies": {
      "babel": "6.5.0",
      "babel-core": "6.3.15",
      "babel-loader": "6.2.4",
      "babel-plugin-transform-class-properties": "6.6.0",
      "babel-preset-es2015": "^6.6.0",
      "babel-preset-react": "^6.5.0",
      "babel-relay-plugin-loader": "^0.6.1",
      "graphql": "^0.4.18",
      "node-jsx": "0.13.3",
      "react": "^0.14.7",
      "react-dom": "^0.14.7",
      "react-relay": "^0.6.0",
      "react-router": ">=2.0.0-rc2",
      "react-router-relay": "^0.9.0",
      "webpack": ">=1.12.14"
    },
    "metadata": {
      "graphql": {
        "schema": "./schema.json"
      }
    }
  }

./schema.json

schema.json tells graphql about the shape, location and required params needed to interact in a declarative fashion with the rails application server. Important note, lib/tasks/graphql.rake contains a rake task that programmatically builds schema.json. The below is an excerpt and the actual schema.json over 2k lines and generally not intended for human consumption.

  {
    "data": {
      "__schema": {
        "queryType": {
          "name": "RootQuery"
        },
        "mutationType": {
          "name": "RootMutation"
        },
        // begin redaction
      },
    },
  }

./webpack.config.js

Webpack is a fancy node library that enables all kinds of magic like ‘transpiling’. In this case, we will be using webpack and babel to transpile a bunch of .jsx files that are written with ES6 into a more browser friendly form of javascript.

  module.exports = {
    entry: ["./app/assets/javascripts/src/app.jsx"],
    output: {
      path: "./app/assets/javascripts/packed",
      filename: "transpiled_output.js"
    },
    module: {
      loaders: [
        { test: /\.jsx$/, exclude: /node_modules/, loader: "babel-loader" }
      ]
    },
    resolve: {
      extensions: ['', '.js', '.jsx']
    }
  };

./.babelrc

Babel is the really fancy node library that converts ES6 compliant javascript into browser runnable ‘normal’ javascript.

  {
    "sourceMaps": "both",
    "plugins": ["babel-relay-plugin-loader", "transform-class-properties"],
    "presets": ["react", "es2015"]
  }

Next Steps

Read the next post in this series, ToEatApp React-Relay-GraphQL Tutorial - Queries.

Talk

A Dream Team

We have traveled many miles.

We will help you build, scale, grow.