React Starter Kit

Daniel Kopka / @danielkopka / 20.01.2016 Warsaw

Senior Software Engineer @ Syncano

About me

We will talk about:

Flow

Tools

Project layout

Flow

What kind of steps we need to take from source to deployment

Development

Deployment

Tools

Grunt

Gulp

Scripts (package.json)

ShellJS

Source

Plain text is not enough

Challenges

JSX - Babel

ES6 - Babel

CSS pre-processors - up to you

Promise - Bluebird

Polyfills - Babel

Routing - react-routing / react-router

Flux - Flux / Redux / Reflux / Alt

Example - Babel


// .babelrc
{
  "presets": ["react", "es2015", "stage-2"],
  "plugins": ["add-module-exports"],
  "env": {
    "development": {
      "presets": ["react-hmre"]
    }
  }
}
						

// Build
babel src --out-dir lib
						

Lint

Because style matters

There are two kinds of people


function() {

}
                    	

function ()
{

}
                    	

Solutions

JSHint

JSLint

ESLint + eslint-plugin-react

Example - ESLint


// .eslintrc
{
  "parser": "babel-eslint",
  "env": {
    "browser": true,
    "es6": true
  },
  "plugins": [
    "react"
  ],
  "rules": {
    "no-inline-comments": 2,
    "comma-dangle": [2, "never"]
    ...
  }
}
						

// Lint
eslint src/** test/**
						

Test

Because nobody does it

Challenges

React DOM - jest-cli / karma / react-addons-test-utils

Unit Tests - mocha / chai / should

Integration Tests - Nightwatch / BrowserSync

Browser Tests - karma + phantomjs

Mocking - jest-cli / mockery / sinon / nock

Coverage - isparta / istanbul

Remember to add proper transpiler!

Example - Unit Test


describe('Some Object', function() {
  describe('#init()', function() {

    it('should have properties', function() {
      var baseObject = {x: 1, y: null};
      should(baseObject).have.property('x').which.is.Number();
      should(baseObject).have.property('y').which.is.null();
  ....
						

// Run
mocha 'test/unit/**/*.js' --compilers js:babel-register
						

Build

Because we need to put it together

Challenges

Source maps

Minification

Compression

Versioning

Cleanup

Tools

Webpack

Browserify

Example - Webpack


// webpack.config.js
module.exports = {
  name: 'package',
  devtool: 'source-map',
  entry: path.join(__dirname, 'src', 'app.jsx'),
  target: 'web',
  module: {
    loaders: [
      { test: /\.jsx$/, exclude: /node_modules/, loader: 'babel-loader'}
    ]
  },
  resolve: {
    modulesDirectories: ['node_modules'],
    extensions: ['', '.js', '.json']
  }
}
						

// Run
webpack
						

Deploy

Because someone will be using it

Where?

Files (sftp) - dploy

S3 - deploy-s3 / s3-deploy

CloudFront

gh-pages :P - gh-pages

Please, please use CI!

Serve

Because it's nice to simplify our lives

Challenges

Development server - webpack-dev-server / beefy

Hot reloading - react-hot-loader / react-transform-hmr

Project layout

There is no best one :)

Challenges

Everything is a component

How to handle tests?

How to handle assets?

Some ideas

Dummy components

Smart components

Assets

Develop own solution :)

Root


├── .babelrc
├── .eslintrc
├── .gitignore
├── .travis.yml
├── circle.yml
├── dist
├── docs
├── package.json
├── src
└── test
						

test


test/
├── e2e
└── unit
						

dist


dist/
├── css
│   ├── app-a7943ea11d.css
│   ├── vendor-21ecda5146.css
│   └── icons-250c6f457d.css
├── fonts
│   └── icons
│       ├── Icons-05ae77937e.eot
│       ├── Icons-c2906c403a.woff
│       └── Icons-cff2ca9105.ttf
├── img
│   └── logo-f1e5710918.svg
├── index.html
└── js
    ├── app-0f88bd7d2e.js
    └── vendor-21ecda5146.js
						

src


src/
├── apps
│   └── Account
│   │   ├── index.js
│   │   ├── Login.jsx
│   │   └── Login.css
│   └── index.js
├── components
│   ├── Button.css
│   └── Button.jsx
├── app.jsx
├── routes.jsx
└── assets
						

Questions?

Thanks!

Daniel Kopka / @danielkopka / 20.01.2016 Warsaw

Senior Software Engineer @ Syncano