Shing Lyu

Minimal React.js Without A Build Step

Nowadays, starting a frontend project means setting up a complex build system with preprocessors, transpliers, compressors, packagers, and many more. Don’t you missed the day when you can just write <script src=”./jquery.js”/> and start coding? I love to build prototype or small tools using HTML and React.js, but the build system thing is killing me (the official documentation suggest you use browserify and babel). So I’m going to show you how to build a minimal react page without any of those distractions.

I’m not oppose to build systems. The frontend community is reinventing (or re-discovering?) the software engineering best practices, this is a good thing. But for most small prototypes, a full build system is usually a overkill. It raise the architectural complexity unnessarily. And JavaScript was desinged for the browser, now you have to compile it before you can run it in the browser? It just feels wrong!

Now I’m going to show you how to bulid a minimal React project without Node, npm, browserify, webpack and babel.

1. Load React.js from CDN instead of npm

Insteal of running


npm install --save react react-dom

write these lines to your main html file


<script src="https://fb.me/react-0.14.8.min.js"></script>
<script src="https://fb.me/react-dom-0.14.8.min.js"></script>

2. Get rid of JSX

Did you notice that we didn’t include the babel in-browser transpiler (Previously JSXTrasnformer.js)? JSX is one of the key reason React apps needs a build step. The build/transformation step also makes the code hard to debug. In fact creating the DOM using React’s JS API React.createElement() is not as hard as you might think. Here are some example:


<h1>Hello Word</h1>

can be written as


React.createElement('h1', null, 'Hello World')

And if you want to pass attributes around, you can do


<div onClick={this.props.clickHandler} data={this.state.data}>
  Click Me!
</div>


React.createElement('div', 
                    {
                      'onClick': this.props.clickHandler, 
                      'data': this.state.data
                    }, 
                    'Click Me!')

Of course you can have nested elements:


<div>
  <h1>Hello World</h1>
  <a>Click Me!</a>
</div>


React.createElement('div, null, 
  React.createElement('h1, null, 'Hello World')
  React.createElement('a', null, 'Click Me!')
)

3. Importing modules

This is probably the most tricky part. Most of the React.js modules out there follows CommonJS syntax. To be honest, I don’t have a good solution for this. For very simple prototypes, I just expose everything in the global scope. I still split the JavaScript into multiple files so I can refactor them into ES6 modules when it’s ready.

4. CSS Styles

As far as I know, the React community promotes the use of inline style, but I still prefer separate stylesheets.

The Benefits

First, we reduce the number of dependencies; Not just the number of npm packages, but we are also less prone to Node and NPM version incompatibilities. Given the recent left-pad incident and my previous experience with Node.js Gaia Integration Tests for B2G, I believe this will save you from a lot of trouble.

Secondly, since is all pure JavaScript, You can easily debug the program using browser’s built-in debuggers. You don’t have to install any add-on or use any source mapping tools.

Finally, It’s super easy to deploy the program. Simply drop the files into any web server (or use GitHub pages). The server doesn’t even need to run Node and NPM, any pure HTTP server will be sufficient. Your cowokers or contributors can also start hacking by opening the html file. The greatly reduce the learning curve, because everybody prefers different building tools, and you often run into trouble your Node and NPM environments are different.

Try it out

You can check out the template here.

Here are two sites built using this template: