building and deploying react applications€¦ · building and deploying react applications boris...
TRANSCRIPT
![Page 4: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/4.jpg)
2005
![Page 5: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/5.jpg)
awesome web and mobile apps
![Page 6: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/6.jpg)
building & deploying
![Page 7: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/7.jpg)
building & deploying
![Page 8: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/8.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/9.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/10.jpg)
customizelike adding css preprocessors
![Page 11: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/11.jpg)
yarn eject / npm eject
![Page 12: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/12.jpg)
yarn eject / npm eject
![Page 13: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/13.jpg)
not trivial
![Page 14: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/14.jpg)
start from scratch
![Page 15: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/15.jpg)
setup internals
![Page 16: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/16.jpg)
![Page 17: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/17.jpg)
environments✓ development
✓ production
x test
![Page 18: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/18.jpg)
package.json
![Page 19: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/19.jpg)
"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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/20.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/21.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/22.jpg)
“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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/23.jpg)
![Page 24: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/24.jpg)
webpack config
![Page 26: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/26.jpg)
![Page 27: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/27.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/28.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/29.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/30.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/31.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/32.jpg)
//… 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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/33.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/34.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/35.jpg)
prod buildyarn build
![Page 36: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/36.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/37.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/38.jpg)
// 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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/39.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/40.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/41.jpg)
<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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/42.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/43.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/44.jpg)
awesome
![Page 45: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/45.jpg)
almost awesome
![Page 46: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/46.jpg)
<%= 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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/47.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/48.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/49.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/50.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/51.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/52.jpg)
separate server and client deployments
![Page 53: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/53.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/54.jpg)
awesome
![Page 55: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/55.jpg)
almost awesome
![Page 56: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/56.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/57.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/58.jpg)
APIcompatibility
![Page 59: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/59.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/60.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/61.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/62.jpg)
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](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/63.jpg)
awesome
![Page 64: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/64.jpg)
really awesome
![Page 65: Building and Deploying React Applications€¦ · Building and Deploying React Applications Boris Nadion boris@astrails.com @borisnadion](https://reader036.vdocument.in/reader036/viewer/2022062919/5edfd1fdad6a402d666b1f7e/html5/thumbnails/65.jpg)
https://github.com/astrails/rails_react_webpackthanks to [email protected] aka @mihap