React Web App Development Guide

Style Guide

We follow AirBnB JavaScript style guide and React styleg uide.

You should lint your code with ESLint to align with the requirements. From the terminal do

$ npm run lint

or

$ yarn run lint

Please do not create pull requests if your code has linter errors.

CSS modules and SCSS Style guide

Unit tests

Under development

We would like you to do unit tests for all your code.

Configuration

TBD

CI / CD

Migrate from Travis to CircleCI (TBD)

Architecture

Organization

As any big project ours is organized in a way that allows scale and feature separation. It is best that each item has its own place, and everybody can follow and find the code she is looking for.

Connect App follows the following structure:

root
|
|--config/						(all webpack configuration files)
|--examples/					(example code)
|--node_modules/				(all node dependencies)
|--src/							(all source file)
	|--actions/					(system actions)
	|--api/
	|--assets/					(all icons and images)
	|--components/				(global components)
	|--config/					(app configurations)
	|--containers/				(app pages)
	|--helpers/					(source file)
	|--reducers/				(redux reducers)
	|--styles/					(all the app styles)
		|--_helpers/			(helper files included in main.scss)
		|--themes/				(where all themes are stored)
			|--connect/			(the default theme)
		|--vendors/				(all 3rd party styles in a separate folder)
		|--main.scss			(the compiled stylesheet)
	|--index.html
	|--index.jsx
|
|--readme.md
|--package.json

Each container (page) should replicate appropriate structure to include all components, reducers they may need. Imagine that we have a project list container that displays all Connect projects in a list view. Each list card would be the main building block, and each card would use some of the global components. Based on the feature separation each component should be accompanied by its logic (as .js file) and style (as .scss file) with the same name.

root
|
|--containers/
	|--project-listing/
		|--actions/
		|--components/
			|--card/
				|--card.jsx
				|--card.js
				|--card.scss
			|--grid_header/
			|--grid_footer/
		|--reducers/
	|--projectListing.jsx
	|--projectListing.js
	|--projectListing.scss

Components

We have 3 types of components:

For more information read Thinking in React

Dumb components

We whould think of those as small blocks of HTML that are repeated multiple times. There should be no logic into a dumb component. All content should be passed by the smart parent as props, and managed by the parent.

const DumbComponent = (props) => {
  return (<div />);
}

Always use props. Period. Read Typechecking With PropTypes

Smart components

Smart containers should build the view with dumb components to avoid repetition and also manage all the data for the dumb components.

Containers

The reason you want to use containers that pass down the data is because you want to avoid having to connect every view to a store when dealing with Flux/Redux. (from here)

Optimize repo size

from this article

Reduce the repo size by always explicitly loading only the things you need, not the whole bundle.

Bloated

import { concat, sortBy, map, sample } from 'lodash';

Lean

import concat from 'lodash/concat';
import sortBy from 'lodash/sortBy';
import map from 'lodash/map';
import sample from 'lodash/sample';

We still don’t have Webpack 2 and tree shaking. Until we upgrade our Webpack, follow this guide.

Resources

https://medium.com/@nesbtesh/react-best-practices-a76fd0fbef21#.v87936dd1 https://engineering.siftscience.com/best-practices-for-building-large-react-applications/ https://facebook.github.io/react/docs/react-component.html

Component styling

CSS Modules provides a novel way to treat the plain old CSS — during build time all the class names of the component and namespaced by webpack (depending on your configuration). This allows us to reuse the same generic .classname in many components and depending on position in the DOM they’ll be compiled to something like .u234432-classname-2344324bngfdsdfgsdfg. This solves the global contamination of namespaces.

For brevity, CSS modules introduce a new keyword composes: … that allows you to reuse styles from the global lists, so you don’t need to write the same code twice. It behaves similar to extends in Sass. For further details read the Css Modules repo.

Connect uses React and to help with the CSS Modules implementation we use a NPM plugin CSS React Modules.

All styles should be in the SCSS format (.scss) and follow CSS Modules. In order for the system to properly compile your styles, use .m.scss suffix for your components.

In the case of 3rd party component being used in Connect, you have to provide a styling alternative in a dedicated folder the ~/scr/styles/vendors/ that matches the name of the component.

Application themes

NOTE: Under development.

We want to create runtime/context dependable styling for our apps. There are cases where the components would need to apply different styles based on the user, organisation or subdomain. The best solution so far seems to be https://github.com/javivelasco/react-css-themr.

Topcoder has its own library of components that we ship with default css. In the next version (2.0) of tc-react-components we will upgrade the styles to use CSS Modules and thus be able to pick different styles through style override.

SVG and images

Scalabel Vector Graphics (SVG) is amazing, and we love it. The best way to use it in our app is through React SVG loader. This converts our .SVG images into React components that we can modify in the code through passing the appropriate .classname. This helps to keep the icons and images in format that can be easily maintained by the designer, limits manual labor and potential errors.

All .svg images should reside under ~/src/assets/icons. Any .svg placed in that folder by default would be available for you as a React component upon import. Any .svg outside of this folder should use .inline.svg suffix for webpack to be able to pick it up.

Example:

// Load the .svg file as react component
import IconDashboard from "icons/dashboard.svg"

...

<li>
	<Link {...getLinkProps()}>
		// Use the new react component as inline SVG and customize it through CSS
		<IcondDashboard className="active"/> Dashboard
	</Link>
</li>

Bonus: Why inline SVG is Best SVG - cool video

Note for the designers: When you export your amazing designs into SVG, please remove any classnames and other styles, use only the standard properties (fill) to add color.