React, Webpack, Babel 101 (in progress!)

Table of Contents

Chapter 1 - React, Webpack, Babel 101

  • Reference React.js, Webpack, Babel

  • Create project directory mkdir react-hello-world && cd react-hello-world

  • Create package.json for Dependency Management npm init

  • Configure Webpack (Task Automation) to generate static assets representing modules with dependencies that it bundles npm install --save webpack

  • Create webpack.config.js touch webpack.config.js

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

// Path of bundle file output
var BUILD_DIR = path.resolve(__dirname, 'src/client/public');

// Path of React.js codebase
var APP_DIR = path.resolve(__dirname, 'src/client/app');

var config = {

    // Starting point of app
    entry: APP_DIR + '/index.jsx',

    // Instructions for Webpack to output bundle.js after bundling process
    output: {
        path: BUILD_DIR,
        filename: 'bundle.js'
    }
};

module.exports = config;
  • Create input subfolder mkdir src && mkdir src/client && mkdir src/client/app && touch src/client/app/index.jsx

  • Create sample JSX in src/client/app/index.jsx console.log('Hello');

  • Run Webpack to compile and generate bundle.js and bundle.js.map file in src/client/public using Development Mode ./node_modules/.bin/webpack -d

  • Open index.html in browser

  • Change from var config = { to module.exports = { debug: true, ...

  • Run Webpack in Dev Mode ... /webpack -d or Prod Mode ... /webpack -p (minified)
  • See CLI Wiki
$ ./node_modules/.bin/webpack -d
Hash: 7d66afc04ec55432dfc0
Version: webpack 1.13.3
Time: 87ms
        Asset     Size  Chunks             Chunk Names
    bundle.js  1.66 kB       0  [emitted]  main
bundle.js.map  1.62 kB       0  [emitted]  main
   [0] ./src/client/app/index.jsx 27 bytes {0} [built]
  • Create src/client/index.html to using bundle.js output
<html>
  <head>
    <meta charset="utf-8">
    <title>React.js using NPM, Babel6 and Webpack</title>
  </head>
  <body>
    <div id="app" />
    <script src="public/bundle.js" type="text/javascript"></script>
  </body>
</html>
  • Add babel-loader to translate JSX and ES6 (to be supported by browsers) before Webpack bundling npm install babel-loader babel-core babel-preset-es2015 babel-preset-react --save

  • Configure babel-loader to use ES6 and JSX plugins (better than alternative to adding to webpack.conf.js ... , query: {presets: ['react', 'es2015']} touch .babelrc
    {
    "presets" : ["es2015", "react"]
    }
    
  • Update Webpack configuration to use babel-loader before bundling files
    ...
    var config = {
    ...
    module : {
        
      // Array of loader properties as elements (i.e. babel-loader, etc)
      loaders : [
        {
          // File extension (i.e. .js and .jsx) the loader processes via the test property
          test : /\.jsx?/,
          include : APP_DIR,
          loader : 'babel' // Name of the loader (i.e. babel-loader)
        }
      ]
    }
    }
    
  • Install React and React DOM npm install react react-dom --save

  • Change index.jsx to: ``` import React from ‘react’; import {render} from ‘react-dom’;

class App extends React.Component { render () { return <p> Hello React!</p>; } }

render(, document.getElementById(‘app’));


- Run Webpack again
`./node_modules/.bin/webpack -d`

- Open index.html in browser

- Customise Webpack with Watch to automatically re-bundle when change detected. Reload webpage still required
`./node_modules/.bin/webpack -d --watch`

- Configure tool runners using NPM by updating package.json with the following for Development and Production Modes:

“scripts”: { “dev”: “webpack -d –watch”, “build” : “webpack -p” },


- Now just run with `npm run dev` or `npm run build`

- Add engines to package.json

“engines”: { “node”: “5.10.1”, “npm”: “3.10.3” },


- Add `publicPath` to webpack.prod.config.js to explicitly state directory containing bundle outputs so not get error public/bundle.js not found error
- References: https://github.com/webpack/docs/wiki/Configuration

publicPath: “/src/client/”


- Install Express server `npm install express --save`

- Create Procfile for Heroku i.e. `web: npm run webpack_prod; npm run express-server;` or use `postinstall:` in package.json to process before server starts instead 

- Add [concurrently](https://codingbox.io/react-for-beginners-part-1-setting-up-repository-babel-express-web-server-webpack-a3a90cc05d1e#.clvjirdpa)

`npm install concurrently --save-dev`

“scripts”: { “webpack_dev_watch”: “./node_modules/.bin/webpack -d –watch –config webpack.dev.config.js”, “express-server”: “node ./server”, “dev”: “concurrently –kill-others "npm run webpack_dev_watch" "npm run express-server"”, “webpack_prod”: “./node_modules/.bin/webpack -p –config webpack.prod.config.js”, “test”: “echo "Error: no test specified" && exit 1” },


- Setup source maps by updating webpack.dev.config.js with below code then open Chrome Dev Tools and go to Sources > top > webpack:// > . > src/client/app / ; and add breakpoints to debug

output: {
			...
    sourceMapFilename: 'bundle.js.map',
    devtoolModuleFilenameTemplate: 'webpack:///[resource-path]?[hash]',
    devtoolFallbackModuleFilenameTemplate: 'webpack:///[resourcePath]?[hash]'
},

devtool: 'source-map' ```
  • Setup CSS and Style loaders for Webpack to inject style tag into DOM. Install with NPM to avoid errors when run i.e. Module not found: Error: Cannot resolve module 'css'
npm install style-loader --save
npm install css-loader --save
  • Setup ENV in webpack.prod.config.js to prevent warning messages on Heroku saying No ENV file found
    plugins: [
      new webpack.DefinePlugin({
          "process.env": {
              NODE_ENV: JSON.stringify("production"),
              PORT: 5000
          }
      })
    ],
    
  • Test works local after removing dependencies rm -rf node_modules

  • Create Heroku app and use heroku local to test locally
    heroku create reactvr
    heroku local web
    git add --all .
    git commit
    git push heroku master
    heroku open
    heroku restart
    heroku logs --tail
    heroku run bash
    

JavaScript Refresher (Reintroduction by Mozilla)

  • JavaScript Refresher

  • call vs apply
  • call uses “C”omma to separate self defined as first argument and a second argument
  • apply takes an “A”rray with self as first argument and an array as second argument
function Person(first, last) {
  this.first = first;
  this.last = last;
}

function lastNameCaps(arg) {
  return this.last.toUpperCase() + arg;
}
var s = new Person("Luke", "Schoen");
lastNameCaps.call(s, "a");
"SCHOENa"

function lastNameCaps(...args) {
  return this.last.toUpperCase() + args[0] + args[1];
}
var s = new Person("Luke", "Schoen");
lastNameCaps.apply(s, ["a", "b"]);
"SCHOENab"

TODO

Webpack

  • Webpack config http://jlongster.com/Backend-Apps-with-Webpack–Part-I
  • Webpack config https://medium.com/@dabit3/beginner-s-guide-to-webpack-b1f1a3638460#.yw56ek5k4
  • Webpack nodemon http://stackoverflow.com/questions/28782656/how-to-run-node-js-app-with-es6-features-enabled
  • Webpack config https://www.twilio.com/blog/2015/08/setting-up-react-for-es6-with-webpack-and-babel-2.html
  • Rollup only loads relevant https://github.com/rollup/rollup/wiki
  • React Heroku Webpack http://ditrospecta.com/javascript/react/es6/webpack/heroku/2015/08/08/deploying-react-webpack-heroku.html
  • ES7 http://stackabuse.com/node-js-async-await-in-es7/
  • SocketIO usage http://socket.io/#how-to-use
  • Node Express REST API http://blog.modulus.io/nodejs-and-express-create-rest-api
  • Node generate webpage http://theholmesoffice.com/how-to-build-a-simple-webpage-in-node-js/
  • Node MVC http://theholmesoffice.com/getting-ready-for-scalability-creating-an-mvc-framework-for-our-node-js-page/
  • Node Bluemix https://www.ibm.com/developerworks/library/wa-simplenode1-app/
  • Server side render Node Express https://www.smashingmagazine.com/2016/03/server-side-rendering-react-node-express/
  • Complex React app code https://github.com/zen-js-code/react-universal-web-apps/tree/simple%2Bssr/app
  • Server side React Node https://medium.com/front-end-hacking/server-side-rendering-with-react-and-express-382591bfc77c#.cv0n0c4rt
  • Server side Node http://stackoverflow.com/questions/14951251/how-to-call-node-js-server-side-method-from-javascript

TDD / BDD Testing

  • Mocha Node https://www.codementor.io/nodejs/tutorial/unit-testing-nodejs-tdd-mocha-sinon

CLI Node

  • Node CLI prompt https://docs.nodejitsu.com/articles/command-line/how-to-prompt-for-command-line-input/
  • Node CLI https://www.sitepoint.com/javascript-command-line-interface-cli-node-js/
  • Node REPL http://www.2ality.com/2011/11/node-repl-start.html
  • Node REPL http://node.readthedocs.io/en/latest/api/repl/
  • Node Custom REPL https://docs.nodejitsu.com/articles/REPL/how-to-create-a-custom-repl/

Node 7 API

  • Node 7 API https://nodejs.org/api/synopsis.html
  • Optimist Node https://github.com/substack/node-optimist
Written on November 7, 2016