

Create a character voting app using React, Node.js, MongoDB and Socket.io - sahat
http://sahatyalkabov.com/create-a-character-voting-app-using-react-nodejs-mongodb-and-socketio/

======
petewailes
Christ on a bike...

I spend a reasonable amount of time developing and maintaining a reasonable
sized js based front end to an application, which uses React heavily (40k
lines). Looking at this, I can't help but think that isomorphic JS apps make
life far more miserable than separate back and front end applications.

To get a decent server running on a linux distro - Nginx, Mariadb,
PHP/Python/etc. An apt-get and your updates are handled nicely for you.
Dependency management via Gulp is better than nothing, but jeez it still sucks
so bad.

Building a nice, RESTful API on a more sensible back end infrastructure is far
less complex, has a vastly smaller toolchain (just a small library for routing
and db connection handling would do), plus you get the joys of things like
Schemas and ACID from a proper RDBMS (because seriously, Mongo? We really
still think that's a good idea?).

That's before we even get on to Step 4. ES6 Crash Course. Or, here's things to
know about a language that you can't use on the client browser, because it's
not actually a thing there, so you can't use all that you'll learn here when
you write JS.

It's insane that people think you need to do all this just to get a live
updating counter. What's wrong with a tidy back end with ZeroMQ for your
pubsub style socket handling to allow real-time event based change
publication, and a separate front end?

It feels like you have to do a hell of a lot of work to get JS + your
favourite V8-based server to do anything, and none of it easily.

~~~
verroq
There is just a lot of friction. Want es6, get ready to put gulp in your work
flow. Want to sanely include frontend dependencies? Time to add throw in
bower. Want those js/css to be injected into the page? Throw in wiredep or
bite the bullet and chuck in the wirepack.conf.js. Don't want that and want to
use a skeleton? Install yeoman and run the isomorphic js generatior that gives
you a 1k+ line project and you haven't even made your app yet.

~~~
TheAceOfHearts
I made a scaffold [0] that tries to give you a reasonable starting point,
without tons of extra cruft. It was important to me that the scaffold handle
all 3 basic environments: development, testing, and production.

It's basically a single webpack config (that's heavily commented, btw!) and a
set of npm run-scripts. You don't need gulp to build an application! And I
would not call bower a sane way to include frontend dependencies... Not by a
long shot.

