7

I'm trying to learn ReactJS and I'm finding a lot of tutorials confusing because they layer NodeJS, Babel, and Webpack into their explanations all at once and gloss over a lot of what's going on. I'm trying to do a basic Hello World app and add these tools one at a time so I can understand what is doing what better.

I start with a basic static HTML and JS file:

index.html:

<!DOCTYPE html>
<html>
  <body>
    <div id="app"></div>
    <script src="https://unpkg.com/react@15/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15/dist/react-dom.js"></script>
    <script src="index.js"></script>
  </body>
</html>

index.js (not using JSX yet):

class Hello extends React.Component {
  render() {
    return React.createElement('div', null, `Hello ${this.props.toWhat}`);
  }
}

ReactDOM.render(
  React.createElement(Hello, {toWhat: 'World'}, null),
  document.getElementById('app')
);

Okay so this works as expected. Now I want to set up a NodeJS project that serves this exact content so I start with:

npm init -y

And that gives me a package.json. How do I configure NodeJS to serve this basic Hello World code at say localhost:8080? My next step would be to add Babel so I can use JSX, but I don't want to skip to that step until I understand the server setup better.

Captain Stack
  • 3,572
  • 5
  • 31
  • 56
  • 1
    you need to actually run a server. https://github.com/indexzero/http-server is an easy solution you can just run in your directory and it will serve static files. or if you have python you can run `python -m SimpleHTTPServer` – Andy Ray Jan 14 '17 at 02:19
  • 2
    Why do you need a server? Isn't react.js just a library? I looked over the basic setup instructions on (https://facebook.github.io/react/docs/installation.html) and I didn't see any mention of node. and I would think webpack+babel should also be optional if you aren't transpiling anything. – chiliNUT Jan 14 '17 at 03:02
  • 1
    Well it is optional. My above setup doesn't use a server. However, I will want to deploy this eventually with something, and I do want to use Babel so I can use JSX. My understanding is that production-grade React apps use most of these tools, and that's what I'm trying to learn. I'm just trying to learn them one at a time so I can understand what each one is doing. – Captain Stack Jan 14 '17 at 03:16
  • @CaptainStack ever you create app using node? – areiilla Jan 14 '17 at 04:07
  • @CaptainStack http://stackoverflow.com/a/4720770/5992765 load your index.html with node – areiilla Jan 14 '17 at 04:09
  • Since you need a server anyway and since Webpack is the standard build/serve tool in the react world I would suggest you just go ahead and use it with your project. It will provide the server you need. With a simple setup it will be easy to then inspect the web pack config and get an idea for the basics of what is going on. – rg88 Jan 14 '17 at 17:51
  • For those who are searching the similar questions: I found the guide from ReactArmory pretty useful https://reactarmory.com/guides/learn-nude-react/custom-react-elements – Hoàng Long Jul 18 '17 at 09:40

3 Answers3

15

ReactJS is a UI framework. To learn ReactJS, you don't need nodejs, npm or any other fancy tools. Just a library script file you can insert the library on a simple index.html and start writing javascript. Note because you are writing on web you need two scripts (exactly like you had).

<script src="https://unpkg.com/react@latest/umd/react.development.js" crossorigin="anonymous"></script> <script src="https://unpkg.com/react-dom@latest/umd/react-dom.development.js" crossorigin="anonymous"></script>

Here is an example 1 with just pure javascript & React:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script src="https://unpkg.com/react@latest/umd/react.development.js" crossorigin="anonymous"></script>
  <script src="https://unpkg.com/react-dom@latest/umd/react-dom.development.js" crossorigin="anonymous"></script>
</head>
<body>

  <div id="root"></div>

  <script>
    function Hello(props) {
     return React.createElement('h1', null, `Hello ${props.text}`);
  }

  ReactDOM.render(
    React.createElement(Hello, {text: 'World'}, null),
    document.getElementById('root')
  );
  </script>

</body>
</html>

If you notice closely, everything in example 1 script is in JavaScript, there isn't html inside the script, just pure javascript in my script. React & ReactDom gets inserted into my window so I can access it globally. Great this will work, I can keep doing this doing this but React introduced a way to insert html into javascript (JSX) so we can write less javascript (we r all lazy developers). So how can we write JSX because browsers doesn't understand JSX and they only understand javascript? Well we will use a tool called standalone library (babel standalone). It will transpile (converts all the code you wrote into browser readable javascript) all the code you wrote in JSX and javascript into a normal javascript file. Before this process starts, you need to let the standalone library know which javascript files you want to transpile so you attach type="text/babel" like this <script type="text/babel">....</script>. Once you dom loaded, standalone library will transpile the scripts you told it to transpile and inserts pure javascript into your dom then your javascript will run. Yes I said that... 1.First your code will transpile 2. then it loaded into the dom 3. Then my javascript runs. This is exactly why we should never use it in production because of the huge delay that happens before your javascript starts running with reactjs. That is where modern tools will help.

