Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris...

67
Building and Deploying React Applications Boris Nadion [email protected] @borisnadion

Transcript of Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris...

Page 1: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

Building and Deploying React Applications

Boris Nadion [email protected]

@borisnadion

Page 3: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

astrailshttp://astrails.com

Page 4: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

2005

Page 5: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

awesome web and mobile apps

Page 6: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

building & deploying

Page 7: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

building & deploying

Page 8: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

facebookincubator/create-react-appCreate React apps with no build configuration.

Page 9: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

npm install -g create-react-app

create-react-app my-app cd my-app/ npm start

Page 10: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

customizelike adding css preprocessors

Page 11: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

yarn eject / npm eject

Page 12: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

yarn eject / npm eject

Page 13: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

not trivial

Page 14: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

start from scratch

Page 15: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

setup internals

Page 16: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion
Page 17: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

environments✓ development

✓ production

x test

Page 18: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

package.json

Page 19: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

"babel": { "presets": [ [ "es2015", { "modules": false } ], "react", "stage-0" ], "plugins": [ "transform-runtime", "babel-plugin-transform-class-properties", "transform-object-rest-spread" ], "env": { "production": { "plugins": [ "transform-react-inline-elements", "transform-react-constant-elements", "transform-react-remove-prop-types" ] } } },

Page 20: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

babel-plugin-transform-class-properties

class Bork { //Property initializer syntax instanceProperty = "bork"; boundFunction = () => { return this.instanceProperty; } //Static class properties static staticProperty = "babelIsCool"; static staticFunction = function() { return Bork.staticProperty; } }

let n = { x, y, ...z };

transform-object-rest-spread

Page 21: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

transform-react-inline-elements

babelHelpers.jsx(Baz, { foo: "bar" }, "1");

const Hr = () => { return <hr className="hr" />; }; const _ref = <hr className="hr" />; const Hr = () => { return _ref; };

transform-react-inline-elements

Baz.propTypes = {…}

transform-react-remove-prop-types

Page 22: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

“start":"env NODE_ENV=development webpack-dev-server --progress --colors",

“build":"rimraf dist &&env NODE_ENV=production webpack --colors &&cp ./dist/* ../public/assets/",

Page 23: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion
Page 24: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

webpack config

Page 25: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

webpack config

http://imgur.com/gallery/EnAmi

Page 26: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion
Page 27: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

const ENV = process.env.NODE_ENV; const VALID_ENVIRONMENTS = ['development', 'production']; if (!VALID_ENVIRONMENTS.includes(ENV)) { throw new Error(`${ ENV } is not valid environment!`); }

const DEVELOPMENT_CONFIG = require('./config/webpack.dev'); const PRODUCTION_CONFIG = require('./config/webpack.prod'); const config = { development: DEVELOPMENT_CONFIG, production: PRODUCTION_CONFIG }[ENV]; const COMMON_CONFIG = { … };

module.exports = webpackMerge.smart(COMMON_CONFIG, config);

Page 28: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

let’s look at the codewebpack.config.js + dev + prod

Page 29: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

3 bundlesbundle.js

+ cssclient.js

+ cssasync.js

+ css

Page 30: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

yarn start v0.24.4 $ env NODE_ENV=development webpack-dev-server --progress --colors 10% building modules 2/2 modules 0 active Project is running at http://0.0.0.0:9001/ webpack output is served from http://localhost:9001/assets/ 404s will fallback to /index.html Hash: 9a91c0c826ebb4c40f2a Version: webpack 2.6.1 Time: 6507ms Asset Size Chunks Chunk Names 0.js 806 bytes 0 [emitted] client.js 313 kB 1 [emitted] [big] client vendor.js 1.45 MB 2 [emitted] [big] vendor 0.js.map 572 bytes 0 [emitted] client.js.map 360 kB 1 [emitted] client index.html 421 bytes [emitted] webpack: Compiled successfully.

Page 31: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

dev mode demohot reload, async load, eslint errors

Page 32: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

//… import { AppContainer } from 'react-hot-loader'; //…const hotRender = () => { render( <AppContainer> <Application store={ store } /> </AppContainer>, document.getElementById('root') ); }; hotRender(); module.hot.accept('components/Application', hotRender);

hot reload

Page 33: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

import asyncComponent from 'components/AsyncComponent'; const AsyncDashboard = asyncComponent(() => import('./Dashboard').then(module => module.default) ); export default AsyncDashboard;

async load

Page 34: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

import React from 'react'; const asyncComponent = (getComponent) => class AsyncComponent extends React.Component { state = { Component: null }; componentWillMount() { if (!this.state.Component) { getComponent().then(Component => { this.setState({ Component }); }); } } render() { const { Component } = this.state; if (Component) { return <Component { ...this.props } />; } return null; } }; export default asyncComponent;

async load

Page 35: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

prod buildyarn build

Page 36: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

yarn build v0.24.4 $ rimraf dist && env NODE_ENV=production webpack --colors && cp ./dist/* ../public/assets/ Hash: f5404348a5a4eadca2c5 Version: webpack 2.6.1 Time: 9894ms Asset Size Chunks Chunk Names client-149e7f81934ccd4797d6.bundle.js.map 183 kB 1 [emitted] client 0-b065752a37e19efffbe1.bundle.js 318 bytes 0 [emitted] webpack-chunk-manifest.json 79 bytes [emitted] vendor-411f8db22ac4a264ff0d.bundle.js 265 kB 2 [emitted] [big] vendor client-e9da9d78d42878a4c3a5a7ab1330ea79.css 2.7 kB 1 [emitted] client 0-b065752a37e19efffbe1.bundle.js.map 2.11 kB 0 [emitted] client-149e7f81934ccd4797d6.bundle.js 24 kB 1 [emitted] client client-e9da9d78d42878a4c3a5a7ab1330ea79.css.map 120 bytes 1 [emitted] client client-149e7f81934ccd4797d6.bundle.js.gz 8.35 kB [emitted] vendor-411f8db22ac4a264ff0d.bundle.js.gz 77.9 kB [emitted] index.html 493 bytes [emitted] webpack-asset-manifest.json 468 bytes [emitted]

Page 37: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

new webpack.HashedModuleIdsPlugin(),

new ManifestPlugin({ fileName: 'webpack-asset-manifest.json' }), new ChunkManifestPlugin({ filename: 'webpack-chunk-manifest.json', manifestVariable: 'webpackManifest' }),

Page 38: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

// webpack-chunk-manifest.json {"0":"0-b065752a37e19efffbe1.bundle.js"}

// webpack-asset-manifest.json { "0-b065752a37e19efffbe1.bundle.js": "0-b065752a37e19efffbe1.bundle.js", "0-b065752a37e19efffbe1.bundle.js.map": "0-b065752a37e19efffbe1.bundle.js.map", "client.css": "client-e9da9d78d42878a4c3a5a7ab1330ea79.css", "client.css.map": "client-e9da9d78d42878a4c3a5a7ab1330ea79.css.map", "client.js": "client-149e7f81934ccd4797d6.bundle.js", "client.js.map": "client-149e7f81934ccd4797d6.bundle.js.map", "vendor.js": "vendor-411f8db22ac4a264ff0d.bundle.js" }

Page 39: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

4 bundlesvendor.js client.js 0.js client.css

Page 40: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

html from server

/* … */ <script type=“text/javascript”> window.apiEndPoint = "http://stage.example.com" </script> <link href="//xxx/client.css" rel="stylesheet" /> <script src="//xxx/vendor.js”></script> <script src="//xxx/client.js"></script> /* … */

} xxx=?