[0] [https://github.com/cesarandreu/web-
app](https://github.com/cesarandreu/web-app)

~~~
quicksnap
I was looking at this a while ago, and it's a really nice starting point! I
too am aiming to remove Gulp from my workflow when possible.

------
cabirum
Great tutorial showing how many components work together in node/mongo/react.

It also absolutely blows my mind. This just feels wrong. 17 separate packages,
some providing _really_ basic stuff like serving favicons and parsing POST
requests that must be a part of bigger framework. Each package is of different
quality, testing strategy, and depends on a different developer who's
completely free to abandon his project tomorrow or introduce some backwards-
incompatible change. This trend as a whole looks unreliable, like a wobbly
house of cards near a working fan.

~~~
Gigablah
> Each package is of different quality, testing strategy, and depends on a
> different developer who's completely free to abandon his project tomorrow or
> introduce some backwards-incompatible change

Welcome to OSS! Really though, there's things like forking, community
involvement and SemVer.

The project configuration reflects the developer's decision not to use
webserver like nginx, otherwise things like serve-favicon and express.static
would be unnecessary.

------
TheAceOfHearts
I challenge your assumption that gulp + browserify is more straightforward
than webpack. Your setup is not representative of a real application.

I setup a project scaffold [0] with a configuration that supports development,
production, and testing environments. It has a heavily commented webpack
config.

No tests? No asset cache busting by updating name references? Come on, those
are basic requirements for a web project.

On top of that, webpack lets your dependencies be resolved as part of your
code, instead of relying on certain files being in certain folders: e.g. your
css and images.

[0] [http://github.com/cesarandreu/web-app](http://github.com/cesarandreu/web-
app)

~~~
renke1
Thanks for your project template. It looks really polished.

What is your experience in regard to running tests with Webpack?

* Can you test individual modules that use arbitrary loaders specified in your Webpack config?

* Can you run tests from the command line?

* Can you write your tests in ES6/7 (or anything else supported by Webpack's loaders)?

I was looking into combining jest with Webpack but every solution so far would
only compile your module directly with Babel and therefore skipping the power
of Webpack.

~~~
TheAceOfHearts
No huge issues with running tests that depend on webpack, but the developer UX
is not outstanding.

If you want to be able to do everything, you'll have to configure more stuff.
Honestly, I don't think it's worth the extra effort to try and configure
things to work with every possible workflow. Just setup what you need, and
then add stuff in as you find yourself wanting / needing it.

My advice is to avoid jest. It's too slow and clunky. If you want to stub
modules, there's rewire-webpack. If you're using babel and ES6 modules you'll
probably want to check out babel-plugin-rewire. I think there's a few other
alternatives, but I haven't had the need for any of these so far.

On to your questions...

> Can you test individual modules that use arbitrary loaders specified in your
> Webpack config?

Yes. The solution I have is to maintain a single webpack config maker function
that has a bunch of conditionals inside, and then I just use that function
from all my configs. When you set options.TEST to true, it'll set the entry
point to an empty object.

That means that my tests will be configured as close as possible to my
production and development. The same loader config will be used for all the
environments.

> Can you run tests from the command line?

Sure. In the web-app repo, it uses karma with phantomjs.

If you want to test your code using node... It's a bit more annoying, but also
doable. I've previously set it up like this: create a test.js [0] file, set it
as the entry-point in the webpack config, and use webpack context to include
all the tests you wanna run, and finally point mocha to the output file. If
you wanna use it in "live" mode, you can run webpack and mocha both with the
watch flag.

If you just wanna run a single test... You can specify a single test as your
entry-point, and then point mocha to it. Again, if you want "live" mode, you
can set the watch flag on both mocha and webpack.

> Can you write your tests in ES6/7 (or anything else supported by Webpack's
> loaders)?

Yes. They use the same loaders as the rest of your codebase.

[0]
[https://www.dropbox.com/s/35ebqijrp9nqyj3/Screenshot%202015-...](https://www.dropbox.com/s/35ebqijrp9nqyj3/Screenshot%202015-07-21%2014.11.06.png?dl=0)

------
verroq
Why is modern webdev this hard?

Even the todo-mvcs are all ~500 to 1000+ lines.

~~~
uptown
It's the future.

[http://blog.circleci.com/its-the-future/](http://blog.circleci.com/its-the-
future/)

~~~
agumonkey
This one hurts, deeply.

------
renke1
"I have yet to find any React boilerplate project with an easy to understand
webpack.config.js file."

I actually think that a simple Webpack configuration for a React project is
pretty easy to understand (thanks to Babel). Here is one that I use in one of
my projects [1]. Adding Less support is like one additional entry.

[1]:
[https://github.com/renke/perpetually/blob/master/webpack.con...](https://github.com/renke/perpetually/blob/master/webpack.config.js)

------
nothrabannosir
How long did it take you to write this?

------
roneesh
Impressive and awesome. This is perfect to catch up on using build tools. I
focus on core programming concepts in my own work, and at work most of that
stuff is automated to just a few commands, so I appreciate the gulp.js part of
your tutorial most. Thanks for the great work.

~~~
bmelton
I can't claim to be a Gulp expert, but it's always shocking to me how tools
like Gulp and Grunt become so pervasive without strong tutorials.

I ignored Grunt for years, always implementing my own hackneyed systems in
Python, until I eventually discovered this tutorial[1], which at least got me
a good introductory "this is how you use this thing that everybody else
already knows how to use, dummy" lesson.

[1] - [http://24ways.org/2013/grunt-is-not-weird-and-
hard/](http://24ways.org/2013/grunt-is-not-weird-and-hard/)

~~~
roneesh
Thanks for the resource!

Yeah they did kind of just sneak up about a year ago it seems. I remember
getting into the field two years ago I didn't hear about them. I suspect the
tipping point was the full migration to front-end frameworks instead of just
plain JS/jQuery.

~~~
bmelton
I think Grunt had been around for awhile. That video is December 2013ish, and
I remember trying and failing more than a couple of times to integrate it into
my workflow. According to whois, gruntjs.com was first registered in April
2012.

Now, to be fair to Grunt, my workflow is usually Python or Go on the backend,
and I just wanted something to manage my front-end assets, so it was never a
necessity for me, but knowing there's something that does what I want it to
do, while being unable to make it do the thing that it does is quite
frustrating.

------
alexggordon
I've been curious about React for awhile now, but every time I step in to play
around with it, I get really turned off by the syntax.

This is a react render function mentioned in the tutorial (gist with all code
here[0]):

    
    
      render() {
       let delta = this.props.delta ? (
         <strong className={this.props.delta > 0 ? 'text-success' : 'text-danger'}>
           {this.props.delta}
         </strong>
       ) : null;
     
       return (
         <div className='card'>
           {delta}
           {this.props.title}
         </div>
       );
      }
    

This is approximately that same function written in ERB and Rails syntax.

    
    
      <div class='card'>
        <%= content_tag_for(:strong, :class => @delta > 0 ? 'text-success' : 'text-danger' ) do %>
          <%= @this_props_title %>
        <% end %>
      </div>
    

On just a pure typing basis, the ERB would take half as long to type as the
react version. Even writing that same function in backbone templates (which I
use frequently) would take less text, and be easier to read. Maybe I haven't
given react and other js frameworks enough of a chance, but to a person that
hasn't learned them, that render function above is a huge deterrent.

[0]
[https://gist.github.com/alexggordon/820020aab934bf192b81](https://gist.github.com/alexggordon/820020aab934bf192b81)

~~~
lojack
Your ERB function is actually wrong though....

    
    
          <div class='card'>
            <% if this_props_delta? %>
              <%= content_tag_for(:strong, :class => @delta > 0 ? 'text-success' : 'text-danger' ) do %>
                <%= @this_props_delta %>
              <% end %>
            <% end %>
            <%= @this_props_title %>
          </div>
    

I'm not a rails developer, so I'm only marginally certain of the correctness
of this, and less certain if there's a more verbose way to write it. Likewise,
I've only played around with React, so its possible that the React version can
be made less verbose.

One could just as easily argue:

    
    
        <div className='card'>
          {() => { this.props.delta ? (
            <strong className={this.props.delta > 0 ? 'text-success' : 'text-danger'}>
                {this.props.delta}
              </strong>
          ) : null }() }
          {this.props.title}
        </div>
    

Is the same amount of typing. Honestly though, I feel as though this whole
argument is a bit of an apples-to-oranges type of argument.

~~~
kentor
Here's how I would inline it, and I encourage people to do it this way.
Intermediate variable is not necessary. Ternary is not necessary since false
evaluates to null in jsx.

    
    
      render() {
       return (
         <div className='card'>
           {this.props.delta > 0 &&
             <strong className={this.props.delta > 0 ? 'text-success' : 'text-danger'}>
               {this.props.delta}
             </strong>
           }
           {this.props.title}
         </div>
       );
      }

------
raylan_givens
Really great tutorial, I looked at your other tutorials and you have some
really great content. Thanks for sharing.

------
VeejayRampay
Standing ovation to you. That is a lot of work and a precious resource. Kudos.

------
wildpeaks
Swig seems superfluous in that stack given it already has React, one could
just use React to prerender the pages.

~~~
ssclafani
He provides his rational towards the bottom of the post:

> But do we really need a separate template for this? Why not just render
> everything inside the App component? Yes, you could do it, as long as you
> are okay with invalid HTML markup and not being able to include inline
> script tags like Google Analytics directly in the App component. But having
> said that, invalid markup is probably not relevant to SEO anymore and there
> are workarounds to include inline script tags in React components. So it's
> up to you, but for the purposes of this tutorial we will be using a Swig
> template.

~~~
vkjv
I'm not clear on the "invalid markup" portion. Aren't `data-*` attributes
valid for all tags in HTML5? Also, if you really don't want them you can
render with `React.renderToStaticMarkup`.

------
henryw
Looks pretty cool! I like the graphics. I think Meteor.js does this too, but
with only one resume buzzword.

------
joshuajenkinsyo
It's great that you're sharing a very practical tutorial, but did it occur to
you that women (and generally reasonable people) might not be particularly
motivated to learn how to build a woman judging app? Seems like your example
project could be less alienating.

------
ngoel36
Really awesome job

------
CmonDev
Is it really a _" full-stack"_ _" app"_? Sounds more like a set of scripts:

 _> "...using React, Node.js, MongoDB and Socket.IO..."_

~~~
sehr
Not a single one of those things are 'scripts' in the colloquial sense of the
word

