Since originally written, Webpack released version 2. There are some changes to the configuration, and we no longer need to setup the define plugin ourselves for production mode.
I’ve updated the guide, but I’m leaving this version here for historical purposes. All new projects should follow along with the new Getting Started with React.
The original Githup repo is also updated for the new guide. You can view the final result as it was for this version of the guide in the git history.
This will be the fast course to get a productive React development flow going. The only real prerequisite (besides a working computer and internet connection) is having a recent version of Node.js installed (as written, this is version 6.2.2, and this may work in versions 4 and 5).
First thing to do is create your new project folder (I’ll be using
react-project in this guide), and run
npm init. The requested information doesn’t directly impact what we are going to be doing, so use whatever values you want.
We need some an html page to attach our app to, so create a
public/ folder, and inside, create
index.html. Paste this content into it:
If you are looking at this and saying, “man, that’s a pretty sparse web page”, well, you’re right. For a “real” app, you are going to want to put your extra meta tags in, maybe Google Analytics, a link to your favicon, and whatever else you need. We’ll get to the content next.
src/ folder in the root of your project. All of your project specific source will be in this folder. For now, just create a
main.js file in
src/, and copy these contents into it:
So now your project folder should look like this:
Well, we can see from above that we need at least a few dependencies from NPM installed, so lets get started on those.
npm install --save react react-dom.
react package is the ReactJS library, and
react-dom is a sister library which lets you render a React virtual DOM to the real DOM.
That actually covers the entire source of the application. Now all we need to do is build it.
So, we primarily need two tools for building a React application: Webpack, and Babel.
Webpack is a module bundler. You give it an entry point file which uses CommonJS (which is the same syntax that Node uses for its modules), and it finds and “bundles” all the required files into a single file, which you can then include in your webpage.
So, lets install Webpack and Babel. Run
Object.assign and objects like
“That’s it right? now we just run
webpack and we’re done, right?” Not quite.
Our next step is to configure webpack. Technically, we could forgo configuring, and just use command line arguments to the webpack cli interface. That would look something like
webpack src/main.js public/bundle.js --module-bind 'js=babel'. However, using a configuration file is much more expressive, gives you more options, and is easier to maintain. So create
webpack.config.js in the root of your project, and copy this into it:
Wow, that’s a lot of configuration for a simple app! Let’s take a closer look though. The first two lines are just requiring Webpack and the Node “path” module, and two the next three lines are just setting of some constants. This line:
Pulls in the name of the npm script command. I’ll get back to this, but for now, just remember something about “TARGET”.
entry property, which is the file that Webpack starts at (more on that in a moment); the
output, which is where Webpack saves the compiled code; the
modules property, which I’ll get to next; and
plugins, which defaults to empty.
entry configuration can take a string, array, or object. If you use a string, it should point at the single file that starts your application. If you use an array, Webpack will concatenate the files. Using an object allows you to have multiple entry points, which is for building multiple separate apps. In our case, we need our main.js file and babel-polyfill (which is loaded first).
Our module property has a loader property, which is an array of the defined loaders. For now, we are just defining babel-loader.
test is a regex to match against file extensions. I’m using pattern which matches
.jsx files. You could also choose to set it to only compile files with the JSX extension, by using
/\.jsx/, or if you decide not to use .jsx at all, just use
/\.js/ to .js files. The
include property tell Webpack that you only want to compile files in a specific folder. This is because you should never need to compile files from
node_modules, since libraries should already be compiled with Babel (if they needed to be). This only stops Webpack from running Babel on files outside of APP_DIR, it doesn’t stop Webpack from bundling those files into the output. Our
loader is Babel. Webpack knows that
babel means it should use the loader from package
plugins property is an array of Webpack plugins and their own configuration. What we are doing is checking the value of TARGET for ‘build’, which is our production build command. If set, we setup one of the built-in Webpack plugins which defines an environment variable. This is the Webpack configuration method for setting an environment variable, the other common way to do this is by setting vars before
webpack in the NPM script (or on the command line directly). In this case, both methods are viable, but I prefer to keep it in my config file.
The last bit is simply exporting the configuration. By default, when Webpack runs, it looks for
And that’s it for our Webpack configuration. Now we just need to add our command to package.json:
We add two npm scripts, “dev” and “build”. These are the command which will become the TARGET from earlier. “dev” will run Webpack with “-d –watch”, which sets webpack in debug mode (more verbose, and outputs code maps for the browser), and in watch mode, which means it continuously runs, re-compiling whenever a require()’d file changes. “build” runs Webpack with “-p”, which enables production mode. In production mode, the output is uglified (using Uglify). For us, with our bit of configuration that watches for the TARGET to be “build”, we also set the NODE_ENV variable to be “production”, which tells React not to include it’s debugging tools (which lets it run faster, and spill less in production if there is an error).
Ok, we’re almost there. We have everything in place except for a little bit of Babel configuration. This one is easy. Create
.babelrc in your project root, and copy this into it:
npm install --save-dev babel-preset-latest babel-preset-react.
That pretty much covers it. And now you know why the React workflow is notorious for being difficult to setup. While it’s not actually that complex, there are many steps to the process, at least the first time through.
So, finally, to start your development environment, run
npm run dev. You should see some output from Webpack, and two more files should appear in
Now you just need a server to get these files into your browser. My go-to mini-server is
http-server, available with npm. I install very few npm packages globally, but this is one. Install it with
npm install -g http-server, then run it from your project root with
http-server public. Now you should be able to visit
localhost:8080 in your browser, and see the web app you just created!