• Stars
    star
    1,818
  • Rank 25,535 (Top 0.6 %)
  • Language
    JavaScript
  • License
    Other
  • Created over 9 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The New & Improved ustwo Website

ustwo.com website

Circle CI build status

Overview

This repository contains all the front end code for the current ustwo.com website and the toolset required to build and deploy it.

In order to be able to have full control over all aspects of the website โ€“ including transitions between pages โ€“ and to make navigation super fast by not having to reload the browser, we decided to build the site as a single-page application. We chose React.js as a main JavaScript technology enabling us to do this, since it has built in support to render pages on the server side too (called isomorphic rendering). This way we could keep the initial rendering performance snappy on mobile and let visitors see content without an extra data loading step which usually happens with most client side JavaScript framework. To enable server side rendering and to have proper URLs, we put a small Node backend server behind our app.

Our content management system behind this is a Wordpress instance which doesn't actually render the pages itself, but instead serves content up via WP API through a mixture of standard and customised JSON REST API endpoints, making the vast majority of the content editable.

Tech stack

React SPA

With the current set of challenges and available browser features we found React.js to be a great solution to templating and events on the UI. The composability of components with the one way binding and "queryless" event handling offered by JSX templates is solving the right problems, without trying to do too much and become a framework. The easy to implement server side rendering combined with the ability to prevent rerendering on client side (by internally doing a comparison to the virtual DOM) is also a great feature to make it a viable solution on mobile.

To make it a single-page application we put Flux Routes and Store behind the React front end, so that it can take over the navigation from the browser and load data from Wordpress by itself.

Since we need to precompile JSX anyway, in our quest to minimise the number of libraries (like Underscore, etc) and push a future-proof way of working with JavaScript, we adopted a lot of ES6 features by transpiling the code with Babel.

As for the CSS, we're using Sass to be able to split our styles and store them together with the components. But in general we're trying to minimise the reliance on Sass language specific features and instead write as much pure CSS as possible, getting ready for a CSS Next / PostCSS world just as we did with ES6.

For the animated illustrations on the site we use SVG sequences, controlled by a small React component. This is unfortunately only possible with inlining SVGs, but all the static vector symbols are stored in one, external SVG sprite, polyfilled for old Internet Explorers with SVG for Everybody.

Node app

Since all the heavy content work is done for is in Wordpress, our Node / Express app is kept as light as possible. The only two main responsibilities are delivering fully baked HTML files through running React rendering on the prefetched content and responding to the same routes as the front end app does.

Nginx

As we had quite a lot of components (or microservices if you will) to tie together โ€“ multiplied by production + staging + dev environments โ€“ we didn't want to overburden our Node server and decided to put an Nginx proxy in place.

Build tools

While we started out using Gulp for our frontend builds which was a very convenient start point for quickly iterating different combination of tools, in the end we settled on shell scripts using the fastest command line builds of libraries.

For JavaScript we're using Browserify (plus Persistify caching) to process our code with Babel and resolve dependencies using Aliasify. Our Sass code is compiled using SassC with PostCSS's Autoprefixer taking care of vendor prefixing. All this happens in a dedicated compiler Docker image, so that we can keep the production application as lean as possible.

To get the Docker environment up and running and to tie all of the above together, we created a fleet of Makefiles to get some extra flexibility with shared variables and task composition on top of shell scripting.

CDN

We have everything served up from a CDN, and by that we mean that ustwo.com is pointed at the CDN URL on a DNS level! Needless to say this guarantees great load speeds across the globe and at very little cost. Call it the "CDN first" approach if you will โ€“ check out our blog post about this here.

Unless you have a lot of user dependent dynamic content (and it's not feasible moving these areas to subdomains) the trick is to remove caching from all layers of the stack, while keeping the client side cache / expiry short (we're using only 1 hour or effectively one session).

This way the only place you need to worry about and manage cache is the CDN. Of course for this you need to have a decent CDN which has an API to purge and prefetch content. At this point all the servers and applications behind can be scaled down to no cache and minimum resources as they'll only be accessed by the CDN network for an occasional update.

The big picture

So here's how all this fits together and creates a working setup with our WordPress backend and CDN.

ustwo.com infrastructure diagram

Inclusion

Browser compatibility

We're aiming to support all evergreen browsers (Chrome, Firefox, Edge and Opera on all platforms), Safari on Mac and iOS, Internet Explorer 10-11 and Android Browser 4.2-4.4.4.

In case you were wondering, we've chosen these as we wanted to be able to use Flexbox, and they also happened to conveniently overlap our historical visitor profiles from Google Analytics.

If you see any misbehaviour with one of these browsers please open an issue!

Performance

Being a studio which is passionate about delivering a great user experience everywhere and early champions of mobile, we kept performance in the front of our minds throughout the process of building the websites.

This means that we are continuously reviewing both hard metrics and perceptual performance. To get reports and keep an eye on things, we found GTmetrix to be a great tool with a generous free tier. It calculates both PageSpeed and YSlow scores, generates a network waterfall, renders a filmstrip view and sends an automated report of all these regularly.

