« Previous Tutorial Next Tutorial »

Right! Back at it, then!

Sorry, for a minute I forgot I wasn’t British. Anyway, in our last tutorial we created a very basic Webpack config file, but had to leave off before we could actually use it. Today we’re going to change that. First we need to make a few additions and changes to our app. We’re going to jump right in by switching to sublime text and then creating a new file in your top level musiclist folder called .babelrc. These are the rules which Babel will use when Webpack calls upon it to transpile your ES2015-17 and JSX down to regular old JavaScript. Fortunately it’s a super simple file. Here is everything it needs to contain:

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

env for all the latest JavaScript goodness, and react for React. That’s it, we’re done here. Save the file, and open up package.json. We need to create a script to run Webpack, so add a comma to line 8, and then underneath it, add the following:

"build-dev": "webpack --config webpack.config.js --progress --profile --colors"

This means when we type yarn run build-dev in our command line, it’ll run Webpack, using the config file we wrote in the last tutorial, with a couple of options set to make its output look a little nicer.

All right, save this file and it’s time to write some JSX, which will give us something to compile so that we can finally see whether or not our Webpack config even works.

Create a top-level directory in your musiclist folder called src which will contain all of our React source files, including JSX components, JavaScript actions and stores (we’ll get to those), and more. In that new folder, create a file called index.jsx. This is the top-level component of our app, from which all other components will be initialized (albeit not all in this file – it’ll branch outwards, like an upside-down tree).

In the future, this file’s going to get fairly complex, but for now it’s quite simple. Here’s what we need:

import React from 'react';
import { render } from 'react-dom';
import TestComponent from './testcomponent';

render(
  <TestComponent />,
  document.querySelector('#react-app'),
);

All right, let’s go through this line-by-line. Line one imports our React module, which seems valuable if we’re going to be writing a React app. Line two does something interesting, which we haven’t covered before in this series. It’s importing something from our React-Dom module … but instead of pulling a master object that contains all of that module’s methods and other properties, we’re pulling a single method, render.

We’re doing this using an awesome ES6 feature called destructuring, which works with objects, arrays, and more. In this instance, destructuring in combination with import allows us to pull just the method we want from a whole big object of stuff, which saves on bundle size, among other things. Variable destructuring will come into play a lot as we work with React, and we’ll cover it more as we move along. If you want to learn more about destructuring (and a whole lot of other ES6 goodness), I cannot recommend Wes Bos’s ES6 for Everyone enough. It’s a great series of video tutorials that covers everything new in ES6.

Back to our JSX file. Line 3 is importing a test React component from testcomponent.jsx (we don’t have to add the file extension – Webpack is smart enough to figure it out). Eagle-eyed observers may note that testcomponent.jsx does not, in fact, exist. We’ll be fixing that in a second.

Lines five through eight use the render function we imported from React-Dom to render our react component into our page, inserting it into a div named react-app. Annoyed by ESLint flagging “document” as undefined? Pop over real quick to .eslintrc and, in the env block, add a comma to line 5 and then add the following:

"browser": true,
"node": true,

This will tell ESLint not to complain about assumed globals like Window, Document, and a few others. Save the file, go back to index.jsx, and hit space, delete, save in order to fresh the ESLint plugin for Sublime. There we go.

OK, so now we need two things: a test component, and a div with an ID of react-app. Let’s do the test component first. Create a new file in /src called testcomponent.jsx, and then add the following:

import React from 'react';

export default function TestComponent() {
  return (
    <div>
      <h1>React Test Component</h1>
    </div>
  );
}

OK, some of you who’ve seen React before might be thinking, “Wait, doesn’t React use, like, classes and stuff?” … the answer is yes, it does, when they’re required, but they aren’t required here so we’re using a pure function to generate our output. Let’s talk about what’s going on here.

We’re importing React again, which we will do a lot. Then we’re defining a new function, which we’re exporting (so that it can be imported by index.jsx), named TestComponent. The “default” means we can just do:

import TestComponent from './testcomponent';

instead of

import { TestComponent } from './testcomponent';

Which is how we import non-default variables, objects, functions, and so forth. This will inevitably cost you some time here and there when your code’s not working and you hunt around for fifteen minutes before realizing you forgot a “default” or forgot some braces for a non-default import, and feel like an idiot. Sorry in advance!

Once we define our function, we give it a return block which, as you can see, returns a bunch of HTML. This is JSX, the bizarre JS/HTML hybrid of which I’ve spoken in the past. Look ye upon it, and despair!

Or don’t. It’s pretty straightforward. Mostly it’s JavaScript, except when you’re in a return block, in which case you can return HTML … which you can mix with JavaScript, but we’re getting ahead of ourselves.

It’s almost time to see that beautiful heading-one text showing up in our browser. All that’s left to do is edit our top level view and then run our Webpack build. So, open up /views/index.ejs. Nuke everything in between the body tags and then add this instead:

<div id="react-app">Loading ...</div>

Then, just below the closing body tag, add this line:

<script src="/javascripts/build.js"></script>

… it’s important to load our build.js after the div that contains our React app, because otherwise it’ll load the javascript and try to initialize React before that div exists, creating an error in our browser console and causing the app load to fail. Save this file. We’re done writing code. Now we switch to a terminal window, make sure we’re in our musiclist directory, and type:

yarn run build-dev

BEHOLD! We have built a React app. Not one that does much, but a React app nonetheless. Make sure our node server is running, then navigate to localhost:3000 … if everything went according to plan, you’ll see a big header that says “React Test Component”

Congrats. This is a big step! We’ll follow it up next time with some more info on how React components work together to create an app. Thanks for watching!

« Previous Tutorial Next Tutorial »