ReactJS and Webpack for Rails

Similar documents
Webpack. What is Webpack? APPENDIX A. n n n

Web Development for Dinosaurs An Introduction to Modern Web Development

Getting Started with ReactJS

Frontend UI Training. Whats App :

RequireJS Javascript Modules for the Browser. By Ben Keith Quoin, Inc.

"Charting the Course... MOC A: Developing with the SharePoint Framework. Course Summary

55249: Developing with the SharePoint Framework Duration: 05 days

Advanced React JS + Redux Development

Webpack 2 The last bundler you would need in Vijay Dharap, Principal Architect, Infosys

React & Redux in Hulu. (Morgan Cheng)

Brunch Documentation. Release Brunch team

Welcome. Quick Introductions

About the Tutorial. Audience. Prerequisites. Copyright & Disclaimer. ReactJS

Full Stack boot camp

Building an OpenLayers 3 map viewer with React

Arjen de Blok. Senior Technical Consultant bij ICT Groep ( sinds 1995 Programmeren sinds 1990 Technologiën. Links

Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling. Philip Hornig (Publicis Pixelpark), Michael Sunaric (Netcentric)

React.js. a crash course. Jake Zimmerman January 29th, 2016

Chapter 1 - Development Setup of Angular

Lecture 8. ReactJS 1 / 24

Future Web App Technologies

LeanJS Documentation. Release Romain Dorgueil

WEBASSETS & DUKPY FREE YOURSELF FROM NODEJS. Alessandro amol

React(.js) the Domino Way High-Performance Client for Domino. Knut Herrmann

Index. Elad Elrom 2016 E. Elrom, Pro MEAN Stack Development, DOI /

MOdern Java(Script) Server Stack

Angular 2 Programming

Modern frontend workflows in Liferay Portal and Liferay DXP. Iván Zaera Avellon, Liferay Chema Balsas, Liferay Pier Paolo Ramon, SMC

Templates and Databinding. SWE 432, Fall 2017 Design and Implementation of Software for the Web

Say No to Complexity!

React + React Native. Based on material by Danilo Filgueira

webpack bundle inner structure and optimization Alexey Ivanov, Evil Martians

Say No to Complexity!

Introduction to Using NPM scripts as a Build Tool. 1. 1

Node.js. Node.js Overview. CS144: Web Applications

Introduction to Sencha Ext JS

Writing Modular Stylesheets With CSS Modules.

welcome to BOILERCAMP HOW TO WEB DEV

Extending Blue Ocean Keith Zantow

Evolution of the "Web

Ten interesting features of Google s Angular Project

npm install [<name> [<name>...]] [--save --save-dev --save-optional]

Web UI. Survey of Front End Technologies. Web Challenges and Constraints. Desktop and mobile devices. Highly variable runtime environment

Comprehensive AngularJS Programming (5 Days)

P a g e 1. Danish Technological Institute. Scripting and Web Languages Online Course k Scripting and Web Languages

Vue.js Developer friendly, Fast and Versatile

MEAN Stack. 1. Introduction. 2. Foundation a. The Node.js framework b. Installing Node.js c. Using Node.js to execute scripts

Before I forget... I'm Ari Lerner

Advance Mobile& Web Application development using Angular and Native Script

APACHE SLING & FRIENDS TECH MEETUP SEPTEMBER Integrating a Modern Frontend Setup with AEM Natalia Venditto, Netcentric

Introduction to the SharePoint Framework Bob German Principal Architect - BlueMetal. An Insight company

django-baton Documentation

High Performance Single Page Application with Vue.js

Cisco Spark Widgets Technical drill down

gettext.js Documentation

DECOUPLING PATTERNS, SERVICES AND CREATING AN ENTERPRISE LEVEL EDITORIAL EXPERIENCE

Angular 2 and TypeScript Web Application Development

React Loadable: Code Splitting with Server Side Rendering

Agile Web Development with Rails 5.1

Full Stack Developer with Java

DrupalCon Barcelona Preston So September 22, 2015

Catbook Workshop: Intro to NodeJS. Monde Duinkharjav

Deep Dive on How ArcGIS API for JavaScript Widgets Were Built

Client Side MVC with Backbone & Rails. Tom

From Browser Wars to Framework Wars How to survive the next generation of Web development battles. Dr. Michael Evans Codernetic Ltd untangled.

20480C: Programming in HTML5 with JavaScript and CSS3. Course Code: 20480C; Duration: 5 days; Instructor-led. JavaScript code.

Episode 298. Getting Started With Spree

Lab 1 - Introduction to Angular

Stencil: The Time for Vanilla Web Components has Arrived

Data Visualization on the Web with D3

CS193X: Web Programming Fundamentals

Developing ASP.NET MVC Web Applications (486)

ES6 Modules...& Polymer

Modular JavaScript. JC Franco. Blake Stearman

AngularJS Fundamentals

McLab tools on the web. Deepanjan Roy Supervisor: Prof. Laurie Hendren

PHP WITH ANGULAR CURRICULUM. What you will Be Able to Achieve During This Course

Overview of BC Learning Network SMS2 Introduction

Modern SharePoint and Office 365 Development

J, K, L. Node.js require() method, 403 package.json, 401 streams functionality, 401 task() method, 401 use strict statement, 403

JavaScript Frameworks

MY STORY WITH WEBPACK

django-baton Documentation

Makbul Khan. Nikhil Sukul

Hi I m Jamund and I love ES6 and I m giving this talk.

Enterprise Web Development

pyramid_assetmutator Documentation

JavaScript: the language of browser interactions. Claudia Hauff TI1506: Web and Database Technology

Manual Html A Href Onclick Submit Form

Front End. Presentation Layer. UI (User Interface) User <==> Data access layer

International Research Journal of Engineering and Technology (IRJET) e-issn: Volume: 05 Issue: 05 May p-issn:

August, HPE Propel Microservices & Jumpstart

Tools. SWE 432, Fall Design and Implementation of Software for the Web

6 th October 2018 Milan

International Research Journal of Engineering and Technology (IRJET) e-issn: Volume: 05 Issue: 06 June p-issn:

A JavaScript Framework for Presentations and Animations on Computer Science

JavaScript and MVC Frameworks FRONT-END ENGINEERING

roots Documentation Release jeff escalante

What is Node.js? Tim Davis Director, The Turtle Partnership Ltd

widgetjs Documentation

Transcription:

Modern Web Conf 2015 ReactJS and Webpack for Rails Tse-Ching Ho 2015-05-16

@tsechingho 何澤清 紅寶 石商 人 Rubiest 鐵道 工 人 Rails worker 黃碼科技創辦 人 Goldenio founder 生物資訊 Bioinformatics 資料視覺化 Infographics

Javascript http://www.animen.com.tw/filesupload/bns/131022_17_001.jpg

http://i0.sinaimg.cn/gm/2014/0707/u4511p115dt20140707184058.jpg 一入某圈深似海 suffered by it s chaos

Javascript after 5 years fighting

Javascript Modules Why modules? Definition & Dependency References Synchronous/Asynchronous Module Definition Nested dependencies CommonJS vs. RequireJS ECMAScript 6

Factory function module // my_module.js var mymodule = (function (my, $) { my.publicmethod = function () { $('.events').fadein(); }; return my; }(mymodule {}, jquery)); window.mymodule = mymodule; // app.js mymodule.publicmethod();

CommonJS module // my_module.js var $ = require( jquery'); exports.mymodule = function () { var my = {}; my.publicmethod = function () { $('.events').fadein(); }; return my; }; // app.js var mymodule = require( my_module'); mymodule.publicmethod();

RequireJS module // my_module.js define(['jquery'], function ($) { var my = {}; my.publicmethod = function () { $('.events').fadein(); }; return my; }); // app.js var mymodule = require('my_module'); mymodule.publicmethod();

ECMAScript 6 module // my_module.js module mymodule { import $ from 'jquery'; export var my = { publicmethod: function () { $('.events').fadein(); } } } // app.js import mymodule from my_module'; mymodule.publicmethod();

NodeJS Ecosystem In My Opinion Feature: Past: npm bower package.json grunt, gulp webpack browserify

Webpack Webpack Dev Server Hot Module Replacement (HMR) webpack.config.js & CLI Multiple entry points Loaders Plugins

Module style of webpack require('../component.less'); var Foo = require('app/shared/foo'); var template = require('raw!./tmpl.mustache'); module.exports = Foo.extend({ template: template,... });

webpack.config.js // client/webpack.rails.config.js const path = require('path'); module.exports = { context: dirname, entry: ['./assets/javascripts/app', './scripts/rails_only'], output = { filename: 'client-bundle.js', // '[name].bundle.js' path: '../app/assets/javascripts/generated' }, externals: { jquery: 'var jquery' }, resolve: { root: [path.join( dirname, 'scripts'), path.join( dirname, 'assets/javascripts'), path.join( dirname, 'assets/stylesheets')], extensions: ['', '.js', '.jsx', '.coffee', '.scss', '.css', '.webpack.js', '.web.js', config.js'] }, module: { loaders: [ { test: /\.coffee$/, exclude: /node_modules/, loader: 'coffee-loader' }, { test: /\.jsx$/, exclude: /node_modules/, loader: babel-loader' }, { test: /\.js$/, exclude: /node_modules/, loader: babel-loader' }, { test: require.resolve('jquery'), loader: expose?jquery' }, { test: require.resolve('jquery'), loader: expose?$' } ] } }; http://webpack.github.io/docs/configuration.html

Entry point script // App.jsx import $ from 'jquery'; import React from 'react'; import CommentBox from './components/commentbox'; $(function onload() { function render() { if ($('#content').length > 0) { React.render( <div> <CommentBox url='comments.json' pollinterval={5000}/> <div classname='container'> <a href='http://modernweb.tw/'> <h3 classname='open-sans-light'> <div classname='logo'/> Modern Web conf 2015 </h3> </a> </div> </div>, document.getelementbyid('content') ); } } render(); $(document).on('page:change', () => { render(); }); });

Transpiler CoffeeScript React JSX transpiler ES6 transpiler Sass transpiler

ReactJS most powerful javascript framework?

Why react? view components virtual dom engine data api to view philosophy

CoffeeScript Style // components/cart_modal.js.coffee {div, h3, a} = React.DOM CartModal = React.createClass proptypes: lang: React.PropTypes.string.isRequired mixins: [ window.cartlifecycle window.cartstorage window.cartmanipulation ] render: -> React.DOM.div classname: 'cart' React.DOM.h3 null, @state.i18n.cart_title React.DOM.div classname: 'cart-body' window.cartform url: '/cart' redirect: true items: @state.items total: @state.total actions: true lang: @props.lang React.DOM.a classname: 'close-reveal-modal' 'x' window.cartmodal = CartModal

HTML layout // index.html <!DOCTYPE html> <html> <head> <title>hello React</title> <script src="express-bundle.js"></script> </head> <body> <div id="content"></div> </body> </html>

Entry Point // App.jsx import $ from 'jquery'; import React from 'react'; import CommentBox from './components/commentbox'; $(function onload() { function render() { if ($('#content').length > 0) { React.render( <div> <CommentBox url='comments.json' pollinterval={5000}/> <div classname='container'> <a href='http://modernweb.tw/'> <h3 classname='open-sans-light'> <div classname='logo'/> Modern Web conf 2015 </h3> </a> </div> </div>, document.getelementbyid('content') ); } } render(); $(document).on('page:change', () => { render(); }); // turblolinks });

Components // components/commentbox.jsx import React from 'react'; import CommentForm from './CommentForm'; import CommentList from './CommentList'; import CommentStore from '../stores/commentstore'; import FormStore from '../stores/formstore'; import CommentActions from '../actions/commentactions'; const CommentBox = React.createClass({ displayname: 'CommentBox', proptypes: { url: React.PropTypes.string.isRequired, pollinterval: React.PropTypes.number.isRequired }, getstorestate() { return { comments: CommentStore.getState(), form: FormStore.getState() }; }, getinitialstate() { return this.getstorestate(); },... }); export default CommentBox;

Components const CommentBox = React.createClass({... componentdidmount() { CommentStore.listen(this.onChange); FormStore.listen(this.onChange); CommentActions.fetchComments(this.props.url, true); setinterval(commentactions.fetchcomments, this.props.pollinterval, this.props.url, false); }, componentwillunmount() { CommentStore.unlisten(this.onChange); FormStore.unlisten(this.onChange); }, onchange() { this.setstate(this.getstorestate()); }, render() { return ( <div classname="commentbox container"> <h1>comments { this.state.form.ajaxsending? 'SENDING AJAX REQUEST!' : '' }</h1> <CommentForm formdata={this.state.form.comment} url={this.props.url} ajaxsending={this.state.form.ajaxsending} /> <CommentList comments={this.state.comments.comments} /> </div> ); } });

Life cycle of view component http://facebook.github.io/react/docs/component-specs.html

Flux https://github.com/facebook/flux

Flux Bridge views components web apis Implementations ALT.js client/ assets/ javascripts/ actions/ components/ common/ session/ stories/ dispatcher/ stores/ utils/ app.jsx routes.jsx

Stores // stores/commentstore.js import alt from '../FluxAlt'; import React from 'react/addons'; import CommentActions from '../actions/commentactions'; class CommentStore { constructor() { this.comments = []; this.errormessage = null; this.bindlisteners({ handlefetchcomments: CommentActions.FETCH_COMMENTS, handleupdatecomments: CommentActions.UPDATE_COMMENTS, handleupdatecommentserror: CommentActions.UPDATE_COMMENTS_ERROR, handleaddcomment: CommentActions.ADD_COMMENT }); } handlefetchcomments() { return false; } }... export default alt.createstore(commentstore, 'CommentStore');

Actions // FluxAlt.js import Alt from 'alt'; const alt = new Alt(); export default alt; // actions/commentactions.js import alt from '../FluxAlt'; import CommentsManager from '../utils/commentsmanager'; class CommentActions { fetchcomments(url, displayspinner) { this.dispatch(displayspinner); CommentsManager.fetchComments(url).then((comments) => this.actions.updatecomments(comments), (errormessage) => this.actions.updatecommentserror(errormessage)); }... } export default alt.createactions(commentactions); // utils/commentsmanager.js import $ from 'jquery'; const CommentsManager = { fetchcomments(url) { return $.ajax({ url: url, datatype: json' }); },... }; export default CommentsManager;

Rails 10 years old NOT old fashion!

Assets Management download from source into vendor/assets use a ruby gem including a rails engine use bower and configure rails use the bower-rails gem use rails-assets.org http://www.codefellows.org/blog/5-ways-to-manage-front-end-assets-in-rails

Rails Asset Pipeline Module Definition Factory function module CommonJS module RequireJS module Transpiler: coffeescript package bundler: sprockets

React on Rails

The simple way sprockets react-rails require.js / browserify-rails coffee-react (cjsx)

3 common ways Use React inside of Rails with react-rails React/Flux front end app within Rails webpack or browserify Separated Rails API and React/Flux front end app http://www.openmindedinnovations.com/blogs/3-ways-to-integrate-ruby-on-rails-react-flux

1st Class JavaScript Citizen NPM Package Manager Gemified JavaScript ES6 (Harmony) CoffeeScript Using Modules Globals on window React.js React-rails JS in server side

Hybrid is Good ES6 + Webpack + React + Rails

http://www.railsonmaui.com/blog/2014/10/02/integrating-webpack-and-the-es6-transpiler-into-an-existing-rails-project/ Package manager win - win

http://www.railsonmaui.com/blog/2014/10/02/integrating-webpack-and-the-es6-transpiler-into-an-existing-rails-project/ Assets bundle frontend - backend

Webpack in Rails app/ assets/ images/ javascripts/ generated/ client-bundle.js application.js stylesheets/ application.sass config/ webpack/ development.config.js production.config.js client/ assets/ images/ javascripts/ stylesheets/ node_modules/ scripts/ rails_only.jsx webpack_only.jsx index.html npm-shrinkwrap.json package.json server.js webpack.hot.config.js webpack.rails.config.js.gitignore.buildpacks package.json Procfile Procfile.dev

Client Side Development foreman start as rails@3000, webpack-dev@4000 adjust client/server.js for json api of webpack modify jsx and sass files under client/assets save files and watch realtime replacement @4000 create json api of rails and verify @3000 deploy with Sprockets

Sprockets long lives Hybrid is good webpack for modularity sprockets for integration (replaced by webpack?) Assets caching/fingerprinting is easy for non-js views helpers are still helpful: asset_path, javascript_include_tag jquery_ujs is still powerful assets:webpack task works well for deploy

Bad ways for Sprockets only app/views/layouts/application.html.slim the layout applies only compiled application.js file the compiled application.js bundles all files under app/assets/javascripts/**/**.js.coffee dependencies describe in every files javascript_include_tag would be used in each views for vendor libraries only

Good ways for Sprockets many app/views/layouts/xxx.html.slim each layout applies a compiled xxx.js file each compiled xxx.js file bundles folders under app/assets/javascripts/xxx/**/**.js.coffee dependencies describe in xxx.js file javascript_include_tag would be used in each views for home brewed bundles

Summary of React on Rails use require.js for legacy javascript codes use browserify-rails for legacy javascript codes use react-rails for dynamic components of views use ES6, Webpack and ReactJS for next feature

http://i0.sinaimg.cn/gm/2014/0707/u4511p115dt20140707184058.jpg 一入某圈深似海 suffered by it s chaos

References http://addyosmani.com/writing-modular-js/ https://github.com/justin808/react-webpack-rails-tutorial http://clarkdave.net/2015/01/how-to-use-webpack-with-rails/ http://www.openmindedinnovations.com/blogs/3-ways-tointegrate-ruby-on-rails-react-flux http://www.railsonmaui.com/blog/2014/10/02/integratingwebpack-and-the-es6-transpiler-into-an-existing-rails-project/ http://fancypixel.github.io/blog/2015/01/28/react-plus-fluxbacked-by-rails-api/