React with Javascript package managers
13 November 2015 at 8:21 pm
One of the best ways to learn new software is to take on a commercial project and force yourself to use it. I do this all the time and with all the cool kids ranting about React, I felt that it was time to do a project based on it. It's been a bit painful, but I've come to enjoy the way React works. It's actually quite beautiful!
I've used Angular before and React feels much more solid and natural. It does require that you learn how React thinks (or want you to think), and that part might take a little time. Here's some of what I've learned while using React.
Javascript - the new frontend AND backend favorite
To create a HelloWorld on the web, all you need is a HTML page with a few lines of inline JS. How can a 200+ file download possibly be an upgrade from that? It just does not make sense that a simple HelloWorld-project should become a folder with 139Mb of Javascript based libraries, right? Like it or not - Javascript is the language that takes over both frontend and backend development these days.
You can use it old-style (and write it all by hand) or use one of the many hundred frameworks that are out there to make your life easier. So while the initial download may be large when using frameworks, the files will normally be cached by the browser. If you use a CDN for your framework, odds are that it's already cached.
I've always known JS and it's very close to Actionscript. Learning React has not only been yet another nail in the Flash coffin (it's really completely dead). Learning React has also taught me several new programming concepts that I'll keep using for other projects.
How React is different
I've had to do lots of refactoring every time I've understood how a new thing worked in React and that’s been a bit painful. Initially I tried to fight against how React worked since I wanted to be in control. The React way of doing things is to not do things directly, but to always do things based on state. The data model controls the GUI in reactive programming. React only re-renders if an object has changed, so to change something on screen, you need to implement a visual change in response to an object/variable changing. This happens asyncronously since the React DOM and the browser DOM are two different things. With React, you never manipulate the DOM directly. It always happens because of a change in the data model of the app.
Changing an object/variable to change the GUI sounds cumbersome until you've used it. The super-neat thing about this is that if you do things correctly, you'll be able to start your app from ANY state and also to change it while it's running! You just set the variables and the app will render straight to this state! No more clicking 20 times to get to a certains state for debugging. Now you just set the data of that state and you're there? Understanding how to solve things "the React way" is what really takes time, but once you get the hang of it you'll wonder why not all software is based on this principle.
A React application starts at a root component, that then renders sub-components that renders sub-components. It takes time to understand where in such a hierarchy certain data should be, how it's passed most effectively and how to implement the visual changes in response. I won't say I'm completely on top of this yet, but I really feel that I'm getting a lot back from this approach of working. The very clean separation of responsibilities between each component makes you much less afraid of breaking stuff than with other ways of working with code. You basically jump straight to the module you want to work on and do your thing, knowing that it won't break stuff. I really recommend trying out this way of developing web apps if you haven't!
Getting up to speed
When you start out with React, you'll most likely start like me using the in-browser JSX transformer to convert JSX to pure javascript at runtime. This process is called "transpiling", since you're not really compiling but rather converting the React's custom JS format (JSX) to plain ECMAScript JS. Following the official docs from Facebook, you'll get your project started but to really grasp the full power of React, you should go through setting up the NPM and JSPM package managers.
Why? For one thing - most of the example code you'll find online will require it. Package managers are great tools since they keep track of all the dependencies used in your project and they download all dependencies from CDN's. The most important is however that they can convert your app to a pure JS class that is much faster than the runtime-compiled JSX script.
So how do you get started with Package Managers? There's several to choose from, but if you've played with Node.js you probably already have "npm" installed? If not, click here to learn how to install it. Once you have npm installed, open a terminal window (or CMD command line on Windows) and type:
sudo npm install jspm -g
This will install JavaScript Package Manager (JSPM) on your system and make it easy to install any library you want to use. JSPM seems like a solid choice among a flurry of others that pop up and then disappear and it can pull in code-packages from both npm and github.
To create a new project from scratch, you'll make a new folder, go into it and type the following:
npm init jspm init
This will create a couple basic files that the package manager needs to keep track of what libraries your project is using. It will also download some base packages you need to start developing: Systemjs makes it easy to include libraries on your app. Babel compiles JSX to a variety of JS (including ECMAScript 6 / ES2015), makes sense out of error messages and adds support for missing features in some browsers. You'll find these and some others in a folder called "jspm_packages". With these files in place, you'll want to get ready for React programming by installing React itself:
jspm install npm:react
These are now added as dependencies in the package.json file in your folder and you can start using React with a package manager to ease your development.
JS and it's blazing speed of development
This talk from Jack Franklin was of great help to me in learning JSPM, but it's also quite typical in the JS-world that the talk from May (6 months ago) is already full of "bugs". JS libs are rarely consistent over time, and if you try to run his code, you'll get errors like:
Warning: React.render is deprecated. Please use ReactDOM.render from require('react-dom') instead
If you then try to use that code, you'll realise that you didn't install the package "react-dom" since that wasn't needed 6 months ago. Looking at the official documentation from Facebook you'll see that you should not use the import-statement as Jack does, but rather use "require" like this:
var React = require('react'); var ReactDOM = require('react-dom');
Running that will give you the error:
Error: require is not defined
Facebook just takes it for granted that you've installed the "browserify" package. This is what give you the require-statement and other goodness since there's no such thing in JS. They take this for granted in all their doumentation, so be aware that you'll need that to have browserify or webpack installed if you want to just cut and paste their examples. They do actually mention it on their Getting Started page, but if you're new to Javascript package managers, it's quick to skip that single mention.
But - armed with your new knowledge about JSPM, you could just pull it down
jspm install npm:browserify
The problem is that this requires that you reconfigure your app from scratch, and since you're now following Jack's great tutorial, you should rather do the following:
jspm install npm:react-dom
Once that is in place, you can use "import" rather than "require" like this:
import React from 'react'; import ReactDOM from 'react-dom';
I don't find these error messages intuitive at all, so I thought I'd better jot this down for Google to find, so others can skip some frustration
Using "import" or "require" syntax is just a matter of preference. You can use both, but since none of them actually exists in JS they're implemented as Polyfills - placeholder syntax for methods that may or may not end up in the ECMA language.
Why Javascript should become what students learn first
When I started using Node.js on both the server & client some years ago, I never thought it'd become as popular as it is today. Now that I'm teaching a bit, I keep thinking that it's crazy that students don't learn JS in school. Think about it - why should students not learn a language that can cover both the client and the server? It is after all the programming concepts you should be tought at school, not the syntax. The Syntax is bound to change and keep changing, but the general concepts of programming is something that you'll carry with you from one language to the next.
If I could affect the students carriculum at University and higher education, I'd use Javascript as the first programming language to learn. Once students know the basics of the language, I'd make a frontend and a backend track. Having one language for both makes it quicker to get past the syntax and tooling stage, and get into the concepts and useful stuff. The frontend track would be focused on using React, Angular and other frameworks. It would be more about how to learn frameworks than creating big projects. Knowing how to learn a new framework is much more useful than focusing on the fine details of a language.
The backend track would be foused on Node.js making multiuser apps and games, controlling hardware and persisting data. Compared to starting with Java, C,C++ or PHP, this would be much more useful to the students. They'd get results faster, they'd learn skills that are instantly useful in a job situation and they'd have a huge and great community to learn from. Once they've learned JS, they'll easier pick up the more advanced features in more mature languages. JS is basically a much better starting language.