Feed powered byStream Blue Logo Copy 5
Avatar of Russel Werner

Russel Werner

Lead Engineer at StackShare

Decision at StackShare about Redis, CircleCI, Webpack, Amazon CloudFront, Amazon S3, GitHub, Heroku, Rails, Node.js, Apollo, Glamorous, React, FrontEndRepoSplit, Microservices, SSR, StackDecisionsLaunch

Avatar of ruswerner
Lead Engineer at StackShare
RedisRedis
CircleCICircleCI
WebpackWebpack
Amazon CloudFrontAmazon CloudFront
Amazon S3Amazon S3
GitHubGitHub
HerokuHeroku
RailsRails
Node.jsNode.js
ApolloApollo
GlamorousGlamorous
ReactReact
#FrontEndRepoSplit
#Microservices
#SSR
#StackDecisionsLaunch

StackShare Feed is built entirely with React, Glamorous, and Apollo. One of our objectives with the public launch of the Feed was to enable a Server-side rendered (SSR) experience for our organic search traffic. When you visit the StackShare Feed, and you aren't logged in, you are delivered the Trending feed experience. We use an in-house Node.js rendering microservice to generate this HTML. This microservice needs to run and serve requests independent of our Rails web app. Up until recently, we had a mono-repo with our Rails and React code living happily together and all served from the same web process. In order to deploy our SSR app into a Heroku environment, we needed to split out our front-end application into a separate repo in GitHub. The driving factor in this decision was mostly due to limitations imposed by Heroku specifically with how processes can't communicate with each other. A new SSR app was created in Heroku and linked directly to the frontend repo so it stays in-sync with changes.

Related to this, we need a way to "deploy" our frontend changes to various server environments without building & releasing the entire Ruby application. We built a hybrid Amazon S3 Amazon CloudFront solution to host our Webpack bundles. A new CircleCI script builds the bundles and uploads them to S3. The final step in our rollout is to update some keys in Redis so our Rails app knows which bundles to serve. The result of these efforts were significant. Our frontend team now moves independently of our backend team, our build & release process takes only a few minutes, we are now using an edge CDN to serve JS assets, and we have pre-rendered React pages!

#StackDecisionsLaunch #SSR #Microservices #FrontEndRepoSplit

10 upvotes20.6K views

Decision at StackShare about Emotion, JavaScript, Glamorous, React, HAML, Sass, Inlinecss

Avatar of ruswerner
Lead Engineer at StackShare
EmotionEmotion
JavaScriptJavaScript
GlamorousGlamorous
ReactReact
HAMLHAML
SassSass
#Inlinecss

When we rebooted our front-end stack earlier this year, we wanted to have a consolidated and friendly developer experience. Up to that point we were using Sass and BEM. There was a mix of HAML views, React components and Angular. Since our ongoing development was going to be exclusively in React, we wanted to shift to an inline styling library so the "wall of classnames" could be eliminated. The ever-shifting landscape of inline CSS libraries for React is sometimes difficult to navigate.

We decided to go with Glamorous for a few reasons:

1) Previous team experience with this library 2) We can write our styles in plain JavaScript (which brings many benefits) 3) It supports server-side rendering 4) It has great composition patterns

As you may or may not know, Glamorous has ceased active development and been mostly superseded by Emotion. We are planning to migrate to either Emotion or @styled-components in the near future, and I'll write another Stack Decision when we get there!

#inlinecss

9 upvotes5.7K views

Decision at StackShare about Redux.js, Apollo, React, GraphQL, FrontEndFrameworks

Avatar of ruswerner
Lead Engineer at StackShare
Redux.jsRedux.js
ApolloApollo
ReactReact
GraphQLGraphQL
#FrontEndFrameworks

Earlier this year we decided to go "all-in" on GraphQL to provide our front-end API. We needed a stable client library to power our React app. We decided to use Apollo Client for a few reasons:

1) Stability 2) Maturity 3) Heaps of features 4) Great documentation (with use cases) 5) Support for server-side rendering 6) Allowed us to stop using Redux and Mobx

Overall we've had great success with this library, along with a few minor hiccups and work arounds, but no show stoppers. If you are coming from Redux.js land, it takes a bit of time to settle into a new way of thinking about how your data is fetched and flows through your React app. This part has been the biggest learning curve of anything to do with GraphQL.

One of the downsides to Apollo Client, once you build a larger application, (past the size of most of the documented use cases and sample apps) the state management tends to get distributed through various places; and not just components. Apollo Client has a state management feature that relies on a normalised local cache. Mastering the knowledge of how this works is key to getting the most out of the library and to architecting your component hierarchy properly.

