Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2016: React v15, ES6, Node.js v6 #2

Open
wants to merge 15 commits into
base: react-v012-2014
Choose a base branch
from

Conversation

i-like-robots
Copy link
Owner

@i-like-robots i-like-robots commented Mar 5, 2022

Scene setting: Olympic divers jump into a green pool in Rio, Brexit means Brexit, Pokémon Go takes over, and who is "Becky With the Good Hair"?

JavaScript

The period between 2014 and 2016 witnessed massive changes to JavaScript...

ECMAScript 6 (also known as ES6 or ES2015) had finally arrived bringing with it transformative changes. There was a long list of new syntax and features to learn including classes, arrow functions, template strings, destructuring assignment, spread operators for arrays, rest parameters for functions, generators, collections, let and const, promises, a module syntax (but no detail on how it should work) and many more significant things we take for granted now.

Support for all of this new functionality was not available right away but a few web browsers able to support most of it did arrive in 2016. Although, this didn't matter much to most developers because Internet Explorer 11 - which supported hardly any ES6 features - still commanded a significant market share.

Whilst JS was evolving Node.js had been wobbling; lacking contributors and community engagement it couldn't keep up with the big steps forward the language was making. Dissatisfied with the slow progress and difficulties in contributing to Node.js a community driven fork of the project was started in November 2014 with the aim of updating its engine and project governance. The fork was named io.js and the team released v1 in early 2015.

Thankfully, the split was short lived and by September the newly formed Node.js Foundation released Node.js v4 which inherited the progress of io.js and gave us the steady release cycle we have now. By the release of Node.js v6 in 2016 Node supported 93% of ES6 features.

And there wasn't just ES6 to learn because browsers had gained a few new features of their own too! Internet Explorer 5's XMLHttpRequest was finally superseded by the modern Fetch API which was neatly complemented by the URL API. Service workers came online as well to provide offline support to our websites (but they've mostly been used to re-implement caching for some reason 😕.)

In just two years how to write JavaScript had completely changed but that's only one part of being a JavaScript developer - there's the ecosystem too! And... I feel tired just thinking about it. JavaScript Fatigue was setting in, driven by an explosion of new tools to learn and glue together and most of them probably solved problems you didn't have anyway.

This iteration of the app uses many of the new JS features. All variable declarations have been updated to use let and const, string concatenation replaced with template strings, many objects are declared using short hand, and callbacks are replaced with arrow functions too. But whilst there is a long list of changes most of them don't materially alter the execution of the app. Subjectively the code looks cleaner but arguably the only change which has made a substantial difference is the switch from callbacks to promises.

React

React's popularity exploded. In 2014 it was an interesting new toy but by 2016 it was everywhere! And it was exhausting.

I've already mentioned JavaScript Fatigue and this was particularly acute in the React ecosystem. Because it is not a full framework you must supply your own conventions and solutions to many common problems and due to this lack of direction many different conventions and solutions were being advocated. It quickly became very easy to succumb to choice paralysis when diving into a new React app.

One of the most common questions was "how do you share state around a large application"? The component tree for the Tube Tracker is small - only 4 layers deep - so passing data around is trivial but most real applications have many more layers and multiple sets of data to manage too.

Facebook shared their Flux architecture back in 2014 and a dozen or more different implementations of it rapidly came and went. MobX and RxJS offered Functional Reactive Programming (😵‍💫) but by far the most popular solution was Redux which was like Flux but isn't. With Redux you can apply some strict conventions to your codebase and break down your application logic into actions, dispatchers, and stores... it's one of things which sounds super complicated but actually isn't once you try it.

But managing application state is just one topic, the Awesome React list already had 700 links to browse through by 2016! You didn't even have to use React, there were also compatible alternatives to try like the tiny Preact or much faster Inferno.js as well.

I remember working on several React projects during this period and always being surprised at how different two apps could be. I also saw a number of React projects fail; some never launched whilst others were replaced soon after. Piecemeal React architectures regularly overwhelmed the teams which created them or inherited them.

React had changed a little bit too. Firstly v0.13 introduced .Component enabling the use of native class based components and later that year v0.14 introduced stateless functional components beginning the trend towards the fully functional (ish) paradigm favoured now. Notably too, React's integrated DOM support was removed and distributed as its own package so that the "beauty and essence of React" could potentially be shared across different runtimes.

This version of the app is written using a combination of class based components and stateless functional components with only a few minor changes required for compatibility with React v15.

Tooling

The demand for tools able to manage the increasingly complex products we wanted to build with the newly turbo-powered JavaScript created a bubble of new bundlers, compilers, optimisers, linters, and everything else besides. As well as learning ES6 and the new frameworks and all their related bits and bobs you also needed to understand how to assemble together an appropriate toolchain to bring it all together in the browser.

Some of those decisions were easier than others. In 2015 the React team deprecated their own JSX transform and instructed users to migrate over to Babel instead. After its name change Babel had repositioned itself from a tool which did one thing to a generic JavaScript parser and AST which plugins could interact with and build upon. It became the defacto tool for transforming one kind of JavaScript into any other type of JavaScript and with such a complex remit as that there were few viable competitors.

But how to bundle JavaScript modules together was far from settled. Webpack 1.0 was released in February 2014 and it didn't just want to do one job like Browserify did, it wanted to do everything. Not only could Webpack bundle JavaScript - ✨ written using any module syntax ✨ - it could also capture CSS and images and other file types in its web and process and optimise all of them via plugins. Webpack also pioneered a new feature which sounded very sexy but definitely wasn't; Hot Module Replacement. The flexibility provided by Webpack requires a lot of configuration options though which is why its complexity is often decried when diverting away from the default path.

For this reason Webpack gained a host of competitors each more "blazing fast" than the last. Parcel could do everything without writing lots of configuration first which was fine providing you were happy to install its 700+ dependencies. FuseBox "did it right", StealJS was "futuristic" and Brunch promised not to give you nightmares. But the most notable bundler to compete with Webpack was Rollup which specifically targeted ES modules and had a neat trick, it could track the imported and exported properties in each module then prune away unused ones in a process known as "tree shaking".

This version of the app uses Babel v6 to compile it's source code to universally compatible ES5 for the browser and vanilla ES6 for the server. For bundling I have used Webpack v2 which was in beta throughout 2014 and was very popular despite it changing so much that the eventual stable release was actually tagged v2.2 (and I think that sums up this period in JavaScript tooling perfectly.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant