
Upgrading from React 0.11.2 to 0.14.7 in 347 easy steps - logician_insa
http://manuel.bernhardt.io/2016/02/25/upgrading-from-react-0-11-2-to-0-14-7-in-374-easy-steps/
======
meshko
I am not a JavaScript developer but was asked to help the JS team just the
other week with an npm build issue. The npm modules built fine on OS X dev
boxes, but CI server running Linux was failing because older version of gcc
was installed. While troubleshooting this, I came to learn a bit about node.js
and npm ecosystem and I surprised slightly more than I expected. Apparently,
it is considered normal now to have build process download dozens of these npm
modules. Many of them are build time dependencies. Things that are good old
native binaries (e.g. for changing compression levels of graphics files) are
downloaded by npm and built from source. Then when module runs, it tries to
execute them by pulling in one of half a dozen possible modules for executing
native binaries. There is no logging. All code is written in crazy
continuation style, because the framework is inherently asynchronous --
nevermind that it only matters in a handful of hot IO cases requiring
optimization -- all code is like that, undecipherable. There is no logging or
error handling. A 3 months old project setup by smart consultants who do this
kind of thing 24x7 already has a significant number of deprecated
dependencies.

~~~
pachydermic
It's maddening.

>The real painful part of the process is caused by everything around React,
including the build tools.

Can't agree with that more. I _really_ like the way react works. It just makes
sense and doesn't get in your way very often.

BUT it's incredibly frustrating dealing with npm dependency hell. Especially
if you really are concerned about security and don't just trust that "someone
else has probably made sure this code is safe, right?"

I just want to use something for longer than 6 months :(

~~~
kccqzy
You can perfectly use React without npm. Just download the prebuilt
development and production versions of react and a simple <script src="...">
would do.

~~~
scribu
Ok, so what about JSX? Yes, you can write React templates without JSX, but not
happily.

------
bjt
To use the article's terminology, I "flipped the table" about a year ago on
build tools, when first learning React and ES6. Every tool in the JS world
seems to want to be the center of its own ecosystem where all the _other_
tools are just plugins to it. I was sad to see Babel go this way.

Like the author, I have something besides Javascript on the backend. In my
case it's Python. Rather than use a Python-specific build system, however,
I've had success using a Makefile as the top level build tool, which can
directly call out to npm, pip, babel, uglify, sass, etc. There is no
Gulp/Grunt/Broccoli/Webpack/Browserify in sight, and that makes me happy. I'm
pretty sure Make will be around long after people have forgotten about Grunt.

~~~
amelius
Do you manually invoke "make" every time you edit a file on the server? Nodejs
has tools to automate this (and make it fast).

~~~
rubiquity
Most UNIXes already have a command line tool for this. It's called entr:
[http://entrproject.org](http://entrproject.org)

------
troutaway123
> One thing seems increasingly clear to me: this way of building software is
> not sustainable. What can we do?

Waiting 530 days before upgrading and then only spending a day to upgrade what
is effectively three major versions actually seems very reasonable to me.

~~~
ktRolster
Yeah, he says that a single day lost isn't really a big deal, although he
knows it's going to happen again.

The point of the article is that (to take his example) in Java world, as you
get used to the ecosystem, things get easier and easier. It becomes
comfortable.

 _au contraire_ in the web/javascript world, things keep changing but they're
still just as hard.

~~~
pluma
Except React has been getting simpler with each release. First there was
React.createClass. Then came ES6 classes. Now components can just be pure
functions.

Also, the author is using a Scala toolchain to build the JS frontend code. The
standard toolchains (with the exception of Google Closure and Facebook's Flow)
are all built around node.js.

There are even a number of code migrations available for React:
[https://github.com/reactjs/react-codemod](https://github.com/reactjs/react-
codemod) \-- but of course even those can't help you if you use non-standard
tooling and let a web frontend codebase collect dust as browsers (and your
dependencies) march forward.

Projects are never finished. If you cease working on a project, it just
becomes unmaintained code.

EDIT: As someone seems to have flagged my account and I'm now apparently
limited to two replies per hour or something ridiculous like that (yay for
passive aggressive moderating tools?) my reply comes as an edit:

> That's a pretty shallow definition of easier.

It's a library that lets you describe DOM subtrees based on application state.
How much simpler could it possibly be?

If you mean the toolchain, the keynote at React.js Conf made it clear that
improving that part is a major goal for 2016 but none of that will help you if
you want to solve everything with your existing Scala tools.

~~~
AgentME
>If you mean the toolchain, the keynote at React.js Conf made it clear that
improving that part is a major goal for 2016

Then people will just complain there's yet another build tool, because
progress or any change is bad!

~~~
zaphar
If your only method of improving something is to rewrite it or add another
layer then something has gone horribly wrong and people have a right to
complain about it. I sincerely hope that the improvment's are not a rewrite or
an additional layer to an already dangerously complex system.

------
tlrobinson
React has actually done a great job of providing clear upgrade paths, assuming
you don't try to jump several major versions at a time.

They generally provide deprecation warnings at least 1 major version before
actually breaking/removing an existing API. They have also started providing
codemod scripts to help migrate a large codebase (though I've found
find/replace sufficient for a lot of them)

My bigger problem has been relying on 3rd party components that hold me back
due to some incompatibility they don't address for months.

~~~
Hovertruck
The biggest pain I've experienced is updating react-router. I've run into
cryptic failures each time, and googling usually turns up answers for the
previous (or even next/beta) version.

~~~
DiNovi
the API churn on react-router really tests my patience.

~~~
Demiurge
not only that, loss of features like named urls...

------
escherize
I use clojurescript to interact with React. Luckily with a small community we
aren't overrun by build tools! I've recently taken up the boot[1], and it's
amazing. I'm able to quickly get up a live-reloadable environment wherein I
can actually _understand_ what is going on.

    
    
        cd my_project
        boot dev
    

'boot dev' is a task that's defined in the project's build.boot file. It
compiles the cljs files to a main.js file, and serves it from a specified
directory.

Any edit to a cljs file triggers a recompile (of that namespace only - takes
about 0.1 second). If the recompile is unsuccessful then a _buzz_ sound plays.
If the recompile is successful, boot will play a nice subtle _ding_ sound, and
reload the main namespace. With immutable datastructures everywhere, arranging
the app's state to allow reloading is simple.

How simple? There's a fantastic tutorial about how to setup everything I've
just described at: [2].

This template will spit out all the code needed for the live-reload-cljs thing
[3]. Once you install boot (with 'brew boot-clj' it's on apt-get too), You can
run it with

    
    
        boot -d seancorfield/boot-new new -t tenzing -a +reagent -n boot-cljs-project
        cd boot-cljs-project
        boot dev
        ;; then edit the cljs file.
    

[1] [http://boot-clj.com](http://boot-clj.com)

[2] [https://github.com/magomimmo/modern-
cljs/blob/master/doc/sec...](https://github.com/magomimmo/modern-
cljs/blob/master/doc/second-edition/tutorial-01.md)

[3]
[https://github.com/martinklepsch/tenzing](https://github.com/martinklepsch/tenzing)

------
hoodoof
I no longer develop application code. Instead I am a professional fighter of
JavaScript build systems.

Actually not strictly true. I spend about one day per week writing application
code and the rest of my time trying to work out why some npm module that I
need to use won't compile.

~~~
tlrobinson
This is exaggerated a bit but I definitely do spend more time than I should
fighting npm and various dependencies.

------
pkrumins
This is yet another reason to avoid using frameworks you don't really need.
Just because someone uses React, and there's buzz around this framework,
doesn't mean you've to use it.

Talking from my experience frameworks are one of the hugest anti-patterns in
software development. They're hard to learn, they limit your creativity, they
go out of business, you've to upgrade them for no good reason and make your
code compatible with the latest version, you've to search for help and ask
others, they bloat your software and create unnecessary dependencies, and you
probably need only 10% of what a framework offers. They just don't make sense.

You can easily implement your own abstractions for your own application and be
done with it. Your abstractions won't need upgrades, you'll be in control, and
you won't have to waste time searching for help. You should be fighting
complexity and not embracing it. I don't use frameworks and I encourage you
don't use them too.

~~~
steve_taylor
> you probably need only 10% of what a framework offers.

Clearly you have not used React. You can't just use 10% and get any value out
of it. It's typically 80% or more.

~~~
Silhouette
Though the effect you describe is partly because React isn't trying to be an
all-things-to-all-people framework. It's a library, with a specific role and
much tighter scope, and it's a small fraction of the size and complexity of
something like Angular.

------
bsimpson
Slightly OT, but why are you calling unmountComponentAtNode before render?
That seems like a bad idea. ReactDOM.render will update in-place, rather than
tearing the whole thing down and instantiating new versions of everything.

[https://facebook.github.io/react/docs/top-level-
api.html#rea...](https://facebook.github.io/react/docs/top-level-
api.html#reactdom.render)

------
Someone
I don't think the issue here is that it requires work to upgrade across
multiple major versions. Rather, it is that "two major versions back" is only
about 1.5 years ago, and that major building blocks got abandoned in the mean
time.

If you have projects that do not see any updates for a few years (fairly
common, in my experience), then see urgent requests come in (in this example,
it was that a Chrome update broke the app, but it might also be a feature
request. Normally, those shouldn't require upgrading technology to new
versions, but there may be security fixes that didn't get backported, or it
may no longer be feasible to get people who know how to use that 'ancient'
version), that can get annoying fast.

Lesson learned should be that one should not blindly use the latest, shiniest,
technologies, but take longevity of the product into account. Problem for web-
based stuff is that there is not really a stable product that one can count on
to be around mostly unchanged in a few years time, and that is best in class
or at least close to it. Evolution is just too rapid.

------
tlrobinson
Note that in the first code example you can still use JSX in place of a manual
call to React.createElement (which is exactly what JSX compiles to:
[https://babeljs.io/repl/#?experimental=false&evaluate=false&...](https://babeljs.io/repl/#?experimental=false&evaluate=false&loose=false&spec=false&code=ReactDOM.render\(%0A%20%20%20%3CBookTeeTimeModal%20issuerId%3D%7BissuerId%7D%20time%3D%7Btime%7D%20facets%3D%7Bfacets%7D%20lat%3D%7Blat%7D%20lng%3D%7Blng%7D%20locationName%3D%7BlocationName%7D%20isotime%3D%7Bisotime%7D%20teeTimeId%3D%7BteeTimeId%7D%20greenFeeIds%3D%7BgreenFeeIds%7D%20restrictedSearch%3D%7BrestrictedSearch%7D%20book%3D%7Bbook%7D%20bookingInfo%3D%7BbookingInfo%7D%20cancellationPolicy%3D%7BcancellationPolicy%7D%20quote%3D%7Bquote%7D%20%2F%3E%2C%0A%20%20%20container%0A%20\)%3B)
)

------
yogthos
This is one thing that I find great about working with ClojureScript. My team
has been using the Reagent library ([https://reagent-
project.github.io/](https://reagent-project.github.io/)) that uses React
internally. Its API has stayed stable through all the versions of React, and
all I had to do to get the benefits of the latest React versions was to update
the dependency version in my project.

------
grandalf
Tldr: sbt made it difficult.

~~~
niccaluim
Yeah, I stopped reading the second I saw "SBT." I know there are lots of Scala
programmers who use it, but none of the ones I know do. (Having worked at
Twitter for 4.5 years, that's a not-insignificant value of n.) I've heard
nothing but bad things about it.

~~~
estefan
SBT is fine, but using it to build a complex JS project that's using immature
dependencies is just asking for trouble. Webpack alone is tricky enough...

------
epmatsw
Yowza, that's a big upgrade. We did 0.12 to 0.13 to 0.14, and it wasn't too
bad since React had deprecation warnings that are pretty clear.

------
quintes
The comments about js build process with these new tools is something I
share.. when you see the dependencies being pulled down and things are getting
included my first reaction is... What am I shipping. It's good to raise that
question in meetings too and see the developers sink back in their seats.
change management no go to me when you're pulling in GitHub projects at each
build and they could change

------
kkmickos
Why is the major version still zero?

AFAIK React is used in production, and I can not find any alpha/beta labelling
on their website either?

~~~
phaedryx
They are about to jump from 0.14.7 to 15.0.0 for that reason.

More here: [http://facebook.github.io/react/blog/2016/02/19/new-
versioni...](http://facebook.github.io/react/blog/2016/02/19/new-versioning-
scheme.html)

------
sergiotapia
React is now React 15 so everybody should expect more easy to upgrade versions
moving forward.

~~~
masklinn
I don't know, if they apply semver but just go from major version to major
version, that's no change in policy. React 15 -> React 16 makes no BC
guarantee.

~~~
pluma
The way the announcement was presented at React.js Conf this year suggests
that the version shift also represents a change in stability. Personally I
think that from now on React will treat major releases more like Node does --
but of course many people would still consider that pace anxiety-inducing.

------
ocean3
I had upgraded from 0.13 to 0.14 along with redux and react-redux for fairly
large project. I had expected i to be difficult, did ran into few issues but
major ones were deprecation warnings. At the end it was far simpler then i
assumed.

------
joostdevries
> stacktrace > an you spot the problem? Yeah, me neither.

I _did_ spot the problem. But then I'm in the middle of making sbt behave
civily with typescript and angular2.

Of course I could just use webpack or some other javascript buildtool. But I
like to have integrated incremental compilation for frontend and backend. And
since our backend is Scala I'm working in my weekends on a typescript sbt
plugin. I guess I should get out more.

------
jpmw
I love the trolly title :)

BTW, the real title is 374, not 347.

------
paulddraper
React is version 0?

Does that mean they don't follow semantic versioning, or that it isn't
production-ready?

~~~
bsimpson
They were on major version 0 to give them flexibility in evolving the API, but
considering it's been used in production at Facebook for some time and that
the API is relatively stable, they are moving from 0.14 to 15.0 in the next
release.

------
amelius
I moved away from React when I noticed how difficult it was to use raw
elements (without the "Component" stuff). Also, I never knew when updates were
taking place in the real DOM.

~~~
DiNovi
how could you not know?

~~~
amelius
Because componentDidMount only works for components, not elements.