#FrontEndFrameworks

9 upvotes1 comment1.7K views

Decision at StackShare about GraphQL, Apollo, Rails, React, React Storybook

Avatar of ruswerner
Lead Engineer at StackShare
GraphQLGraphQL
ApolloApollo
RailsRails
ReactReact
React StorybookReact Storybook

Our front-end team decided to use React Storybook for our primary React development environment. It allows us to write components in isolation without the need to fire up our Rails stack. When writing components in isolation; you can focus on styling, behaviour and prop design. It forces you to think about how your component is going to be used by others. React Storybook uses webpack and hot module reloading under the hood. This allows us to write components very quickly since it hot reloads in the browser as you code!

The knobs add-on is great for testing different edge cases for the component props. There is even an add-on that will auto-render and snapshot your components with every prop permutation allows by your defined knobs. These snapshots can then be part of your CI testing.

We have a step in our build process that publishes a static React Storybook site on our production server. This allows our entire team to interactively test components before they are integrated into larger features. Once we are happy with our components in isolation, we integrate them into connected feature components which are wired up to Apollo and GraphQL to provide the data and state.

There are heaps of React Storybook add-ons to checkout. If you aren't using it, you should be.

8 upvotes2K views

Decision at StackShare about Percy, Happo.io, React Storybook, Enzyme, Jest

Avatar of ruswerner
Lead Engineer at StackShare
PercyPercy
Happo.ioHappo.io
React StorybookReact Storybook
EnzymeEnzyme
JestJest

We use Jest because when we rebooted our "front end" stack earlier last year, we need to have a testing solution (we didn't have any front-end tests before that!). Jest is fast and convenient and it has plenty of community support behind it. It let's us run our unit tests with Enzyme and snapshot tests.

This is an area that we are constantly reviewing to see what can be improved, both in terms of developer needs, accuracy, test maintainability, and coverage.

I'm currently exploring using React Storybook to be the record of snapshot tests and using some online services, such as Happo.io and Percy in our CI pipeline.

7 upvotes1.6K views

Decision at StackShare about HTML5

Avatar of ruswerner
Lead Engineer at StackShare
HTML5HTML5

We use HTML5 because it has now become the standard in building websites. We have recently performed a "semantic sweep" of our markup and are now using the newer HTML5 semantic tags for the various content across our pages. This includes <aside>, <header>, <main>, <nav>, etc. We are also making more use of CSS transitions where it makes sense and enhances the user experience.

7 upvotes1.6K views

Decision at StackShare about Visual Studio Code, WebStorm, ESLint, Prettier

Avatar of ruswerner
Lead Engineer at StackShare
Visual Studio CodeVisual Studio Code
WebStormWebStorm
ESLintESLint
PrettierPrettier

We use Prettier because when we rebooted our front-end stack, I decided that it would be an efficient use of our time to not worry about code formatting issues and personal preferences during peer review. Prettier eliminates this concern by auto-formatting our code to a deterministic output. We use it along with ESLint and have 1st-class support in our WebStorm and Visual Studio Code editors.

6 upvotes1.8K views

Decision at StackShare about React, StackDecisionsLaunch

Avatar of ruswerner
Lead Engineer at StackShare
ReactReact
#StackDecisionsLaunch

We adopted react-motion for all our animated React UI transitions, which is still in-use when you focus/blur the Decision Composer. However, when we built out the mobile version of StackShare Feed, it became immediately obvious that there were some performance problems with this library. I really prefer using spring physics over timeline-based tweens; they make the movement feel more natural and more like native apps (on mobile platforms). The API design in react-motion uses a render prop pattern, which is nice to use, however I believe it is causing too many re-renders to execute the animations. We ultimately had to remove react-motion on mobile and use hand-written rAf and time-based easing functions. We'll be working on removing react-motion, in favour of our own animation library, for the remainder of our site in the near future. #StackDecisionsLaunch

6 upvotes1.2K views

Decision at StackShare about React, Apollo, GraphQL, MobX

Avatar of ruswerner
Lead Engineer at StackShare
ReactReact
ApolloApollo
GraphQLGraphQL
MobXMobX

Some of our existing pages use MobX however we decided to stop using MobX for new work for a few good reasons:

  1. It forced us to use an experimental language feature (decorators)
  2. We went all-in on GraphQL and Apollo to manage our data and local state.

For all the places where we don't store state in Apollo Client, we use plain old React and hooks (useState and useContext). Our first choice in state management it to have all state stored in Apollo keeping local state accurate by using mutation updates, client resolvers, and local cache.

4 upvotes1.6K views