There are too many things to list here, but we mentioned a lot of optimisations throughout this README and might cover some of them specifically in blog posts later.

Accessibility

Officially supporting only modern browsers doesn't mean that we ignore people (and browsers) with special needs.

  • We're delivering prerendered HTML, so content is delivered to and rendered on clients without Javascript (or with overzealous ad blockers)
  • Clean, standards compliant markup
  • WAI-ARIA tags (TODO: test more comprehensively and with real users)

Setup

Docker

In order to get up and running you need Docker. The best way to install Docker is to follow the current Docker documentation

Then add the following aliases to your /etc/hosts file:

127.0.0.1 local.ustwo.com
127.0.0.1 staging.ustwo.com

Note: For setup without the native docker client, skip this step and see DOCKER-SOURCE.md.

Credentials / Vault

  • Open a Terminal window and go to the project folder.

The easiest way is to load the vault image from a tar. If you receive the image tar from someone in the team just do:

    $ make vault-load VAULT_PATH=path/to/vault-2015.tar

If you do not have access to this tar then you can proceed by generating your own self-signed certificates.

    $ make vault-generate-cert
    $ make vault-build

Note: If you use self-signed certificates you probably want to use your docker IP (e.g. docker-machine ip dev) instead of a custom ustwo.com domain.

Develop

Note: Check the MAKE.md for an explanation of how the Make tasks are structured.

  • Open a Terminal window and go to the project folder.

Prepare a new environment:

    $ make compiler-build build