Page 41: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

<div id="root"></div> <%= api_endpoint_from_environment %> <%= client_application_stylesheet_tag 'client.css' %><%= client_application_javascript_tag 'vendor.js' %> <%= client_application_javascript_tag 'client.js' %>

server template

Page 42: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

module ClientApplicationHelper

# client_application_javascript_tag 'client.js' def client_application_javascript_tag(bundle) src = if client_application[:use_manifest]

# "client.js": "client-149e7f81934ccd4797d6.bundle.js", manifest = client_application[:asset_manifest][bundle] # static asset "/assets/#{bundle}" else # dev mode "http://localhost:9001/assets/#{bundle}" end javascript_include_tag(src) end def client_application_stylesheet_tag(bundle) # … # almost the same but no need to render in dev mode end end

Page 43: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

serve from

• webpack dev server (for dev mode)

• same server, static assets

• static assets through CDN

• CDN direct

• whatever

Page 44: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

awesome

Page 45: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

almost awesome

Page 46: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

<%= client_application_stylesheet_tag 'client.css' %> <%= client_application_javascript_tag 'vendor.js' %> <%= client_application_javascript_tag 'client.js' %>

in a context of a request

Page 47: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

current_userreq.current_user, request.user[. is_authenticated], …

Page 48: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

module ClientApplicationHelper def client_application_javascript_tag(bundle) src = if client_application[:use_manifest] # "client.js": "client-149e7f81934ccd4797d6.bundle.js", manifest = assets_manifest_for(current_user)[bundle] # … end javascript_include_tag(src) end end

Page 49: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

storing manifests per userS3, database, redis, memcache, etc

+ default manifest for the rest of the users

Page 50: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

assets_manifest_for(current_user)[bundle]

• A/B testing

• features testing in production env

• UI experiments

• gradually rolling out new features

Page 51: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

assets_manifest_for(current_user)[bundle]

bundles v1.12default

bundles v1.13debugging an issue

bundles v2.0testing new release

user with a bug in v1.12

marketing user

all users

Page 52: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

separate server and client deployments

Page 53: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

client lifecycle

• build: get new bundles + manifest

• deploy: upload bundles to remote storage (S3) + warm up CDN

• release: update user’s or default manifest

Page 54: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

awesome

Page 55: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

almost awesome

Page 56: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

http://www.enjoyart.com/single_posters/animals_art_photo/NoahsArkTakinoAnimalsArtPrintPoster.htm

zoo

Page 57: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

bundles v2.0bundles v2.1bundles v2.2bundles v2.3bundles v2.4server

compatibility

Page 58: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

APIcompatibility

Page 59: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

develop deploy test releasenew frontend version

new backend versionlocal staging production

Page 60: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

release = update default manifestfor all the users

Page 61: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

server firstserver is always backward compatible

easier to maintain compatibility on server with API versioning

Page 62: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

zoo = not an engineering issuebut administrative one

Page 63: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

awesome

Page 64: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

really awesome

Page 65: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

https://github.com/astrails/rails_react_webpackthanks to [email protected] aka @mihap

Page 66: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

http://astrails.com/blogslides will be available

Page 67: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion

thanks!

Boris Nadion http://astrails.com [email protected]

@borisnadion