Hacker News new | ask | show | jobs
by sdnguyen90 3681 days ago
This is how I start off a React app:

  $ npm install --save react react-dom
  $ npm install --save-dev webpack webpack-dev-server babel-core babel-preset-es2015 babel-preset-react react-addons-test-utils
/webpack.config.js

  module.exports = {
    entry: 'src/index.js',
    output: 'dist/bundle.js',
    module: {
      loaders: [{
        test: /\.jsx?$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          presets: ['es2015', 'react']
        }
      }]
    }
  }

/src/index.js

  import React from 'react';
  import ReactDOM from 'react-dom';
  
  const MyRootComponent = (props) => {
    return <div>Hello World</div>
  };
  
  ReactDOM.render(MyRootComponent, document.getElementById('react-app'));

/static/index.html

  ...
  <body>
    <div id="react-app"></div>
    <script src="bundle.js"></script>
  <body>
  ...
start the web server

  $ webpack-dev-server --content-base static/
There is nothing forcing you to use all the extra dependencies. You can build a full app without them.
4 comments

> There is nothing forcing you to use all the extra dependencies

This right here is a major problem with a ton of apologists. "You don't need to use X and Y, just start with barebones Z".

If you're doing your own side project, sure. Or if you're lucky to be developer #1 in a greenfield project. I can count on one hand the number of times in my career that's happened.

Most of the time, you're going to be maintaining someone else's work. They'll have a ton of dependencies and glue and workarounds, and you're really, really lucky if they've written tests or documentation. So all the complexity mentioned in the article? You get to deal with that, only not so neatly put together. More likely they'll have an out-of-date version of react-router that's incompatible with the library you're trying to install, upgrading react-router means rewriting a ton of code because they love to change their API every other release....

Now I like React, and I've built things with it. But there is a huge and growing PR problem with it right now, that for all its promise there is too much incidental complexity, too many ways to do it, a lack of standardization around things like build tools. Companies aren't overjoyed at having codebases that become impossible to maintain 6 months out, when the frontend devs jump ship. Whether the answer is a more structured framework like Ember or Angular, I don't know, but there is a lot of fatigue and frustration around trying to build and maintain a project out of lots of tiny pieces, and it's showing in this thread.

The extreme modularization is a huge, huge issue. There is a slight settling: the recommendation for state management shifting almost exclusively to Redux is IMO a very good thing, if only for the fact of how brutally simple it is, with almost zero chance there will be any API changes. Packages such as react-router, with constant API changes, are a nightmare though. Standardisation this year would be good: state management (Redux), a router (a settled react-router), immutability (Immutable), a method of dealing with asynchrony/promises that's well documented and easy for people to just pick up and use, a drop in test framework (personal bugbear is setting up the multifarious bits of test/coverage/complexity tools - Ava + NYC + Plato seems a very good build so far for this, but it's very young). But it's the configuration of build tools which is the killer

React itself is very simple, but then so is jQuery, and having to pick apart the twenty or thirty jQuery plugins + associated spaghetti the last dev dropped into a project is even less fun than the current situation, it just took a lot less of a deep understanding of JS; one of the issues I'm starting to get a lot more of is devs dropping in prebuilt components, which is just jQuery all over again, but in extremis.

Nifty! The config needed some fixes and tweaks (using `babel-loader`, `<MyRootComponent/>`, a `resolve` section) before it actually works out of the box, but it's a nice idea. I made a `git clone`:able version of the setup with fixes and a `Makefile` at https://github.com/johan/make-react-hack
Out of curiosity, why did you write the function like this:

   const MyRootComponent = (props) => {
When it's shorter and more obvious what's happening if you write them like this:

  function MyRootComponent(props) {
"An arrow function expression has a shorter syntax compared to function expressions and lexically binds the this value (does not bind its own this, arguments, super, or new.target). Arrow functions are always anonymous."

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Why do you want it to be anonymous in this context? I get you can drop the `return`, but I don't see how you gain anything (apart from a tiny reduction typing and a small increase in incomprehensibility) by using anonymous functions to define components (I know the pattern is used a lot in the wild, but there seems to be zero reasoning for it; lexical binding isn't really relevant here)
In this case: You're potentially closing over node's "this inside of module body === exports" which seems more confusing than helpful..?
None of which, in this context, matters; none of those is in scope where the function is defined, so it won't be closing over them anyway.
Yep, that looks much cleaner and easier to reason about. Thanks for the sample config file.