Compile the assets (you can use only this when you're only recompiling on front end stuff):

    $ make stuff

Or target specific subtasks:

    $ make css             # compiles SASS files
    $ make spa             # compiles the React app
    $ make vendors         # compiles app dependencies

Note: css and spa combined with VERBOSE=true will create sourcemaps.

Note: spa and vendors combined with FLUSH_CACHE=true will skip any cache created by browserify. Ex:

    $ make spa VERBOSE=true FLUSH_CACHE=true

Deploy app (when you need to restart services):

    $ make -i love LOCAL_FS=true VERBOSE=true

Note: Add the flag LOCAL_FS=true if you want to use your local files instead of the ones inside the containers. Note: Add the flag VERBOSE=true if you want the JS and CSS expanded and more log output on the services.

As long as LOCAL_FS=true is set a convenient way to refresh the environment is:

    $ make -i love stuff LOCAL_FS=true

As it will rebuild the assets (stuff) and recreate the containers (love) remounting all necessary files from the host environment.

Clean the environment:

    $ make clean

See Node app logs with:

    $ make app-log

And Nginx logs with:

    $ make proxy-log

Watch and reload

  • Open a Terminal window and go to the project folder.

CSS has extra tasks to speed up the development cycle. css-watch starts a fswatch process in the host machine watching any scss or css file under scr/app.

    $ make css-watch

Note: brew install fswatch to install fswatch in your machine.

sync starts a dockerised browser-sync proxy listening by default to port 3000. So you can combine the two:

    $ make -i sync css-watch

Open http://192.168.99.100:3000 in your browser and start editing scss and let the toolchain compile and push changes to the browser.

Note: browser-sync uses a self-signed certificate so using local.ustwo.com or the raw IP will make the browser complain. If you need to overcome this please add a forward rule to Virtualbox so you can use http://localhost:3000.

Test

  • Open a Terminal window and go to the project folder.

Run all tests:

    $ make test

Sandbox

We believe that every component should hold a single responsibity, and which functionality must be working independently from the context the component is instantiated in.

To enforce best practices โ€“ like storing functionality and styles in the component they belong to โ€“ we created a sandbox to test components in an isolated environment.

To prepare the sandbox run:

    $ make sandbox-build

And start the sandbox server with:

    $ make -i sandbox LOCAL_FS=true

The sandbox will be available at https://local.ustwo.com:9443/sandbox

Unit

We're using Mocha + Chai + Sinon to run unit tests against JSDOM as this setup works well with React and executes fast.

Run the unit tests:

    $ make assets-unit-test

Integration

To keep setup simple and still be able to test Internet Explorer and mobile browsers running on real devices, we're running integrations tests using Sauce Labs with a Sauce Connect tunnel. This unfortunately means that if you want to be able to run these tests, you'll need to create an account and set up SAUCE_USERNAME and SAUCE_ACCESS_KEY as environment variables.

Also to minimise context switching, we're running our simple sanity testing suite using Mocha + Chai + Chai Promises + WD.js.

Run the integration tests:

    $ make assets-integration-test

If you need more info on what's happening with the tests, you can either log in to the Sauce web UI to see the Selenium logs to understand more details about the browser interactions or run verbose mode locally for more info on the API requests and their results:

    $ make assets-integration-test VERBOSE=true

TODO: add flow diagram about git branches -> CI, etc

Release

We're using Docker Hub and Docker Machine to tag and deploy Docker images, for more info see RELEASE.md.

Contribution

To read up on our coding style and general contribution guide, have a look at CONTRIBUTING.md.

License

ustwo.com website front end and tools Copyright (C) 2015-2017 ustwo fampany limited.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

More Repositories

1

US2FormValidator

Form validation framework for iOS.
Objective-C
593
star
2

formvalidator-swift

A framework to validate inputs of text fields and text views in a convenient way.
Swift
495
star
3

mastermind

Man in the middle testing
Python
385
star
4

clockwise

Watch face framework for Android Wear developed by ustwo
Java
345
star
5

videoplayback-ios

Swift AVPlayer wrapper using the VIPER architecture. Currently a work in progress
Swift
218
star
6

autocluster

The code base around the cluster prototypes.
JavaScript
101
star
7

ReplayKitUnityBridge

A bridge created from iOS to Unity - exposing the Cocoa ReplayKit API. It allows you to record the screen, set a limited time for the screen to be recorded, and receive a file of the recorded session
ASP
61
star
8

vip-demo-swift

Swift sample app demonstrating VIP architecture for iOS.
Swift
49
star
9

android-boilerplate

Android Boilerplate ร  la ustwo
Java
42
star
10

docker-browser-sync

Docker image for BrowserSync
JavaScript
39
star
11

vip-templates-swift

Xcode templates based on https://clean-swift.com for generating Swift source code in View Interactor Presenter architecture.
Shell
32
star
12

bdd-crossplatform-apps

An ustwo guide about one way to BDD cross platform applications.
Ruby
27
star
13

clockwise-samples

Sample watch faces
Java
24
star
14

GL-2D-watchface

A light-weight library to manage and render Bitmaps in OpenGL on a watch face.
Java
20
star
15

objective-c-style-guide

The ustwo Objective-C style guide
20
star
16

US2MapperKit

JSON driven object mapper developed by ustwo
Swift
17
star
17

midi-to-philips-hue

This is a proof of concept of a set of Philips Hue lights controlled by a Behringer BCD300 MIDI controller
Ruby
16
star
18

android-coding-standards

Android Coding Standards
16
star
19

daydream-experiment

Google Daydream Experiment
C#
15
star
20

recipe-book

ustwobies love food, so they Open Source their recipes, as any sane geek would do.
15
star
21

docker-node-boilerplate

โš ๏ธ No longer maintained โš ๏ธ
JavaScript
10
star
22

brunel

A demonstration of organisation for an app that runs on both iOS and tvOS platforms using a unified code base. โš ๏ธ No longer maintained โš ๏ธ
Swift
9
star
23

docker-sauce-connect

Builds a Sauce Labs Connect image
Makefile
9
star
24

photoshop-contrast-checker

JavaScript
8
star
25

baseviewcontroller-swift

An organizational tool for writing custom view controllers using UIKit.
Ruby
8
star
26

branded-interactions

JavaScript
7
star
27

react-native-experiment

React Native experiment for mapping of content
JavaScript
7
star
28

scout

Scout discovers apps installed on an iOS device utilising the URL scheme feature.
Objective-C
7
star
29

ibeacon-demo

Objective-C
6
star
30

US2KeyboardType

Objective-C
5
star
31

ustwoadventure

Front-end code for the Adventure website
JavaScript
5
star
32

autolayout-helper-ios

UIView helper to easily create common Auto Layout Constraints for iOS
Objective-C
4
star
33

image-color-swift

Swift
4
star
34

toolbar-keyboard-ios

UIToolbar extension to create toolbars useful for keyboards or pickers for iOS
Objective-C
4
star
35

mockingbird

A demonstration of using the Swift Package Manager and writing Swift code to run on both Linux and macOS.
Swift
3
star
36

array-remove-swift

Swift
2
star
37

xcode-snippets

Xcode Snippets
2
star
38

mongolabkit-swift

MongoLabKit is a REST client API for iOS, tvOS and watchOS written to make REST calls to a MongoLab database.
Swift
2
star
39

github-scanner

A commandline tool for scanning GitHub repositories. โš ๏ธ No longer maintained โš ๏ธ
Swift
2
star
40

bench-xr-social-experiments

C#
1
star
41

ustwo-swiftui-bindings-example

Swift
1
star
42

google-docs-scripts

A collection of Google docs scripts
JavaScript
1
star
43

UIColor-US2Colors

UIColor+US2Colors category
Objective-C
1
star
44

homebrew-tools

Collection of tools ustwo development might need
Ruby
1
star
45

ios-swift-dictionaries-sample

Sample code from "Reading from a Dictionary in Swift" blog post.
Objective-C
1
star
46

docker-ansible

DEPRECATED
Makefile
1
star
47

pink-workshop-22

JavaScript
1
star
48

docker-nodejs

DEPRECATED
Makefile
1
star
49

baseview-swift

UIView subclass to abstract Base functionality for iOS
Swift
1
star
50

github-issues

A command line interface to fetch Github Issues โš ๏ธ No longer maintained โš ๏ธ
Rust
1
star
51

engineering-blog

usTwo Engineering
SCSS
1
star