Here is example 2 with JSX & React on browser:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script src="https://unpkg.com/react@latest/umd/react.development.js" crossorigin="anonymous"></script>
  <script src="https://unpkg.com/react-dom@latest/umd/react-dom.development.js" crossorigin="anonymous"></script>
  <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js" crossorigin="anonymous"></script>
</head>
<body>

  <div id="root"></div>

  <script type="text/babel">
     function Hello(props) {
        return <h1>Hello {props.text}</h1>;
      }

      ReactDOM.render(
         <Hello text="World" />,
    document.getElementById('root')
      );
   </script>


</body>
</html>

Great now that we inserted, JSX, what if I want to use latest ES6 and beyond features? Browsers don't support them yet. The standalone library comes to rescue again. The library gives you ability to add plugins to compile latest javascript or jsx or others into javascript.

Here is example 3 with ES6 and JSX on browser with a plugin:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script src="https://unpkg.com/react@latest/umd/react.development.js" crossorigin="anonymous"></script>
  <script src="https://unpkg.com/react-dom@latest/umd/react-dom.development.js" crossorigin="anonymous"></script>
  <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js" crossorigin="anonymous"></script>
</head>
<body>
  <div id="root"></div>

  <script data-plugins="transform-es2015-modules-umd" type="text/babel">
     class Hello extends React.Component {
      render() {
        return <h1>Hello {this.props.text}</h1>;
      }
    }

      ReactDOM.render(
         <Hello text="World" />,
    document.getElementById('root')
      );
   </script>

</body>
</html>

All these tools like babel, webpack, help make your app ready for production but for learning it is much easier first to understand react without extra tools then slowly start expanding.

** Note: All the examples are for learning purposes and prototyping and not for production use, if you read my entire answer you will know why.

РАВИ
  • 11,467
  • 6
  • 31
  • 40
3

The simplest way would be using a lib like node-static (npm install node-static --save-dev) and adding it as the start script in your package.json

"scripts": {       
   "start": "static ./"
 },

Start it with the npm start command.

Though this will work, if you plan to add babel I highly recommend you to jump into webpack (or any other build tool, I personally think webpack is the best option) because webpack already have a development server that will serve static files during development for you ( witch a lot of goodies like hot reload ) and webpack is not that hard to learn, the official documentation is somewhat difficult for beginners, I recommend you to read this how-to first.

Tiago Engel
  • 3,533
  • 1
  • 17
  • 22
  • Indeed. The job of a developer is to learn new development tools constantly. If you don't have to learn an entirely new build tool every two weeks someone is not doing their job. Oh, and the other 10% of a developer's job is to write the actual application. – HeadCode Aug 02 '17 at 00:15
-1

First of all create your webpack.config.js file in your root folder like this:

var path = require('path');
var webpack = require('webpack');

module.exports = {
  devtool: 'cheap-module-eval-source-map',
  entry: [
    'webpack-hot-middleware/client',
    './index.js' //path to your index.js in your case
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/static/'
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
  ],
  module: {
    loaders: [
    // js
    {
      test: /\.js$/,
      loaders: ['babel'],
      include: path.join(__dirname, 'client')
    },
    // CSS
    { 
      test: /\.styl$/, 
      include: path.join(__dirname, 'client'),
      loader: 'style-loader!css-loader!stylus-loader'
    }
    ]
  }
};

After that create your server.js file to server static files with express:

var path = require('path');
var express = require('express');
var webpack = require('webpack');
var config = require('./webpack.config.dev');

var app = express();
var compiler = webpack(config);

app.use(require('webpack-dev-middleware')(compiler, {
  noInfo: true,
  publicPath: config.output.publicPath
}));

app.use(require('webpack-hot-middleware')(compiler));

app.get('*', function(req, res) {
  res.sendFile(path.join(__dirname, 'index.html'));
});

app.listen(3000, 'localhost', function(err) {
  if (err) {
    console.log(err);
    return;
  }

  console.log('Listening at http://localhost:3000');
});

Lastly add .babelrc file to your root folder to tell babel about the presets you're about to use, (in our case es2015 and react):

{
 presets: 'es2015'
}

You will need the following additional modules:

babel-loader, babel-core, babel-preset-react, babel-preset-es2015, webpack-dev-middleware, webpack-hot-middleware, express

Good luck ;)

Razvan Alex
  • 1,706
  • 2
  • 18
  • 21