├── CNAME ├── apple-touch-icon.png ├── favicon.ico ├── images └── me.jpeg ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon-96x96.png ├── favicon-160x160.png ├── favicon-192x192.png ├── img ├── ModernReact.jpg ├── BuildingInteractive-001.png ├── BuildingInteractive-002.png ├── BuildingInteractive-003.png ├── BuildingInteractive-004.png ├── webpack-production │ ├── after.png │ └── before.png ├── playing-with-react-and-d3 │ ├── plot_points.png │ ├── basic_render.png │ └── complete_chart.png └── 10x-react-performance │ ├── performance-benchmark-1.png │ └── performance-benchmark-2.png ├── apple-touch-icon-114x114.png ├── apple-touch-icon-120x120.png ├── apple-touch-icon-144x144.png ├── apple-touch-icon-152x152.png ├── apple-touch-icon-180x180.png ├── apple-touch-icon-57x57.png ├── apple-touch-icon-60x60.png ├── apple-touch-icon-72x72.png ├── apple-touch-icon-76x76.png ├── _includes ├── navigation.html ├── footer.html ├── post_footer.html ├── header.html ├── pagination.html ├── social_links.html ├── share_buttons.html └── head.html ├── README.md ├── .gitignore ├── css └── pixyll.scss ├── pages ├── about.md └── contact.md ├── _layouts ├── page.html ├── center.html ├── default.html └── post.html ├── _posts ├── 2014-10-20-about.md ├── 2015-08-15-automate-your-home.md ├── 2015-07-29-alt-instances.md ├── 2014-10-20-contact.md ├── 2014-12-29-thanks.md ├── 2015-03-11-i-hear-you-want-a-react-europe-ticket.md ├── 2014-11-28-react-conf-ticket-giveaway.md ├── 2015-01-02-react-conf-giveaway-winner.md ├── 2014-10-13-what-is-this.md ├── 2015-05-24-es6-gotchas.md ├── 2015-08-07-roundup-august-7.md ├── 2017-03-06-the-diverse-react-navigation-ecosystem.md ├── 2014-10-20-tweets-week-in-reactjs-october-20th.md ├── 2016-01-03-NgRepeat-Equivalent-in-React.md ├── 2016-03-14-redux-middleware.md ├── 2014-10-20-this-week-in-react-october-17th.md ├── 2017-03-07-component-kits-for-react-native.md ├── 2014-10-28-twir-a-conference-is-coming.md ├── 2014-11-04-this-week-in-tweets.md ├── 2015-09-19-testing-the-easy-way.md ├── 2015-01-31-react-conf-recap.md ├── 2016-01-28-react-and-ag-grid.md ├── 2015-01-01-isomorphic-javascript-with-react-node.md ├── 2015-07-29-modals-in-react.md ├── 2017-03-28-proxies-with-redux-types.md ├── 2015-11-30-structuring-react-projects.md ├── 2016-04-07-how-to-make-your-react-apps-10x-faster.md ├── 2016-09-28-routing-in-react-native-with-jake-murzy.md ├── 2014-12-27-react-style-guide-patterns-i-like.md ├── 2016-01-15-bring-your-animations-to-life-with-physics.markdown ├── 2014-11-06-the-state-of-flux.md ├── 2015-08-06-composing-components.md ├── 2015-12-01-building-a-react-based-application.md └── 2016-03-13-webpack-in-production.md ├── 404.md ├── index.html ├── feed.xml ├── LICENSE.txt ├── _config.yml └── _sass ├── _solarized-dark.scss ├── _solarized-light.scss └── _main.scss /CNAME: -------------------------------------------------------------------------------- 1 | reactjsnews.com -------------------------------------------------------------------------------- /apple-touch-icon.png: -------------------------------------------------------------------------------- 1 | apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/favicon.ico -------------------------------------------------------------------------------- /images/me.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/images/me.jpeg -------------------------------------------------------------------------------- /favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/favicon-16x16.png -------------------------------------------------------------------------------- /favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/favicon-32x32.png -------------------------------------------------------------------------------- /favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/favicon-96x96.png -------------------------------------------------------------------------------- /favicon-160x160.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/favicon-160x160.png -------------------------------------------------------------------------------- /favicon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/favicon-192x192.png -------------------------------------------------------------------------------- /img/ModernReact.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/img/ModernReact.jpg -------------------------------------------------------------------------------- /apple-touch-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/apple-touch-icon-114x114.png -------------------------------------------------------------------------------- /apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /apple-touch-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/apple-touch-icon-144x144.png -------------------------------------------------------------------------------- /apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /img/BuildingInteractive-001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/img/BuildingInteractive-001.png -------------------------------------------------------------------------------- /img/BuildingInteractive-002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/img/BuildingInteractive-002.png -------------------------------------------------------------------------------- /img/BuildingInteractive-003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/img/BuildingInteractive-003.png -------------------------------------------------------------------------------- /img/BuildingInteractive-004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/img/BuildingInteractive-004.png -------------------------------------------------------------------------------- /img/webpack-production/after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/img/webpack-production/after.png -------------------------------------------------------------------------------- /img/webpack-production/before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/img/webpack-production/before.png -------------------------------------------------------------------------------- /_includes/navigation.html: -------------------------------------------------------------------------------- 1 | About 2 | Contact 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ReactJSNews 2 | 3 | Open for contributions! Create a PR with a link to your blog post, or include the text in the PR itself. 4 | -------------------------------------------------------------------------------- /img/playing-with-react-and-d3/plot_points.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/img/playing-with-react-and-d3/plot_points.png -------------------------------------------------------------------------------- /img/playing-with-react-and-d3/basic_render.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/img/playing-with-react-and-d3/basic_render.png -------------------------------------------------------------------------------- /img/playing-with-react-and-d3/complete_chart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/img/playing-with-react-and-d3/complete_chart.png -------------------------------------------------------------------------------- /img/10x-react-performance/performance-benchmark-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/img/10x-react-performance/performance-benchmark-1.png -------------------------------------------------------------------------------- /img/10x-react-performance/performance-benchmark-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Legitcode/ReactJSNews/HEAD/img/10x-react-performance/performance-benchmark-2.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore the config file that's used for gh-pages. 2 | _config.gh-pages.yml 3 | _site/ 4 | .sass-cache/ 5 | node_modules/ 6 | .DS_Store 7 | Gemfile.lock 8 | npm-debug.log 9 | -------------------------------------------------------------------------------- /css/pixyll.scss: -------------------------------------------------------------------------------- 1 | --- 2 | # The scss file which include files from _sass/ 3 | --- 4 | 5 | @charset "utf-8"; 6 | 7 | @import "basscss"; 8 | @import "main"; 9 | @import "solarized-dark"; 10 | -------------------------------------------------------------------------------- /pages/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: About 4 | permalink: /about/ 5 | --- 6 | 7 | ReactJSNews is a community driven site. Anyone is welcome to contribute by sending a pull request [on github](https://github.com/Legitcode/ReactJSNews/). -------------------------------------------------------------------------------- /pages/contact.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Contact 4 | permalink: /contact/ 5 | --- 6 | 7 | ReactJSNews is a community driven site. Anyone is welcome to contribute by sending a pull request [on github](https://github.com/Legitcode/ReactJSNews/). 8 | -------------------------------------------------------------------------------- /_layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 |
13 | {% if post.summary %} 14 | {{ post.summary }} 15 | {% else %} 16 | {{ post.excerpt }} 17 | {% endif %} 18 |
19 | Read More 20 | |
22 | |
23 |
|
29 | |
30 |
|
36 | |
37 |
Now with nested routes and http API data:
http://t.co/l5ndTOCg20
The App:
https://t.co/P6g6nBz0uV
Go ahead, disable JavaScript :)
— Ryan Florence (@ryanflorence) October 14, 2014
41 | @ReactJSNews http://t.co/TVsw27rjJC , http://t.co/JbWQqi1m58. With React (react-bootstrap, traceur, webpack) it was really easy to build
— koorchik (@koorchik) November 4, 2014
19 |
20 | @ReactJSNews @eiriklv's http://t.co/OzUa3L92z7 is an amazing #reactjs site. Infinite scrolling, masonry, fast. Blog- http://t.co/U4dsWb1HXv
— Jeff Winkler (@winkler1) November 4, 2014
21 |
22 | @ReactJSNews an admin dashboard for my site with React and Chartjs http://t.co/GKo0yBL4DQ
— Yongzhi Huang (@whyzhi) November 4, 2014
23 |
24 | @reactjs @Vjeux @ReactJSNews Understanding #Reactjs and reimplementing it from scratch https://t.co/VbO2XNJVYj
— Giulio Canti (@GiulioCanti) October 29, 2014
25 |
26 | Why we should stop using Grunt & Gulp http://t.co/imaz0U6OCi
— Jorge Cuadra (@Cuadraman) November 4, 2014
27 |
28 | marty 0.0.0 https://t.co/5KmdaXEx2n A React.js/Flux Framework
— npm_tweets (@npm_tweets) November 4, 2014
29 |
30 | The lack of React.js swag is painful.
— Trek Glowacki (@trek) November 4, 2014
31 |
32 | Highlights of the Secret Santa page: @reactjs, react-router, and nodeject DI. Fun project to work on. Architecture thanks to @jo_asakura.
— Brian Holt (@holtbt) November 3, 2014
33 |
34 | immutable-js has now its first official release and a website :) http://t.co/CEyi89ognu
— React (@reactjs) October 31, 2014
35 |
36 | @fkadev This is how i've been using it with React if you are interested https://t.co/dsqXQahuFv
— Vjeux (@Vjeux) October 30, 2014
37 |
38 | Understanding React and reimplementing it from scratch Part 1: Views
https://t.co/tToEt31yvt
#reactjs
— React JS France (@ReactJSFrance) October 29, 2014
39 |
40 | #reactjs subreddit http://t.co/wAEuwaUATv
— Elijah Luigi Mañor (@elijahmanor) October 28, 2014
41 |
--------------------------------------------------------------------------------
/_posts/2015-09-19-testing-the-easy-way.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: post
3 | title: "Testing Components, The Easy Way"
4 | excerpt_separator:
5 | author: Zach Silveira
6 | date: 2015-09-19 21:35
7 | published: true
8 | categories: react, testing
9 | ---
10 |
11 | You may have seen Darin's post on [testing in React](http://reactjsnews.com/testing-in-react/) last month. We work together at the same company. In the past couple of weeks I've realized that I really *hate* how annoying it is to setup and write tests for components.
12 |
13 |
14 |
15 | You may have seen Darin's post on [testing in React](http://reactjsnews.com/testing-in-react/) last month. We work together at the same company. In the past couple of weeks I've realized that I really *hate* how annoying it is to setup and write tests for components.
16 |
17 | ##How We Used To Do Tests
18 |
19 | With every new project we start, we have to include jsdom and set that up in a setup.js file that will be ran before each of our tests. If you take a look at [his post](http://reactjsnews.com/testing-in-react/), you'll see that process very clearly. Not only were we including this file in every project, our tests were not easy to follow. Take a look:
20 |
21 | ```js
22 | it('should generate a login form', () => {
23 | loginForm = TestUtils.renderIntoDocument(React is now iOSmorphic too... #reactnative
— Jeff Winkler (@winkler1) January 28, 2015
21 |
22 | If you don't get it, you really shouldn't be using React. On a more serious note, the coolest points about RN is live reloading. No waiting for it to compile your app after making a code change. The project is still in its infancy, there isn't really a complete routing solution, which is understandable considering it's not even public yet. The good news is that the [react-router](https://github.com/rackt/react-router) team has verbally committed to making it compatible with RN.
23 |
24 | If you're curious about what these React Native components look like, I posted a picture from the conference:
25 |
26 | Native components. pic.twitter.com/X8BtTEuWk6
— ReactJS News (@ReactJSNews) January 29, 2015
27 | One of the top features here is the fact that [@Vjeux](http://twitter.com/vjeux) brought over full [flexbox](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes) compatibility into React Native. So you can style things the way you're used to doing on the web.
28 |
29 | Everytime I remember another awesome feature that RN has, I keep wanting to say that it's the best feature, they're all just so awesome. The next thing it can do is use any npm module you're already using. It'll work out of the box!
30 |
31 | If you were curious about how good the gestures are in a React Native app, Pete Hunt sums it up pretty well.
32 | btw, it's really good: @jordwalke (react native guy) often uses a slow-mo camera to ensure #reactnative's touch gestures are solid
— Pete Hunt (@floydophone) January 29, 2015
33 | Another good tweet from an iOS developer confirms that RN is really good.
34 | People asked why I like React's model over UIKit's: it does a better job of promoting isolation and confining effects, while being simpler.
— Andy Matuschak (@andy_matuschak) January 29, 2015
35 |
36 | You can see a deep dive into RN [on youtube](https://www.youtube.com/watch?v=7rDsRXj9-cU).
37 |
38 | ##Relay & GraphQL
39 |
40 | Relay was mentioned a little, but after talking to some members on the team, I found out it'll be months before it's actually released. This is a shame because it solves the missing piece with Flux. It is a full framework that uses React and GraphQL. GraphQL, is a new way to fetch data from your backend and is meant to be a replacement for REST. What's really nice about it is that inside of your components you define the data you're checking. Not that much is known other than the fact that you can delay certain data from loading in your app if you need to. Facebook loads posts and then after that is finished, in a non-blocking way of course, then comments are fetched. You'll also be able to slowly migrate flux apps over to Relay. I'm very interested in seeing what this framework will have to offer.
41 |
42 | ##What's Next
43 | You can see all of the conference talks [on youtube](https://www.youtube.com/playlist?list=PLb0IAmt7-GS1cbw4qonlQztYV1TAW0sCr). I hope you liked my recap of the conference.
44 |
45 | After asking people on Twitter if there's any React jobs available I got an overwhelming response. I'm currently working on a job board built using React that'll hopefully be up soon. For now I'll continue to send out jobs and other secret stuff in the newsletter. You can subscribe to that in the sidebar!
46 |
47 |
48 |
--------------------------------------------------------------------------------
/_posts/2016-01-28-react-and-ag-grid.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: post
3 | title: "React and ag-Grid - the Perfect Match"
4 | excerpt_separator:
5 | author: Niall Crosby
6 | author_url: https://www.ag-grid.com/
7 | date: 2016-01-28 00:05
8 | published: true
9 | categories: react
10 | ---
11 |
12 |
13 | ### What is ag-Grid
14 |
15 | ag-Grid is an enterprise JavaScript data grid with zero library dependencies, including no dependency for it's rendering. You can build an application using just JavaScript and ag-Grid alone. The 'ag' stands for framework AGnostic.
16 |
17 |
18 |
19 | ### And React?
20 |
21 | Now ag-Grid is providing an optional React component and React rendering. ag-Grd is fully in bed with React and treats React as a first class component - meaning if you are using React, ag-Grid is NOT using any other framework to get the job done.
22 |
23 | React Components follow standard DOM interaction patterns using properties, events (callbacks) and an optional API for interacting with the components. React also uses immutability to assist state management. ag-Grid uses the same principles. ag-Grid's core interface maps directly onto what is required by React making ag-Grid and React match perfectly.
24 |
25 | To demonstrate, lets break down the provided
26 | [example React and ag-Grid on Github](https://github.com/ceolter/ag-grid-react-example).
27 | (note: the example can be found running [here](https://www.ag-grid.com/best-react-grid/index.php))
28 |
29 | ~~~js
30 | render() {
31 | return (
32 | Etc.
80 |More Content. Anything goes here
155 | Check out this Pen!
34 |
35 | #### Using timed CSS animations
36 |
37 | A CSS transition can be added to the properties of an element with the CSS transition property. Per the [Mozilla docs for transition](https://developer.mozilla.org/en/docs/Web/CSS/transition), we can pass the duration we want the transition to take and a cubic bezier timing function. In this case I have set the duration to 0.5s and used the default timing function of ease.
38 |
39 | Check out this Pen!
40 |
41 |
42 | #### Cubic Bezier
43 |
44 | 
45 |
46 | A cubic bezier curve is a timing function that starts at position 0 and time 0 and ends at 1,1. It accepts four arguments (x1, y1, x2, y2), which are the two control points to determine the shape of the curve. As you can see above, the ease function accelerates at the start and then decelerates at the middle, causing the animation to 'ease' as it finishes. The ease function is just shorthand for cubic-bezier(0.25,0.1,0.25,1). If you want to prove this, re-run this example after changing line 18 to:
47 |
48 | ~~~js
49 | transition: '0.5s cubic-bezier(0.25, 0.1, 0.25, 1)'
50 | ~~~
51 |
52 | The [cubic bezier site by Lea Verou](http://cubic-bezier.com/) is a great resource for experimenting with different timing functions. Below I have compared a linear function against the ease function.
53 |
54 | 
55 |
56 | Chrome dev tools allow you to experiment with different curves and also control the speed of animations as seen below.
57 |
58 | 
59 |
60 | #### Why you should use spring physics in animations
61 |
62 | 
63 |
64 | As cubic bezier functions only give you two points of control, it doesn't give the developer enough control to model real life movement. However, by controlling the animation with Javascript, we have full control and can use Hooke's law which expresses how springs extends and contract. Spring animation is already very popular and can be used to provide lively animations in iOS core animation, and in Facebook's Pop and Rebound libraries.
65 |
66 | Look at the cubic bezier animations on the left taken from [framerjs](http://framerjs.com/learn/basics/animation/), compared with the spring animation on the right. The spring animation has a bounce effect - which is not possible with a cubic bezier function. You could acheive this animation with CSS by using key frames, but you would have to hard code the key frame values and duration of the animation.
67 |
68 | 
69 |
70 | React Motion implements a terse API for you to use spring animation which can be used on the web and with React Native. You have the option to specify the start value (in this case, 0) and the spring physics values you want to animate to. React Motion runs in a request animation frame. The Motion component will keep calling your function to render your animated component with a style object that has the calculated values for each frame. In the example below I have destructured the x property and rendered it in the component.
71 |
72 | Check out this Pen!
73 |
74 | ##### Continuous fluid interfaces
75 |
76 | In the excellent talk on the [state animation in React](https://www.youtube.com/watch?v=1tavDv5hXpo), Cheng Lou, the creator, highlighted a quote from a former UIKit engineer at Apple.
77 |
78 | Animation APIs parameterized by eg duration and curve are fundamentally opposed to continuous, fluid interactivity.
— Andy Matuschak (@andy_matuschak) February 14, 2015
79 |
80 | In the talk, Cheng used an example of animating an opening menu to illustrate this point - "For example, if you have a menu deploy animation that takes 500 milliseconds, and half-way the user clicks on something, and you toggle it back to its initial hidden state, why should this way back also be 500 milliseconds? And also, what should the curve be: ease-in, linear? It is not very clear".
81 |
82 | 
83 |
84 | The need for a fluid interface is what made me look into react-motion. We are currently building a calendar at [Fergus](http://fergusapp.com/) which requires the ability to respond to drag events and clicks moving the calendar in different directions and by different distances. When we prototyped this with CSS transitions, it was janky and felt slow.
85 |
86 | Compare how fluid the spring motion animation is against the CSS animations by clicking the 'Run animation' button multiple times in quick succession.
87 |
88 | Check out this Pen!
89 |
90 | #### Configuring React Motion
91 |
92 | The React Motion spring takes two arguments: stiffness and damping (which defaut to 120 and 17, respectively). Four [presets](https://github.com/chenglou/react-motion/blob/master/src/presets.js) are provided: noWobble, gentle, wobbly, and stiff. By adjusting the stiffness and damping below, you can watch how these factors change the animation.
93 |
94 | Check out this Pen!
95 |
96 | #### When to use CSS Animations
97 |
98 | As Cheng said in his talk, CSS animations are better for animations that you don't want to stop or adjust after they are triggered - such as Twitter's exploding heart animation. This is because CSS animations are more performant. React Motion does incur the cost of having your app re-rendered every animation frame which could be a problem if your application is not performant.
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/_posts/2014-11-06-the-state-of-flux.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: post
3 | title: "The State of Flux"
4 | excerpt_separator:
5 | author: David Chang
6 | date: 2014-11-06 16:29
7 | published: true
8 | categories: react
9 | ---
10 | Facebook announced Flux at F8 in April as an application paradigm to complement React. But Flux has been pretty nebulous, as there hasn’t been much code released. The examples in Facebook’s Flux repository gave a better idea of its overall composition, but there was still a ton of boilerplate involved, and that’s usually where a library comes along to bring some level of abstraction and convenience.
11 |
12 |
13 |
14 | Facebook announced Flux at F8 in April as an application paradigm to complement React. But Flux has been pretty nebulous, as there hasn’t been much code released. The examples in Facebook’s Flux repository gave a better idea of its overall composition, but there was still a ton of boilerplate involved, and that’s usually where a library comes along to bring some level of abstraction and convenience.
15 |
16 | Assuming a prior knowledge of Flux’s inner workings, here’s a comparison of the following Flux libraries that have been developed by the community:
17 |
18 | - Reflux @ReactJSNews "you should switch because you want to look cool and argue about mixins" :P
— Ryan Florence (@ryanflorence) August 2, 2015
20 |
21 | @ReactJSNews There aren't really any good arguments for using classes in React besides the fact that people who are used to OOP grok them.
— Michael Jackson (@mjackson) August 3, 2015
22 |
23 | There's also those of us who are more neutral on the subject:
24 |
25 | @mjackson @reactjsnews arguing ES6 class vs React.createClass is like constructor pttrn vs Factory pttrn. They BOTH are just classes.
— Naman Goel (@naman34) August 3, 2015
26 |
27 | @mjackson @ReactJSNews it's just a matter of taste. It has no real impact, which syntax you use while semantics stays the same
— Alexey Frolov (@__fro) August 3, 2015
28 |
29 | Here’s my take: In the large scheme of things, it doesn’t matter that much. For most of the cases out there, the difference between `React.createClass` and `class X extends React.component` is that of syntax. If you don’t use mixins or decorators often, just choose the syntax you like the best.
30 |
31 | But apart from that, there are some real reasons to choose one way over the other.
32 |
33 | There are some real features you lose by going with ES6 Classes (I’m not going to say ES2015, you can’t make me!) — namely mixins, autoBound functions and the oft-forgotten this.isMounted method. ES6 classes also means you now have a hard dependency on a tool like Babel. If you’ve not embraced JSX, and are currently writing ES5 code that doesn’t need transpilation, this might be a dealbreaker for you.
34 |
35 | But before we get into the pros and cons list, let say something that people tend to overlook. Using ES6 classes instead of React.createClass DOES NOT make your code any more or less Object oriented. It’s just a different syntax for defining classes folks, it has a fewer features, but essentially you’re moving from a factory pattern to a constructor pattern. So, if you like your code nice and functional, this should be a non-debate for you.
36 |
37 | On the flip side, using ES6 classes does make it easier to do inheritance. But please, don’t. Let me put it this way, if you’re going to use ES6 classes just so you can make deep inheritance chains, just stick to React.createClass and write some mixins.
38 |
39 | ## Reasons to use React.createClass
40 |
41 | ### "I like auto-binding functions"
42 |
43 | This is a valid argument, except you **can** autobind with ES2015 classes, (See the [React blog post](https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding))
44 |
45 | Using Babel stage: 0 (which I’m personally a huge fan of) you can write your classes like this:
46 |
47 | ~~~js
48 | class Counter extends React.Component {
49 | tick = () => {
50 | ...
51 | }
52 | ...
53 | }
54 |
55 | ~~~
56 |
57 | If you think stage: 0 is way too extreme, there are other options out there. You can, for example, use an [autobind decorator](https://github.com/andreypopp/autobind-decorator):
58 |
59 | But decorators are a stage: 0 feature, I hear you say. Yes, but you don’t need stage: 0:
60 |
61 | ~~~js
62 | class Counter extends React.Component {
63 | tick() {
64 | ...
65 | }
66 | render(){
67 | ...
68 | }
69 | ...
70 | }
71 |
72 | export default autobind(Counter)
73 | ~~~
74 |
75 | ### "I like mixins”
76 |
77 | This is pretty much the main reason people are sticking to React.createClass, and for good reason. There are large React code bases that rely on mixins. React-router, for example, gets a lot of power by using mixins.
78 | Again, you can use [React-mixin](https://www.npmjs.com/package/react-mixin), to use mixins with ES6 classes, but you may be getting annoyed by the decorators by now.
79 |
80 | ### Little things like this.isMounted
81 |
82 | You hardly ever need to use them, and when you do, they are easy to add. Personally I find no reason for using `this.isMounted` in your code.
83 |
84 | ## Reasons to switch to the ES6 syntax
85 |
86 | ### Autobinding?
87 | Maybe this is stockholme syndrome, but we’ve been dealing with context issues in Javascript so long, that it’s starting to feel right. The automatic autobinding that React.createClass handles for you can be confusing to beginners, and the implicit nature of the binding can be confusing even after months for some.
88 | ES6 classes make you explicitly bind your methods. Which makes everything clearer, and will help developers new to React grok what’s going on. With some of the latest Babel-supported ES6/7 features, manual binding isn't much of a problem.
89 |
90 | ### Move over Mixins, use Higher-Order-Components
91 | Go to any conversation about ES6 classes, and you’ll find someone telling you to use composition over inheritance. You may have seen this meme before:
92 |
93 | 
94 |
95 | The fact is that inheritance is a terrible way to code. It’s error-prone, clunky and hard to understand. It can lead to extremely brittle code, and forces you to write all your code the same way. Mixins are definitely a much better solution, but developers still tend to abuse them to do things that could simply be done with composition. Who said you can’t be functional with classes? As an added bonus, Higher-Order-Component will work with both kinds of classes, and will be forward compatible with pure functions.
96 |
97 | On the other hand, using decorator functions, you can do some very powerful things with ES6 classes, such as polyfill the oft-discussed polyfill API. This power should be used sparingly, but when you do need it, it’s nice to have.
98 |
99 | ### No Cruft
100 | Getting rid of features such as this.isMounted which is rarely used in practice helps React be lighter and more nimble. Over time this is also helping React be faster. I know we all love React, but we also want to keep winning the speed tests, don’t we.
101 |
102 | ### FlowTypes
103 | This is one is near and dear to my heart. For a very long time, I’ve pretty much ignored Typescript and Flow, but after losing a whole day to a typo in an event name, I started using flow in my code and I haven’t looked back. Flow lets you embrace it slowly on a file-by-file basis, and even though it may make you jump through hoops sometimes to work around errors, it will find a whole bunch of subtle errors that you didn’t even know existed.
104 |
105 | But what does this have anything to do with ES6 class syntax? Flowtype (and typescript) are much easier to use if you’re using ES6 classes.
106 |
107 | This is how you can annotate properties in an ES6 class:
108 |
109 | ~~~js
110 | Class X extends React.Component {
111 | someProp: string | number;
112 | state: SomeType;
113 | props: SomeType;
114 | ...
115 | }
116 | ~~~
117 |
118 | The same is a little more complicated with React.createClass
119 | ~~~js
120 | React.createClass({
121 | someProp: (0: string | number),
122 | ...
123 | })
124 | ~~~
125 |
126 | You can’t even define types for props and state with flow with React.createClass. Instead, flow depends on a huge amount of custom code to figure out the types for props by looking at propTypes. In practice, it never works that well. And type checking state is simply not even possible.
127 |
128 | ##Conclusion
129 |
130 | Neither of these options for creating your classes are going away anytime soon. I feel that things are headed towards the ES6 way of doing things but it will be a while until it's mainstream. If it ever becomes something everyone chooses over `createClass`, Javascript needs more than just syntactic sugar, it needs real classes. I choose to write my components the ES6 way mainly because I feel that it looks a little nicer, no commas after every function and the downsides to using this syntax doesn't bother me that much. We would love to hear feedback in the comments about what you think! Hopefully we'll discuss this on the next episode of the [React Podcast](http://reactpodcast.com).
131 |
--------------------------------------------------------------------------------
/_posts/2015-12-01-building-a-react-based-application.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: post
3 | title: "Building a React-based Application"
4 | excerpt_separator:
5 | author: Marc Scholten
6 | date: 2015-12-01 17:15
7 | published: true
8 | categories: react
9 | ---
10 |
11 | Building a frontend application is hard. Compared to building backend applications, you have way too much mutable state to manage and in the end your whole code base is so complex that nobody wants to touch anything.
12 |
13 | We already know how to build backend applications - generating html, sending it to the browser, repeat - without it ending in a nightmare of complexity, but building frontend stuff is very complicated. Backend is easy, frontend is hard. So, why don't we just build the frontend like the backend?
14 |
15 |
16 |
17 | Building a frontend application is hard. Compared to building backend applications, you have way too much mutable state to manage and in the end your whole code base is so complex that nobody wants to touch anything.
18 |
19 | We already know how to build backend applications - generating html, sending it to the browser, repeat - without it ending in a nightmare of complexity, but building frontend stuff is very complicated. Backend is easy, frontend is hard. So, why don't we just build the frontend like the backend?
20 |
21 | ## Building it like a backend application
22 |
23 | A good old web application usually consists of a router mapping the current url to a controller action which will render the whole page including the outer layout. The big picture looks like this:
24 |
25 | 
26 |
27 | By replicating this cycle in our frontend application we can - together with react - reach an easier to understand application design with less mutable parts.
28 |
29 | ## Implementing it
30 | When the user is navigating to a different view, we will just use links. When the user clicks a link an event handler will tell the router to render the new page (by using `window.history.pushState`). Our frontend application flow now looks like this:
31 |
32 | 
33 |
34 | This leads to a one-directional data flow which is easier to reason about than a bidirectional data flow which you can usually find in frontend applications.
35 |
36 | Let's take a look to some example code.
37 |
38 |
39 | ## The Application Component
40 |
41 | ```js
42 | // Application.jsx
43 | import Router from "./Router"
44 | import { routes as postRoutes } from "./PostView"
45 | import { routes as accountRoutes } from "./AccountView"
46 |
47 | class Application {
48 | render() {
49 | if (this.state.user) {
50 | return 102 | 103 | 104 | A couple people wanted a better explanation as to what's happening here. When I was first building my production webpack config, even after using all of these plugins: 105 | 106 | ```js 107 | new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js'), 108 | new webpack.optimize.OccurenceOrderPlugin(), 109 | new webpack.optimize.DedupePlugin(), 110 | new webpack.optimize.UglifyJsPlugin({ 111 | compress: { warnings: false }, 112 | comments: false, 113 | sourceMap: false, 114 | mangle: true, 115 | minimize: true 116 | }), 117 | 118 | ``` 119 | 120 | My bundle looked like this: 121 | 122 |  123 | 124 | That's pretty huge if you think about it. And I'm not talking about the amount of bundles. I'm talking about the file size. After searching everywhere for a solution to get the bundle size down further, I found webpack's [AggressiveMergingPlugin](https://webpack.github.io/docs/list-of-plugins.html#aggressivemergingplugin). This thing is a life saver. As you may have seen from the tweet, the output turns into this: 125 | 126 |  127 | 128 | Just having the main, vendor, and one other bundle brings the whole site under 1MB. I'm using the plugin to only merge files if the size reduction is more than 50%, which is the default. 129 | 130 | People talk about code splitting in webpack and think it's really amazing to load the JS for the page you're on and nothing more. It sounds great. The problem is that the file size is immensely bigger. If someone more familiar with webpack has a better idea as to why this is, I'd like a better explanation. It isn't feasable to keep the splits instead of merging them. This site is pretty large, with a lot of routes as you can tell from the screenshots. Codesplitting without merging would cause way more waiting on the client side every time you navigate to a new page. Even if the JS was heavily cached, the first time you hit these pages it will have to load a 300kb bundle for some of them. 131 | 132 | ##Caching 133 | 134 | That takes us to caching. We are about a month away from publicly launching this site, so we haven't setup the workflow for pushing updates through a cdn, but that will be the end result. For now, in my webpack config, my output object looks like this: 135 | 136 | ```js 137 | output: { 138 | path: __dirname + '/public/assets/js/[hash]/', 139 | filename: '[name].js', 140 | chunkFilename: '[id].js', 141 | publicPath: '/assets/js/[hash]/' 142 | }, 143 | ``` 144 | 145 | This is in the production config of course. This way I can cache the files and when I update the code, the hash will change and the browser won't be caching the old code. I pass in the hash as an env variable at runtime to that the server has the correct path to the assets folder. 146 | 147 | 148 | ##Problems 149 | 150 | There were a few big problems I came across while building out a server rendered app with dynamic routes. The first was page titles. How am I supposed to have the right title on the client and on the initial server render? Thankfully, Ryan has yet another solution. [react-title-component](https://github.com/ryanflorence/react-title-component) solves this perfectly. 151 | 152 | The next was, how do I hit an api, wait for the response on server render, load new data on route changes, and of course, do this at the component level. As I mentioned before, [async-props](https://github.com/ryanflorence/async-props) solves this problem too. It will give you route info so that you can make requests based on things in the url. 153 | 154 | The next problem is one that I haven't fully solved. Webpack is getting really slow. It takes around 20 seconds on a maxed out macbook 15" to build code in production. On the server, it takes more like a minute! If I'm in development mode, it takes around 10 seconds to make the initial build, and sometimes it lags on building the splits on code change. If anyone has insight into this I would love to hear it. 155 | 156 | This one goes along with the webpack one, and it is reloading the server. I haven't tried to webpack the server but I hear doing so works great for this. I don't think it would fix the problem with webpack being slow though, and in fact it would probably make it even slower. 157 | 158 | 159 | ##Folder structure 160 | 161 | I almost forgot to throw this one in here! I'm really happy with the structure of this project. I have a views folder that has all of the same folders and file names as the routes folder. It makes it really easy to find things. These also correspond with the URL to the page. `/account/settings` will be in `views/account/settings.jsx` and `routes/account/settings.js`. The same is true for my tests folder. 162 | 163 | 164 | ##Conclusion 165 | 166 | I hope this gave you a good glimpse at how webpack and react router work at a larger scale than you see most blog posts cover. If you have any questions or things that you would like me to talk about that I haven't already, please leave a comment below and I will update this post! I'm sure that I forgot a few problems and tips writing this. I was thinking this would be a short post but it blew up on me! 167 | -------------------------------------------------------------------------------- /_sass/_main.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /* 3 | Pixyll 4 | A simple, beautiful theme for Jekyll that emphasizes content rather than 5 | aesthetic fluff. 6 | Best served with BASSCSS (http://jxnblk.github.io/basscss) 7 | Crafted with <3 by John Otander (@4lpine) - ©2015 John Otander 8 | MIT License http://opensource.org/licenses/MIT 9 | */ 10 | #carbonads, .carbon-wrap{ 11 | display: -webkit-flex; 12 | display: -ms-flexbox; 13 | display: flex; 14 | -webkit-align-items: center; 15 | -ms-flex-align: center; 16 | align-items: center; 17 | -webkit-justify-content: center; 18 | -ms-flex-pack: center; 19 | justify-content: center; 20 | } 21 | 22 | .carbon-img{ 23 | min-width: 150px; 24 | } 25 | 26 | .carbon-text{ 27 | font-size: 15px; 28 | padding: 5px; 29 | } 30 | 31 | .carbon-poweredby{ 32 | font-size: 10px; 33 | float: right; 34 | } 35 | 36 | body { 37 | font-family: "Merriweather", "PT Serif", Georgia, "Times New Roman", serif; 38 | } 39 | 40 | html, body { 41 | height: 100%; 42 | } 43 | 44 | img { 45 | width: auto; 46 | max-width: 100%; 47 | } 48 | 49 | .site-wrap { 50 | min-height: 100%; 51 | margin-bottom: -120px; 52 | } 53 | 54 | .site-wrap:after { 55 | content: ""; 56 | display: block; 57 | } 58 | 59 | .footer, .site-wrap:after { 60 | height: 120px; 61 | } 62 | 63 | body { 64 | font-size: 1.5rem; 65 | 66 | box-sizing: border-box; 67 | -moz-box-sizing: border-box; 68 | -webkit-box-sizing: border-box; 69 | } 70 | 71 | .gist, 72 | .gist .highlight .p { 73 | font-size: .75rem; 74 | } 75 | 76 | .gist .lines { 77 | width: 100%; 78 | } 79 | 80 | .site-header a { 81 | color: #333; 82 | font-weight: 300; 83 | } 84 | 85 | .site-header nav a { 86 | font-size: 1rem; 87 | color: #666; 88 | } 89 | 90 | .site-header nav a:hover { 91 | color: #444; 92 | opacity: 1; 93 | border-bottom: 2px solid #444; 94 | } 95 | 96 | .site-nav a + a { 97 | margin-left: 1em; 98 | } 99 | 100 | .site-nav { 101 | margin: 0; 102 | padding: 0; 103 | } 104 | 105 | .site-header a:hover, 106 | .posts .post a:hover .post-meta, 107 | .posts .post a:hover .post-title, 108 | .posts .post a:hover .post-summary { 109 | opacity: 0.88; 110 | } 111 | 112 | /* 113 | Table styles copied from Bootstrap 114 | Copyright (c) 2013 Twitter, Inc 115 | */ 116 | 117 | table { 118 | width: 100%; 119 | max-width: 100%; 120 | margin-bottom: 1.5; 121 | font-size: 1.125rem; 122 | // Cells 123 | > thead, 124 | > tbody, 125 | > tfoot { 126 | > tr { 127 | > th, 128 | > td { 129 | padding: 12px; 130 | line-height: 1.2; 131 | vertical-align: top; 132 | border-top: 1px solid #333; 133 | } 134 | } 135 | } 136 | // Bottom align for column headings 137 | > thead > tr > th { 138 | vertical-align: bottom; 139 | border-bottom: 2px solid #333; 140 | } 141 | // Remove top border from thead by default 142 | > caption + thead, 143 | > colgroup + thead, 144 | > thead:first-child { 145 | > tr:first-child { 146 | > th, 147 | > td { 148 | border-top: 0; 149 | } 150 | } 151 | } 152 | // Account for multiple tbody instances 153 | > tbody + tbody { 154 | border-top: 2px solid #333; 155 | } 156 | } 157 | 158 | .related-post-title { 159 | border-bottom: thin solid #f3f3f3; 160 | } 161 | 162 | .posts { 163 | margin: 0; 164 | } 165 | 166 | .posts .post { 167 | margin-bottom: 0.75em; 168 | padding-bottom: .375em; 169 | border-bottom: thin solid #f3f3f3; 170 | } 171 | 172 | .posts .post:last-child { 173 | border-bottom: none; 174 | margin-bottom: .375em; 175 | padding-bottom: 0; 176 | } 177 | 178 | .post-link .post-title { 179 | margin-top: 0; 180 | font-weight: 600; 181 | color: #333; 182 | } 183 | 184 | .post-footer { 185 | @extend .italic; 186 | 187 | margin-top: .75rem; 188 | text-align: center; 189 | } 190 | 191 | .post-footer .avatar { 192 | margin: 2rem 0; 193 | width: 100px; 194 | border-radius: 50%; 195 | } 196 | 197 | .pagination, 198 | .button { 199 | font-size: 1rem; 200 | font-family: 'Lato', 'Helvetica Neue', Helvetica, sans-serif; 201 | font-weight: 300; 202 | text-align: center; 203 | } 204 | 205 | .pagination a, .pagination .disabled { 206 | transition: all 0.2s ease-in-out; 207 | background: #fafafa; 208 | border-radius: 0.1875em; 209 | border: 1px solid #f3f3f3; 210 | color: #333333; 211 | padding: 1em 1.5em; 212 | } 213 | 214 | .pagination .disabled { 215 | opacity: 0.5; 216 | } 217 | 218 | .pagination a:hover, .pagination a:focus { 219 | background: white; 220 | color: #477dca; 221 | } 222 | 223 | .pagination a:active { 224 | background: #f7f7f7; 225 | } 226 | 227 | .wrap .measure { 228 | margin: 0 auto; 229 | } 230 | 231 | .meta, 232 | .post-meta { 233 | width: auto; 234 | font-size: 1rem; 235 | font-weight: 300; 236 | margin: 0; 237 | padding: .25em 0; 238 | color: #7a7a7a; 239 | font-style: italic; 240 | } 241 | 242 | .pagination .button { 243 | font-size: 1rem; 244 | font-weight: 300; 245 | letter-spacing: 1px; 246 | } 247 | 248 | .button-disabled { 249 | opacity: 0.55; 250 | background-color: #999; 251 | } 252 | 253 | .button-disabled:hover, 254 | .button-disabled:active, 255 | .button-disabled:focus { 256 | cursor: not-allowed; 257 | background-color: #999; 258 | } 259 | 260 | form { 261 | font-family: 'Lato', 'Helvetica Neue', Helvetica, sans-serif; 262 | font-weight: 300; 263 | font-size: 1rem; 264 | } 265 | 266 | textarea.input { 267 | height: 8em; 268 | } 269 | 270 | p { 271 | font-weight: 300; 272 | line-height: 1.5; 273 | color: #333; 274 | } 275 | 276 | abbr { 277 | border-bottom: 1px black dotted; 278 | cursor: help; 279 | } 280 | 281 | pre, code { 282 | font-family: Menlo, Monaco, "Courier New", monospace 283 | } 284 | 285 | code { 286 | color: #7a7a7a; 287 | } 288 | 289 | pre { 290 | padding: 1.125em; 291 | font-size: 1.125rem; 292 | line-height: 1.11; 293 | overflow-x: scroll; 294 | margin-bottom: 0.88em; 295 | } 296 | 297 | .highlight .p { 298 | font-size: 1.125rem; 299 | line-height: 1; 300 | } 301 | 302 | blockquote { 303 | padding: 1.33em; 304 | font-style: italic; 305 | border-left: 5px solid #7a7a7a; 306 | } 307 | 308 | blockquote footer { 309 | font-size: .85rem; 310 | font-style: normal; 311 | background-color: #fff; 312 | color: #7a7a7a; 313 | border-color: transparent; 314 | } 315 | 316 | h1, 317 | .h1, 318 | h2, 319 | .h2, 320 | h3, 321 | .h3, 322 | h4, 323 | .h4, 324 | h5, 325 | .h5, 326 | h6, 327 | .h6 { 328 | font-family: "Lato", 'Helvetica Neue', Helvetica, sans-serif; 329 | font-weight: 900; 330 | line-height: 1.2; 331 | margin: 1em 0 0.5em; 332 | } 333 | 334 | .social-icons { 335 | padding: 0.5em 0 0 0; 336 | font-size: 1.25rem; 337 | width: 100%; 338 | } 339 | .social-icons a.fa { 340 | padding: 0.2em; 341 | opacity: 0.8; 342 | cursor: pointer; 343 | } 344 | .social-icons a.fa:hover { 345 | opacity: 1; 346 | } 347 | .social-icons iframe[title=Flattr] { 348 | position: relative; 349 | top: 0.1em; 350 | } 351 | 352 | @media screen and (min-width: 48em) { 353 | .site-header .site-title { 354 | float: left; 355 | } 356 | 357 | .meta, 358 | .post-meta { 359 | margin: 0; 360 | padding: 0; 361 | font-size: 1.25rem; 362 | } 363 | 364 | .h1, 365 | h1 { 366 | font-size: 3.250rem; 367 | } 368 | 369 | .h2, 370 | h2 { 371 | font-size: 2.298rem; 372 | } 373 | 374 | .h3, 375 | h3 { 376 | font-size: 1.625rem; 377 | } 378 | 379 | .h4, 380 | h4 { 381 | font-size: 1.150rem; 382 | } 383 | 384 | .p, 385 | p, 386 | li { 387 | font-size: 1.25rem; 388 | line-height: 1.8; 389 | } 390 | 391 | .small { 392 | font-size: 1rem; 393 | } 394 | 395 | table { 396 | font-size: 1.25rem; 397 | } 398 | 399 | .post-link .post-title { 400 | margin-top: 0.5em; 401 | } 402 | 403 | .posts .post { 404 | margin-bottom: 1.333em; 405 | padding-bottom: 0.666em; 406 | border-bottom: thin solid #f3f3f3; 407 | } 408 | 409 | .posts .post:last-child { 410 | border-bottom: none; 411 | margin-bottom: .333em; 412 | padding-bottom: 0; 413 | } 414 | } 415 | 416 | @media screen and (max-width: 48em) { 417 | blockquote { 418 | margin-left: 1rem; 419 | margin-right: 0; 420 | padding: 0.5em; 421 | } 422 | 423 | .h1, 424 | h1 { 425 | font-size: 2.827rem; 426 | } 427 | 428 | .h2, 429 | h2 { 430 | font-size: 1.999rem; 431 | } 432 | 433 | .h3, 434 | h3 { 435 | font-size: 1.413rem; 436 | } 437 | 438 | .h4, 439 | h4 { 440 | font-size: 1rem; 441 | } 442 | 443 | .site-header { 444 | text-align: center; 445 | } 446 | 447 | .site-header .site-title { 448 | float: center; 449 | } 450 | 451 | .site-header .site-nav { 452 | width: 100%; 453 | float: left; 454 | text-align: center; 455 | margin-top: 0.666em; 456 | margin-bottom: 1.333em; 457 | } 458 | 459 | .social-icons .left, .social-icons .right { 460 | text-align: center; 461 | float: none; 462 | } 463 | } 464 | 465 | @media screen and (min-width: 64em) { 466 | .h1, 467 | h1 { 468 | font-size: 4.498rem; 469 | } 470 | 471 | .h2, 472 | h2 { 473 | font-size: 3.18rem; 474 | } 475 | 476 | .h3, 477 | h3 { 478 | font-size: 2.249rem; 479 | } 480 | 481 | .h4, 482 | h4 { 483 | font-size: 1.591rem; 484 | } 485 | 486 | .posts .post-meta { 487 | padding-bottom: .2em; 488 | } 489 | 490 | .post-link .post-title { 491 | margin-top: .125em; 492 | } 493 | 494 | .posts .post { 495 | margin-bottom: 2.666em; 496 | padding-bottom: 1.333em; 497 | border-bottom: thin solid #f3f3f3; 498 | } 499 | 500 | .posts .post:last-child { 501 | border-bottom: none; 502 | margin-bottom: .666em; 503 | padding-bottom: 0; 504 | } 505 | } 506 | 507 | .share-page { 508 | font-size: 0.65em; 509 | padding: 2em 0 0 0; 510 | } 511 | 512 | .share-page div { 513 | font-size: 1.3em; 514 | } 515 | 516 | footer { 517 | border-top: thin solid #f3f3f3; 518 | } 519 | 520 | footer, 521 | footer .wrap { 522 | color: #7a7a7a; 523 | background-color: #fafafa; 524 | font-family: 'Lato', 'Helvetica Neue', Helvetica, sans-serif; 525 | font-weight: 300; 526 | clear: both; 527 | } 528 | 529 | footer:after { 530 | content: ""; 531 | display: block; 532 | } 533 | 534 | @charset "UTF-8"; 535 | 536 | /*! 537 | Animate.css - http://daneden.me/animate 538 | Licensed under the MIT license - http://opensource.org/licenses/MIT 539 | Copyright (c) 2014 Daniel Eden 540 | */ 541 | 542 | .animated { 543 | -webkit-animation-duration: 1s; 544 | animation-duration: 1s; 545 | -webkit-animation-fill-mode: both; 546 | animation-fill-mode: both; 547 | } 548 | 549 | .animated.infinite { 550 | -webkit-animation-iteration-count: infinite; 551 | animation-iteration-count: infinite; 552 | } 553 | 554 | .animated.hinge { 555 | -webkit-animation-duration: 2s; 556 | animation-duration: 2s; 557 | } 558 | 559 | @-webkit-keyframes fadeInDown { 560 | 0% { 561 | opacity: 0; 562 | -webkit-transform: translateY(-20px); 563 | transform: translateY(-20px); 564 | } 565 | 566 | 100% { 567 | opacity: 1; 568 | -webkit-transform: translateY(0); 569 | transform: translateY(0); 570 | } 571 | } 572 | 573 | @keyframes fadeInDown { 574 | 0% { 575 | opacity: 0; 576 | 577 | -webkit-transform: translateY(-20px) translate3d(0, 0, 0); 578 | transform: translateY(-20px) translate3d(0, 0, 0); 579 | } 580 | 581 | 100% { 582 | opacity: 1; 583 | 584 | -webkit-transform: translateY(0) translate3d(0, 0, 0); 585 | transform: translateY(0) translate3d(0, 0, 0); 586 | } 587 | } 588 | 589 | .fade-in-down { 590 | -webkit-animation-name: fadeInDown; 591 | animation-name: fadeInDown; 592 | } --------------------------------------------------------------------------------webpack splits vs AggressiveMergingPlugin({minSizeReduce: 1.0}) pic.twitter.com/b6kxHEqNcO
— ReactJS News (@ReactJSNews) March 10, 2016