From a91d988889160c60354de90f66d640af3c535519 Mon Sep 17 00:00:00 2001 From: sfletche Date: Fri, 16 Sep 2016 11:19:53 -0700 Subject: [PATCH 01/30] initial react style guide edits --- react/README.md | 38 +++++--------------------------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/react/README.md b/react/README.md index d672e56b16..a884ac1cc8 100644 --- a/react/README.md +++ b/react/README.md @@ -22,7 +22,7 @@ ## Basic Rules - Only include one React component per file. - - However, multiple [Stateless, or Pure, Components](https://facebook.github.io/react/docs/reusable-components.html#stateless-functions) are allowed per file. eslint: [`react/no-multi-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md#ignorestateless). + - eslint: [`react/no-multi-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md#ignorestateless). - Always use JSX syntax. - Do not use `React.createElement` unless you're initializing the app from a file that is not JSX. @@ -72,7 +72,7 @@ ## Naming - **Extensions**: Use `.jsx` extension for React components. - - **Filename**: Use PascalCase for filenames. E.g., `ReservationCard.jsx`. + - **Filename**: Use lower-case-kabob for filenames. E.g., `reservation-card.jsx`. - **Reference Naming**: Use PascalCase for React components and camelCase for their instances. eslint: [`react/jsx-pascal-case`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md) ```jsx @@ -89,44 +89,16 @@ const reservationItem = ; ``` - - **Component Naming**: Use the filename as the component name. For example, `ReservationCard.jsx` should have a reference name of `ReservationCard`. However, for root components of a directory, use `index.jsx` as the filename and use the directory name as the component name: + - **Component Naming**: Use the filename as the component name. For example, `ReservationCard.jsx` should have a reference name of `ReservationCard`: ```jsx // bad - import Footer from './Footer/Footer'; - - // bad - import Footer from './Footer/index'; + import Bootsie from './Footer'; // good import Footer from './Footer'; ``` - - **Higher-order Component Naming**: Use a composite of the higher-order component's name and the passed-in component's name as the `displayName` on the generated component. For example, the higher-order component `withFoo()`, when passed a component `Bar` should produce a component with a `displayName` of `withFoo(Bar)`. - - > Why? A component's `displayName` may be used by developer tools or in error messages, and having a value that clearly expresses this relationship helps people understand what is happening. - - ```jsx - // bad - export default function withFoo(WrappedComponent) { - return function WithFoo(props) { - return ; - } - } - - // good - export default function withFoo(WrappedComponent) { - function WithFoo(props) { - return ; - } - const wrappedComponentName = WrappedComponent.displayName - || WrappedComponent.name - || 'Component'; - - WithFoo.displayName = `withFoo(${wrappedComponentName})`; - return WithFoo; - } - ``` ## Declaration - Do not use `displayName` for naming components. Instead, name the component by reference. @@ -482,7 +454,7 @@ // good render() { - return (
); + return
; } ``` From e27d030b57594553b7b364e50d73bdcf4e50196f Mon Sep 17 00:00:00 2001 From: sfletche Date: Fri, 16 Sep 2016 11:23:34 -0700 Subject: [PATCH 02/30] removing css-in-javascript readme (for now) --- css-in-javascript/README.md | 433 ------------------------------------ 1 file changed, 433 deletions(-) delete mode 100644 css-in-javascript/README.md diff --git a/css-in-javascript/README.md b/css-in-javascript/README.md deleted file mode 100644 index 59c1c7bcbd..0000000000 --- a/css-in-javascript/README.md +++ /dev/null @@ -1,433 +0,0 @@ -# Airbnb CSS-in-JavaScript Style Guide - -*A mostly reasonable approach to CSS-in-JavaScript - -## Table of Contents - -1. [Naming](#naming) -1. [Ordering](#ordering) -1. [Nesting](#nesting) -1. [Inline](#inline) -1. [Themes](#themes) - -## Naming - - - Use camelCase for object keys (i.e. "selectors"). - - > Why? We access these keys as properties on the `styles` object in the component, so it is most convenient to use camelCase. - - ```js - // bad - { - 'bermuda-triangle': { - display: 'none', - }, - } - - // good - { - bermudaTriangle: { - display: 'none', - }, - } - ``` - - - Use an underscore for modifiers to other styles. - - > Why? Similar to BEM, this naming convention makes it clear that the styles are intended to modify the element preceded by the underscore. Underscores do not need to be quoted, so they are preferred over other characters, such as dashes. - - ```js - // bad - { - bruceBanner: { - color: 'pink', - transition: 'color 10s', - }, - - bruceBannerTheHulk: { - color: 'green', - }, - } - - // good - { - bruceBanner: { - color: 'pink', - transition: 'color 10s', - }, - - bruceBanner_theHulk: { - color: 'green', - }, - } - ``` - - - Use `selectorName_fallback` for sets of fallback styles. - - > Why? Similar to modifiers, keeping the naming consistent helps reveal the relationship of these styles to the styles that override them in more adequate browsers. - - ```js - // bad - { - muscles: { - display: 'flex', - }, - - muscles_sadBears: { - width: '100%', - }, - } - - // good - { - muscles: { - display: 'flex', - }, - - muscles_fallback: { - width: '100%', - }, - } - ``` - - - Use a separate selector for sets of fallback styles. - - > Why? Keeping fallback styles contained in a separate object clarifies their purpose, which improves readability. - - ```js - // bad - { - muscles: { - display: 'flex', - }, - - left: { - flexGrow: 1, - display: 'inline-block', - }, - - right: { - display: 'inline-block', - }, - } - - // good - { - muscles: { - display: 'flex', - }, - - left: { - flexGrow: 1, - }, - - left_fallback: { - display: 'inline-block', - }, - - right_fallback: { - display: 'inline-block', - }, - } - ``` - - - Use device-agnostic names (e.g. "small", "medium", and "large") to name media query breakpoints. - - > Why? Commonly used names like "phone", "tablet", and "desktop" do not match the characteristics of the devices in the real world. Using these names sets the wrong expectations. - - ```js - // bad - const breakpoints = { - mobile: '@media (max-width: 639px)', - tablet: '@media (max-width: 1047px)', - desktop: '@media (min-width: 1048px)', - }; - - // good - const breakpoints = { - small: '@media (max-width: 639px)', - medium: '@media (max-width: 1047px)', - large: '@media (min-width: 1048px)', - }; - ``` - -## Ordering - - - Define styles after the component. - - > Why? We use a higher-order component to theme our styles, which is naturally used after the component definition. Passing the styles object directly to this function reduces indirection. - - ```jsx - // bad - const styles = { - container: { - display: 'inline-block', - }, - }; - - function MyComponent({ styles }) { - return ( -
- Never doubt that a small group of thoughtful, committed citizens can - change the world. Indeed, it’s the only thing that ever has. -
- ); - } - - export default withStyles(() => styles)(MyComponent); - - - // good - function MyComponent({ styles }) { - return ( -
- Never doubt that a small group of thoughtful, committed citizens can - change the world. Indeed, it’s the only thing that ever has. -
- ); - } - - export default withStyles(() => ({ - container: { - display: 'inline-block', - }, - }))(MyComponent); - ``` - -## Nesting - - - Leave a blank line between adjacent blocks at the same indentation level. - - > Why? The whitespace improves readability and reduces the likelihood of merge conflicts. - - ```js - // bad - { - bigBang: { - display: 'inline-block', - '::before': { - content: "''", - }, - }, - universe: { - border: 'none', - }, - } - - // good - { - bigBang: { - display: 'inline-block', - - '::before': { - content: "''", - }, - }, - - universe: { - border: 'none', - }, - } - ``` - -## Inline - - - Use inline styles for styles that have a high cardinality (e.g. uses the value of a prop) and not for styles that have a low cardinality. - - > Why? Generating themed stylesheets can be expensive, so they are best for discrete sets of styles. - - ```jsx - // bad - export default function MyComponent({ spacing }) { - return ( -
- ); - } - - // good - function MyComponent({ styles, spacing }) { - return ( -
- ); - } - export default withStyles(() => ({ - periodic: { - display: 'table', - }, - }))(MyComponent); - ``` - -## Themes - - - Use an abstraction layer such as [react-with-styles](https://github.com/airbnb/react-with-styles) that enables theming. *react-with-styles gives us things like `withStyles()`, `ThemedStyleSheet`, and `css()` which are used in some of the examples in this document.* - - > Why? It is useful to have a set of shared variables for styling your components. Using an abstraction layer makes this more convenient. Additionally, this can help prevent your components from being tightly coupled to any particular underlying implementation, which gives you more freedom. - - - Define colors only in themes. - - ```js - // bad - export default withStyles(() => ({ - chuckNorris: { - color: '#bada55', - }, - }))(MyComponent); - - // good - export default withStyles(({ color }) => ({ - chuckNorris: { - color: color.badass, - }, - }))(MyComponent); - ``` - - - Define fonts only in themes. - - ```js - // bad - export default withStyles(() => ({ - towerOfPisa: { - fontStyle: 'italic', - }, - }))(MyComponent); - - // good - export default withStyles(({ font }) => ({ - towerOfPisa: { - fontStyle: font.italic, - }, - }))(MyComponent); - ``` - - - Define fonts as sets of related styles. - - ```js - // bad - export default withStyles(() => ({ - towerOfPisa: { - fontFamily: 'Italiana, "Times New Roman", serif', - fontSize: '2em', - fontStyle: 'italic', - lineHeight: 1.5, - }, - }))(MyComponent); - - // good - export default withStyles(({ font }) => ({ - towerOfPisa: { - ...font.italian, - }, - }))(MyComponent); - ``` - - - Define base grid units in theme (either as a value or a function that takes a multiplier). - - ```js - // bad - export default withStyles(() => ({ - rip: { - bottom: '-6912px', // 6 feet - }, - }))(MyComponent); - - // good - export default withStyles(({ units }) => ({ - rip: { - bottom: units(864), // 6 feet, assuming our unit is 8px - }, - }))(MyComponent); - - // good - export default withStyles(({ unit }) => ({ - rip: { - bottom: 864 * unit, // 6 feet, assuming our unit is 8px - }, - }))(MyComponent); - ``` - - - Define media queries only in themes. - - ```js - // bad - export default withStyles(() => ({ - container: { - width: '100%', - - '@media (max-width: 1047px)': { - width: '50%', - }, - }, - }))(MyComponent); - - // good - export default withStyles(({ breakpoint }) => ({ - container: { - width: '100%', - - [breakpoint.medium]: { - width: '50%', - }, - }, - }))(MyComponent); - ``` - - - Define tricky fallback properties in themes. - - > Why? Many CSS-in-JavaScript implementations merge style objects together which makes specifying fallbacks for the same property (e.g. `display`) a little tricky. To keep the approach unified, put these fallbacks in the theme. - - ```js - // bad - export default withStyles(() => ({ - .muscles { - display: 'flex', - }, - - .muscles_fallback { - 'display ': 'table', - }, - }))(MyComponent); - - // good - export default withStyles(({ fallbacks }) => ({ - .muscles { - display: 'flex', - }, - - .muscles_fallback { - [fallbacks.display]: 'table', - }, - }))(MyComponent); - - // good - export default withStyles(({ fallback }) => ({ - .muscles { - display: 'flex', - }, - - .muscles_fallback { - [fallback('display')]: 'table', - }, - }))(MyComponent); - ``` - - - Create as few custom themes as possible. Many applications may only have one theme. - - - Namespace custom theme settings under a nested object with a unique and descriptive key. - - ```js - // bad - ThemedStyleSheet.registerTheme('mySection', { - mySectionPrimaryColor: 'green', - }); - - // good - ThemedStyleSheet.registerTheme('mySection', { - mySection: { - primaryColor: 'green', - }, - }); - ``` - ---- - -CSS puns adapted from [Saijo George](http://saijogeorge.com/css-puns/). From 84d97e581ea974f219c9bb397a0bf705ae8f95a7 Mon Sep 17 00:00:00 2001 From: sfletche Date: Fri, 16 Sep 2016 11:29:30 -0700 Subject: [PATCH 03/30] name changing and removing links --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 572efb257c..a824166747 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Airbnb JavaScript Style Guide() { +# RenewFinancial JavaScript Style Guide() { -*A mostly reasonable approach to JavaScript* +*Mostly borrowed from Airbnb...* [![Downloads](https://img.shields.io/npm/dm/eslint-config-airbnb.svg)](https://www.npmjs.com/package/eslint-config-airbnb) [![Downloads](https://img.shields.io/npm/dm/eslint-config-airbnb-base.svg)](https://www.npmjs.com/package/eslint-config-airbnb-base) @@ -9,9 +9,6 @@ Other Style Guides - [ES5 (Deprecated)](https://github.com/airbnb/javascript/tree/es5-deprecated/es5) - [React](react/) - - [CSS-in-JavaScript](css-in-javascript/) - - [CSS & Sass](https://github.com/airbnb/css) - - [Ruby](https://github.com/airbnb/ruby) ## Table of Contents From 612a25cbd621b81a0d54a46d43ca45dbdf969e4a Mon Sep 17 00:00:00 2001 From: sfletche Date: Fri, 16 Sep 2016 11:31:05 -0700 Subject: [PATCH 04/30] title and subtitle changes --- README.md | 2 +- react/README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a824166747..e1e91ef2c7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # RenewFinancial JavaScript Style Guide() { -*Mostly borrowed from Airbnb...* +*A mostly reasonable approach to JavaScript (and mostly borrowed from Airbnb)* [![Downloads](https://img.shields.io/npm/dm/eslint-config-airbnb.svg)](https://www.npmjs.com/package/eslint-config-airbnb) [![Downloads](https://img.shields.io/npm/dm/eslint-config-airbnb-base.svg)](https://www.npmjs.com/package/eslint-config-airbnb-base) diff --git a/react/README.md b/react/README.md index a884ac1cc8..379fad4f4f 100644 --- a/react/README.md +++ b/react/README.md @@ -1,6 +1,6 @@ -# Airbnb React/JSX Style Guide +# RenewFinancial React/JSX Style Guide -*A mostly reasonable approach to React and JSX* +*A mostly reasonable approach to React and JSX (and mostly borrowed from Airbnb)* ## Table of Contents From ed53b831b9c2784cd2f0ba15c78c575e7eea5132 Mon Sep 17 00:00:00 2001 From: sfletche Date: Fri, 16 Sep 2016 13:57:53 -0700 Subject: [PATCH 05/30] FE-413: removing 6.2 long strings --- README.md | 21 --------------------- react/README.md | 6 +++--- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index e1e91ef2c7..d15dfb4b9a 100644 --- a/README.md +++ b/README.md @@ -480,27 +480,6 @@ Other Style Guides const name = 'Capt. Janeway'; ``` - - - [6.2](#strings--line-length) Strings that cause the line to go over 100 characters should not be written across multiple lines using string concatenation. - - > Why? Broken strings are painful to work with and make code less searchable. - - ```javascript - // bad - const errorMessage = 'This is a super long error that was thrown because \ - of Batman. When you stop to think about how Batman had anything to do \ - with this, you would get nowhere \ - fast.'; - - // bad - const errorMessage = 'This is a super long error that was thrown because ' + - 'of Batman. When you stop to think about how Batman had anything to do ' + - 'with this, you would get nowhere fast.'; - - // good - const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.'; - ``` - - [6.4](#es6-template-literals) When programmatically building up strings, use template strings instead of concatenation. eslint: [`prefer-template`](http://eslint.org/docs/rules/prefer-template.html) [`template-curly-spacing`](http://eslint.org/docs/rules/template-curly-spacing) jscs: [`requireTemplateStrings`](http://jscs.info/rule/requireTemplateStrings) diff --git a/react/README.md b/react/README.md index 379fad4f4f..d1005d121b 100644 --- a/react/README.md +++ b/react/README.md @@ -22,9 +22,9 @@ ## Basic Rules - Only include one React component per file. - - eslint: [`react/no-multi-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md#ignorestateless). - - Always use JSX syntax. - - Do not use `React.createElement` unless you're initializing the app from a file that is not JSX. + - eslint: [`react/no-multi-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md#ignorestateless) + - Always use JSX syntax + - Do not use `React.createElement` unless you're initializing the app from a file that is not JSX ## Class vs `React.createClass` vs stateless From 7412b7cc2a9ad27c350ea2c69fb83fc8d108b3dc Mon Sep 17 00:00:00 2001 From: danchapman Date: Tue, 20 Sep 2016 08:53:09 -0700 Subject: [PATCH 06/30] adds more tech day changes --- README.md | 61 ++++++++++++++----------------------------------------- 1 file changed, 15 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index d15dfb4b9a..ebda90f69b 100644 --- a/README.md +++ b/README.md @@ -530,9 +530,9 @@ Other Style Guides ## Functions - - [7.1](#functions--declarations) Use named function expressions instead of function declarations. eslint: [`func-style`](http://eslint.org/docs/rules/func-style) jscs: [`requireFunctionDeclarations`](http://jscs.info/rule/requireFunctionDeclarations) + - [7.1](#functions--declarations) Use function declarations. eslint: [`func-style`](http://eslint.org/docs/rules/func-style) jscs: [`requireFunctionDeclarations`](http://jscs.info/rule/requireFunctionDeclarations) - > Why? Function declarations are hoisted, which means that it’s easy - too easy - to reference the function before it is defined in the file. This harms readability and maintainability. If you find that a function’s definition is large or complex enough that it is interfering with understanding the rest of the file, then perhaps it’s time to extract it to its own module! Don’t forget to name the expression - anonymous functions can make it harder to locate the problem in an Error's call stack. + > Why? Because life's too short, you are smart enough to figure out hoisting, and cause Schwalbe. ```javascript // bad @@ -540,12 +540,14 @@ Other Style Guides }; // bad + const foo = function bar() { + }; + + // good function foo() { } - // good - const foo = function bar() { - }; + ``` @@ -1213,12 +1215,12 @@ Other Style Guides ``` - - [11.2](#generators--nope) Don't use generators for now. + - [11.2](#generators--nope) We are going to use generators for now, despite AirBnb's advice. - > Why? They don't transpile well to ES5. + > They don't transpile well to ES5, which is why AirBnb recommends against them. - - [11.3](#generators--spacing) If you must use generators, or if you disregard [our advice](#generators--nope), make sure their function signature is spaced properly. eslint: [`generator-star-spacing`](http://eslint.org/docs/rules/generator-star-spacing) + - [11.3](#generators--spacing) If you use generators, make sure their function signature is spaced properly. eslint: [`generator-star-spacing`](http://eslint.org/docs/rules/generator-star-spacing) > Why? `function` and `*` are part of the same conceptual keyword - `*` is not a modifier for `function`, `function*` is a unique construct, different from `function`. @@ -2160,7 +2162,7 @@ Other Style Guides ``` - - [18.12](#whitespace--max-len) Avoid having lines of code that are longer than 100 characters (including whitespace). Note: per [above](#strings--line-length), long strings are exempt from this rule, and should not be broken up. eslint: [`max-len`](http://eslint.org/docs/rules/max-len.html) jscs: [`maximumLineLength`](http://jscs.info/rule/maximumLineLength) + - [18.12](#whitespace--max-len) Avoid having lines of code that are longer than 100 characters (including whitespace): [`max-len`](http://eslint.org/docs/rules/max-len.html) jscs: [`maximumLineLength`](http://jscs.info/rule/maximumLineLength) > Why? This ensures readability and maintainability. @@ -2421,6 +2423,9 @@ Other Style Guides // good const thisIsMyObject = {}; function thisIsMyFunction() {} + + // exception + const CONSTANT_VALUE = 'hello'; ``` @@ -2491,44 +2496,8 @@ Other Style Guides } ``` - - - [22.6](#naming--filename-matches-export) A base filename should exactly match the name of its default export. - - ```javascript - // file 1 contents - class CheckBox { - // ... - } - export default CheckBox; - - // file 2 contents - export default function fortyTwo() { return 42; } - - // file 3 contents - export default function insideDirectory() {} - - // in some other file - // bad - import CheckBox from './checkBox'; // PascalCase import/export, camelCase filename - import FortyTwo from './FortyTwo'; // PascalCase import/filename, camelCase export - import InsideDirectory from './InsideDirectory'; // PascalCase import/filename, camelCase export - - // bad - import CheckBox from './check_box'; // PascalCase import/export, snake_case filename - import forty_two from './forty_two'; // snake_case import/filename, camelCase export - import inside_directory from './inside_directory'; // snake_case import, camelCase export - import index from './inside_directory/index'; // requiring the index file explicitly - import insideDirectory from './insideDirectory/index'; // requiring the index file explicitly - - // good - import CheckBox from './CheckBox'; // PascalCase export/import/filename - import fortyTwo from './fortyTwo'; // camelCase export/import/filename - import insideDirectory from './insideDirectory'; // camelCase export/import/directory name/implicit "index" - // ^ supports both insideDirectory.js and insideDirectory/index.js - ``` - - - [22.7](#naming--camelCase-default-export) Use camelCase when you export-default a function. Your filename should be identical to your function's name. + - [22.7](#naming--camelCase-default-export) Use camelCase when you export-default a function. ```javascript function makeStyleGuide() { From efbbae2e2adb1b0fc739629b25d100620cc711b6 Mon Sep 17 00:00:00 2001 From: sfletche Date: Tue, 27 Sep 2016 14:42:45 -0700 Subject: [PATCH 07/30] consensus on 7.2 - 7.13 on ES6 styles --- README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ebda90f69b..5c8aaa57b8 100644 --- a/README.md +++ b/README.md @@ -563,7 +563,7 @@ Other Style Guides ``` - - [7.3](#functions--in-blocks) Never declare a function in a non-function block (if, while, etc). Assign the function to a variable instead. Browsers will allow you to do it, but they all interpret it differently, which is bad news bears. eslint: [`no-loop-func`](http://eslint.org/docs/rules/no-loop-func.html) + - [7.3](#functions--in-blocks) Never declare a function in a non-function block (if, while, etc). [`no-loop-func`](http://eslint.org/docs/rules/no-loop-func.html) - [7.4](#functions--note-on-blocks) **Note:** ECMA-262 defines a `block` as a list of statements. A function declaration is not a statement. [Read ECMA-262's note on this issue](http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf#page=97). @@ -576,7 +576,7 @@ Other Style Guides } } - // good + // bad let test; if (currentUser) { test = () => { @@ -697,13 +697,11 @@ Other Style Guides ```javascript // bad - const f = function(){}; - const g = function (){}; - const h = function() {}; + function bad(){} + function bad (){} // good - const x = function () {}; - const y = function a() {}; + function good() {} ``` @@ -715,11 +713,14 @@ Other Style Guides // bad function f1(obj) { obj.key = 1; + ... }; // good function f2(obj) { - const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1; + const newObj = _.clone(obj); + newObj.key = 1; + ... }; ``` From 79ac808175fb0a2d64128cfb961a3235765f49dc Mon Sep 17 00:00:00 2001 From: sfletche Date: Tue, 4 Oct 2016 12:51:38 -0700 Subject: [PATCH 08/30] couple tweaks in 7.2-7.14 --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c8aaa57b8..ef3b691896 100644 --- a/README.md +++ b/README.md @@ -699,13 +699,14 @@ Other Style Guides // bad function bad(){} function bad (){} + function bad () {} // good function good() {} ``` - - [7.12](#functions--mutate-params) Never mutate parameters. eslint: [`no-param-reassign`](http://eslint.org/docs/rules/no-param-reassign.html) + - [7.12](#functions--mutate-params) Never mutate parameters in React (and do your best with Angular). eslint: [`no-param-reassign`](http://eslint.org/docs/rules/no-param-reassign.html) > Why? Manipulating objects passed in as parameters can cause unwanted variable side effects in the original caller. From 5a97a980c4f43af72591facc97c5c0d173a1419e Mon Sep 17 00:00:00 2001 From: sfletche Date: Fri, 18 Nov 2016 14:36:25 -0800 Subject: [PATCH 09/30] completing review of ES6 style guide --- README.md | 507 ++++-------------------------------------------------- 1 file changed, 35 insertions(+), 472 deletions(-) diff --git a/README.md b/README.md index ef3b691896..d490f0c63c 100644 --- a/README.md +++ b/README.md @@ -804,7 +804,7 @@ Other Style Guides // bad [1, 2, 3].map(number => { const nextNumber = number + 1; - `A string containing the ${nextNumber}.`; + return `A string containing the ${nextNumber}.`; }); // good @@ -885,9 +885,6 @@ Other Style Guides // bad const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize; - // good - const itemHeight = item => (item.height > 256 ? item.largeSize : item.smallSize); - // good const itemHeight = (item) => { const { height, largeSize, smallSize } = item; @@ -1024,11 +1021,28 @@ Other Style Guides } } + // good + class Jedi { + getName() { + return this.name; + } + } + // bad class Rey extends Jedi { constructor(...args) { super(...args); } + getbBDash8() { + return this.bBDash8; + } + } + + // good + class Rey extends Jedi { + getbBDash8() { + return this.bBDash8; + } } // good @@ -1037,6 +1051,9 @@ Other Style Guides super(...args); this.name = 'Rey'; } + getbBDash8() { + return this.bBDash8; + } } ``` @@ -1091,7 +1108,8 @@ Other Style Guides - [10.2](#modules--no-wildcard) Do not use wildcard imports. - > Why? This makes sure you have a single default export. + > Why? This makes sure you have a single default export, + > and forces you to define the API (keeping things organized) ```javascript // bad @@ -1189,7 +1207,7 @@ Other Style Guides ## Iterators and Generators - - [11.1](#iterators--nope) Don't use iterators. Prefer JavaScript's higher-order functions instead of loops like `for-in` or `for-of`. eslint: [`no-iterator`](http://eslint.org/docs/rules/no-iterator.html) [`no-restricted-syntax`](http://eslint.org/docs/rules/no-restricted-syntax) + - [11.1](#iterators--nope) Prefer JavaScript's higher-order functions instead of loops like `for-in` or `for-of`. eslint: [`no-iterator`](http://eslint.org/docs/rules/no-iterator.html) [`no-restricted-syntax`](http://eslint.org/docs/rules/no-restricted-syntax) > Why? This enforces our immutable rule. Dealing with pure functions that return values is easier to reason about than side effects. @@ -1341,32 +1359,6 @@ Other Style Guides const dragonball = 'z'; ``` - - - [13.3](#variables--const-let-group) Group all your `const`s and then group all your `let`s. - - > Why? This is helpful when later on you might need to assign a variable depending on one of the previous assigned variables. - - ```javascript - // bad - let i, len, dragonball, - items = getItems(), - goSportsTeam = true; - - // bad - let i; - const items = getItems(); - let dragonball; - const goSportsTeam = true; - let len; - - // good - const goSportsTeam = true; - const items = getItems(); - let dragonball; - let i; - let length; - ``` - - [13.4](#variables--define-where-used) Assign variables where you need them, but place them in a reasonable place. @@ -1438,36 +1430,6 @@ Other Style Guides // the same applies for `const` ``` - - - [13.6](#variables--unary-increment-decrement) Avoid using unary increments and decrements (++, --). eslint [`no-plusplus`](http://eslint.org/docs/rules/no-plusplus) - - > Why? Per the eslint documentation, unary increment and decrement statements are subject to automatic semicolon insertion and can cause silent errors with incrementing or decrementing values within an application. It is also more expressive to mutate your values with statements like `num += 1` instead of `num ++`. Disallowing unary increment and decrement statements also prevents you from pre-incrementing/pre-decrementing values unintentionally which can also cause unexpected behavior in your programs. - - ```javascript - // bad - - let array = [1, 2, 3]; - let num = 1; - let increment = num ++; - let decrement = -- num; - - for(let i = 0; i < array.length; i++){ - let value = array[i]; - ++value; - } - - // good - - let array = [1, 2, 3]; - let num = 1; - let increment = num += 1; - let decrement = num -= 1; - - array.forEach((value) => { - value += 1; - }); - ``` - **[⬆ back to top](#table-of-contents)** @@ -1766,36 +1728,6 @@ Other Style Guides ## Comments - - - [17.1](#comments--multiline) Use `/** ... */` for multi-line comments. - - ```javascript - // bad - // make() returns a new element - // based on the passed in tag name - // - // @param {String} tag - // @return {Element} element - function make(tag) { - - // ...stuff... - - return element; - } - - // good - /** - * make() returns a new element - * based on the passed-in tag name - */ - function make(tag) { - - // ...stuff... - - return element; - } - ``` - - [17.2](#comments--singleline) Use `//` for single line comments. Place single line comments on a newline above the subject of the comment. Put an empty line before the comment unless it's on the first line of a block. @@ -1998,10 +1930,10 @@ Other Style Guides // good $('#items') .find('.selected') - .highlight() - .end() + .highlight() + .end() .find('.open') - .updateCount(); + .updateCount(); // bad const leds = stage.selectAll('.led').data(data).enter().append('svg:svg').classed('led', true) @@ -2011,13 +1943,13 @@ Other Style Guides // good const leds = stage.selectAll('.led') - .data(data) + .data(data) .enter().append('svg:svg') - .classed('led', true) - .attr('width', (radius + margin) * 2) + .classed('led', true) + .attr('width', (radius + margin) * 2) .append('svg:g') - .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')') - .call(tron.led); + .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')') + .call(tron.led); // good const leds = stage.selectAll('.led').data(data); @@ -2164,7 +2096,7 @@ Other Style Guides ``` - - [18.12](#whitespace--max-len) Avoid having lines of code that are longer than 100 characters (including whitespace): [`max-len`](http://eslint.org/docs/rules/max-len.html) jscs: [`maximumLineLength`](http://jscs.info/rule/maximumLineLength) + - [18.12](#whitespace--max-len) Avoid having lines of code that are longer than 120 characters (including whitespace): [`max-len`](http://eslint.org/docs/rules/max-len.html) jscs: [`maximumLineLength`](http://jscs.info/rule/maximumLineLength) > Why? This ensures readability and maintainability. @@ -2594,377 +2526,6 @@ Other Style Guides **[⬆ back to top](#table-of-contents)** -## Events - - - - [24.1](#events--hash) When attaching data payloads to events (whether DOM events or something more proprietary like Backbone events), pass a hash instead of a raw value. This allows a subsequent contributor to add more data to the event payload without finding and updating every handler for the event. For example, instead of: - - ```javascript - // bad - $(this).trigger('listingUpdated', listing.id); - - ... - - $(this).on('listingUpdated', (e, listingId) => { - // do something with listingId - }); - ``` - - prefer: - - ```javascript - // good - $(this).trigger('listingUpdated', { listingId: listing.id }); - - ... - - $(this).on('listingUpdated', (e, data) => { - // do something with data.listingId - }); - ``` - - **[⬆ back to top](#table-of-contents)** - - -## jQuery - - - - [25.1](#jquery--dollar-prefix) Prefix jQuery object variables with a `$`. jscs: [`requireDollarBeforejQueryAssignment`](http://jscs.info/rule/requireDollarBeforejQueryAssignment) - - ```javascript - // bad - const sidebar = $('.sidebar'); - - // good - const $sidebar = $('.sidebar'); - - // good - const $sidebarBtn = $('.sidebar-btn'); - ``` - - - - [25.2](#jquery--cache) Cache jQuery lookups. - - ```javascript - // bad - function setSidebar() { - $('.sidebar').hide(); - - // ...stuff... - - $('.sidebar').css({ - 'background-color': 'pink' - }); - } - - // good - function setSidebar() { - const $sidebar = $('.sidebar'); - $sidebar.hide(); - - // ...stuff... - - $sidebar.css({ - 'background-color': 'pink' - }); - } - ``` - - - - [25.3](#jquery--queries) For DOM queries use Cascading `$('.sidebar ul')` or parent > child `$('.sidebar > ul')`. [jsPerf](http://jsperf.com/jquery-find-vs-context-sel/16) - - - - [25.4](#jquery--find) Use `find` with scoped jQuery object queries. - - ```javascript - // bad - $('ul', '.sidebar').hide(); - - // bad - $('.sidebar').find('ul').hide(); - - // good - $('.sidebar ul').hide(); - - // good - $('.sidebar > ul').hide(); - - // good - $sidebar.find('ul').hide(); - ``` - -**[⬆ back to top](#table-of-contents)** - - -## ECMAScript 5 Compatibility - - - - [26.1](#es5-compat--kangax) Refer to [Kangax](https://twitter.com/kangax/)'s ES5 [compatibility table](https://kangax.github.io/es5-compat-table/). - -**[⬆ back to top](#table-of-contents)** - - -## ECMAScript 6+ (ES 2015+) Styles - - - - [27.1](#es6-styles) This is a collection of links to the various ES6 features. - -1. [Arrow Functions](#arrow-functions) -1. [Classes](#classes--constructors) -1. [Object Shorthand](#es6-object-shorthand) -1. [Object Concise](#es6-object-concise) -1. [Object Computed Properties](#es6-computed-properties) -1. [Template Strings](#es6-template-literals) -1. [Destructuring](#destructuring) -1. [Default Parameters](#es6-default-parameters) -1. [Rest](#es6-rest) -1. [Array Spreads](#es6-array-spreads) -1. [Let and Const](#references) -1. [Iterators and Generators](#iterators-and-generators) -1. [Modules](#modules) - - - - [27.2](#tc39-proposals) Do not use [TC39 proposals](https://github.com/tc39/proposals) that have not reached stage 3. - - > Why? [They are not finalized](https://tc39.github.io/process-document/), and they are subject to change or to be withdrawn entirely. We want to use JavaScript, and proposals are not JavaScript yet. - -**[⬆ back to top](#table-of-contents)** - -## Testing - - - - [28.1](#testing--yup) **Yup.** - - ```javascript - function foo() { - return true; - } - ``` - - - - [28.2](#testing--for-real) **No, but seriously**: - - Whichever testing framework you use, you should be writing tests! - - Strive to write many small pure functions, and minimize where mutations occur. - - Be cautious about stubs and mocks - they can make your tests more brittle. - - We primarily use [`mocha`](https://www.npmjs.com/package/mocha) at Airbnb. [`tape`](https://www.npmjs.com/package/tape) is also used occasionally for small, separate modules. - - 100% test coverage is a good goal to strive for, even if it's not always practical to reach it. - - Whenever you fix a bug, _write a regression test_. A bug fixed without a regression test is almost certainly going to break again in the future. - -**[⬆ back to top](#table-of-contents)** - - -## Performance - - - [On Layout & Web Performance](https://www.kellegous.com/j/2013/01/26/layout-performance/) - - [String vs Array Concat](https://jsperf.com/string-vs-array-concat/2) - - [Try/Catch Cost In a Loop](https://jsperf.com/try-catch-in-loop-cost) - - [Bang Function](https://jsperf.com/bang-function) - - [jQuery Find vs Context, Selector](https://jsperf.com/jquery-find-vs-context-sel/13) - - [innerHTML vs textContent for script text](https://jsperf.com/innerhtml-vs-textcontent-for-script-text) - - [Long String Concatenation](https://jsperf.com/ya-string-concat) - - [Are Javascript functions like `map()`, `reduce()`, and `filter()` optimized for traversing arrays?](https://www.quora.com/JavaScript-programming-language-Are-Javascript-functions-like-map-reduce-and-filter-already-optimized-for-traversing-array/answer/Quildreen-Motta) - - Loading... - -**[⬆ back to top](#table-of-contents)** - - -## Resources - -**Learning ES6** - - - [Draft ECMA 2015 (ES6) Spec](https://people.mozilla.org/~jorendorff/es6-draft.html) - - [ExploringJS](http://exploringjs.com/) - - [ES6 Compatibility Table](https://kangax.github.io/compat-table/es6/) - - [Comprehensive Overview of ES6 Features](http://es6-features.org/) - -**Read This** - - - [Standard ECMA-262](http://www.ecma-international.org/ecma-262/6.0/index.html) - -**Tools** - - - Code Style Linters - + [ESlint](http://eslint.org/) - [Airbnb Style .eslintrc](https://github.com/airbnb/javascript/blob/master/linters/.eslintrc) - + [JSHint](http://jshint.com/) - [Airbnb Style .jshintrc](https://github.com/airbnb/javascript/blob/master/linters/.jshintrc) - + [JSCS](https://github.com/jscs-dev/node-jscs) - [Airbnb Style Preset](https://github.com/jscs-dev/node-jscs/blob/master/presets/airbnb.json) - -**Other Style Guides** - - - [Google JavaScript Style Guide](https://google.github.io/styleguide/javascriptguide.xml) - - [jQuery Core Style Guidelines](https://contribute.jquery.org/style-guide/js/) - - [Principles of Writing Consistent, Idiomatic JavaScript](https://github.com/rwaldron/idiomatic.js) - -**Other Styles** - - - [Naming this in nested functions](https://gist.github.com/cjohansen/4135065) - Christian Johansen - - [Conditional Callbacks](https://github.com/airbnb/javascript/issues/52) - Ross Allen - - [Popular JavaScript Coding Conventions on Github](http://sideeffect.kr/popularconvention/#javascript) - JeongHoon Byun - - [Multiple var statements in JavaScript, not superfluous](http://benalman.com/news/2012/05/multiple-var-statements-javascript/) - Ben Alman - -**Further Reading** - - - [Understanding JavaScript Closures](https://javascriptweblog.wordpress.com/2010/10/25/understanding-javascript-closures/) - Angus Croll - - [Basic JavaScript for the impatient programmer](http://www.2ality.com/2013/06/basic-javascript.html) - Dr. Axel Rauschmayer - - [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Zack Bloom & Adam Schwartz - - [ES6 Features](https://github.com/lukehoban/es6features) - Luke Hoban - - [Frontend Guidelines](https://github.com/bendc/frontend-guidelines) - Benjamin De Cock - -**Books** - - - [JavaScript: The Good Parts](https://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) - Douglas Crockford - - [JavaScript Patterns](https://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752) - Stoyan Stefanov - - [Pro JavaScript Design Patterns](https://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X) - Ross Harmes and Dustin Diaz - - [High Performance Web Sites: Essential Knowledge for Front-End Engineers](https://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309) - Steve Souders - - [Maintainable JavaScript](https://www.amazon.com/Maintainable-JavaScript-Nicholas-C-Zakas/dp/1449327680) - Nicholas C. Zakas - - [JavaScript Web Applications](https://www.amazon.com/JavaScript-Web-Applications-Alex-MacCaw/dp/144930351X) - Alex MacCaw - - [Pro JavaScript Techniques](https://www.amazon.com/Pro-JavaScript-Techniques-John-Resig/dp/1590597273) - John Resig - - [Smashing Node.js: JavaScript Everywhere](https://www.amazon.com/Smashing-Node-js-JavaScript-Everywhere-Magazine/dp/1119962595) - Guillermo Rauch - - [Secrets of the JavaScript Ninja](https://www.amazon.com/Secrets-JavaScript-Ninja-John-Resig/dp/193398869X) - John Resig and Bear Bibeault - - [Human JavaScript](http://humanjavascript.com/) - Henrik Joreteg - - [Superhero.js](http://superherojs.com/) - Kim Joar Bekkelund, Mads Mobæk, & Olav Bjorkoy - - [JSBooks](http://jsbooks.revolunet.com/) - Julien Bouquillon - - [Third Party JavaScript](https://www.manning.com/books/third-party-javascript) - Ben Vinegar and Anton Kovalyov - - [Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript](http://amzn.com/0321812182) - David Herman - - [Eloquent JavaScript](http://eloquentjavascript.net/) - Marijn Haverbeke - - [You Don't Know JS: ES6 & Beyond](http://shop.oreilly.com/product/0636920033769.do) - Kyle Simpson - -**Blogs** - - - [DailyJS](http://dailyjs.com/) - - [JavaScript Weekly](http://javascriptweekly.com/) - - [JavaScript, JavaScript...](https://javascriptweblog.wordpress.com/) - - [Bocoup Weblog](https://bocoup.com/weblog) - - [Adequately Good](http://www.adequatelygood.com/) - - [NCZOnline](https://www.nczonline.net/) - - [Perfection Kills](http://perfectionkills.com/) - - [Ben Alman](http://benalman.com/) - - [Dmitry Baranovskiy](http://dmitry.baranovskiy.com/) - - [Dustin Diaz](http://dustindiaz.com/) - - [nettuts](http://code.tutsplus.com/?s=javascript) - -**Podcasts** - - - [JavaScript Air](https://javascriptair.com/) - - [JavaScript Jabber](https://devchat.tv/js-jabber/) - - -**[⬆ back to top](#table-of-contents)** - -## In the Wild - - This is a list of organizations that are using this style guide. Send us a pull request and we'll add you to the list. - - - **4Catalyzer**: [4Catalyzer/javascript](https://github.com/4Catalyzer/javascript) - - **Aan Zee**: [AanZee/javascript](https://github.com/AanZee/javascript) - - **Adult Swim**: [adult-swim/javascript](https://github.com/adult-swim/javascript) - - **Airbnb**: [airbnb/javascript](https://github.com/airbnb/javascript) - - **Apartmint**: [apartmint/javascript](https://github.com/apartmint/javascript) - - **Ascribe**: [ascribe/javascript](https://github.com/ascribe/javascript) - - **Avalara**: [avalara/javascript](https://github.com/avalara/javascript) - - **Avant**: [avantcredit/javascript](https://github.com/avantcredit/javascript) - - **Billabong**: [billabong/javascript](https://github.com/billabong/javascript) - - **Bisk**: [bisk/javascript](https://github.com/Bisk/javascript/) - - **Blendle**: [blendle/javascript](https://github.com/blendle/javascript) - - **Brainshark**: [brainshark/javascript](https://github.com/brainshark/javascript) - - **Chartboost**: [ChartBoost/javascript-style-guide](https://github.com/ChartBoost/javascript-style-guide) - - **ComparaOnline**: [comparaonline/javascript](https://github.com/comparaonline/javascript-style-guide) - - **Compass Learning**: [compasslearning/javascript-style-guide](https://github.com/compasslearning/javascript-style-guide) - - **DailyMotion**: [dailymotion/javascript](https://github.com/dailymotion/javascript) - - **DoSomething**: [DoSomething/eslint-config](https://github.com/DoSomething/eslint-config) - - **Digitpaint** [digitpaint/javascript](https://github.com/digitpaint/javascript) - - **Ecosia**: [ecosia/javascript](https://github.com/ecosia/javascript) - - **Evernote**: [evernote/javascript-style-guide](https://github.com/evernote/javascript-style-guide) - - **Evolution Gaming**: [evolution-gaming/javascript](https://github.com/evolution-gaming/javascript) - - **EvozonJs**: [evozonjs/javascript](https://github.com/evozonjs/javascript) - - **ExactTarget**: [ExactTarget/javascript](https://github.com/ExactTarget/javascript) - - **Expensify** [Expensify/Style-Guide](https://github.com/Expensify/Style-Guide/blob/master/javascript.md) - - **Flexberry**: [Flexberry/javascript-style-guide](https://github.com/Flexberry/javascript-style-guide) - - **Gawker Media**: [gawkermedia/javascript](https://github.com/gawkermedia/javascript) - - **General Electric**: [GeneralElectric/javascript](https://github.com/GeneralElectric/javascript) - - **GoodData**: [gooddata/gdc-js-style](https://github.com/gooddata/gdc-js-style) - - **Grooveshark**: [grooveshark/javascript](https://github.com/grooveshark/javascript) - - **How About We**: [howaboutwe/javascript](https://github.com/howaboutwe/javascript-style-guide) - - **Huballin**: [huballin/javascript](https://github.com/huballin/javascript) - - **HubSpot**: [HubSpot/javascript](https://github.com/HubSpot/javascript) - - **Hyper**: [hyperoslo/javascript-playbook](https://github.com/hyperoslo/javascript-playbook/blob/master/style.md) - - **InfoJobs**: [InfoJobs/JavaScript-Style-Guide](https://github.com/InfoJobs/JavaScript-Style-Guide) - - **Intent Media**: [intentmedia/javascript](https://github.com/intentmedia/javascript) - - **Jam3**: [Jam3/Javascript-Code-Conventions](https://github.com/Jam3/Javascript-Code-Conventions) - - **JeopardyBot**: [kesne/jeopardy-bot](https://github.com/kesne/jeopardy-bot/blob/master/STYLEGUIDE.md) - - **JSSolutions**: [JSSolutions/javascript](https://github.com/JSSolutions/javascript) - - **KickorStick**: [kickorstick/javascript](https://github.com/kickorstick/javascript) - - **Kinetica Solutions**: [kinetica/javascript](https://github.com/kinetica/Javascript-style-guide) - - **M2GEN**: [M2GEN/javascript](https://github.com/M2GEN/javascript) - - **Mighty Spring**: [mightyspring/javascript](https://github.com/mightyspring/javascript) - - **MinnPost**: [MinnPost/javascript](https://github.com/MinnPost/javascript) - - **MitocGroup**: [MitocGroup/javascript](https://github.com/MitocGroup/javascript) - - **ModCloth**: [modcloth/javascript](https://github.com/modcloth/javascript) - - **Money Advice Service**: [moneyadviceservice/javascript](https://github.com/moneyadviceservice/javascript) - - **Muber**: [muber/javascript](https://github.com/muber/javascript) - - **National Geographic**: [natgeo/javascript](https://github.com/natgeo/javascript) - - **National Park Service**: [nationalparkservice/javascript](https://github.com/nationalparkservice/javascript) - - **Nimbl3**: [nimbl3/javascript](https://github.com/nimbl3/javascript) - - **Orion Health**: [orionhealth/javascript](https://github.com/orionhealth/javascript) - - **OutBoxSoft**: [OutBoxSoft/javascript](https://github.com/OutBoxSoft/javascript) - - **Peerby**: [Peerby/javascript](https://github.com/Peerby/javascript) - - **Razorfish**: [razorfish/javascript-style-guide](https://github.com/razorfish/javascript-style-guide) - - **reddit**: [reddit/styleguide/javascript](https://github.com/reddit/styleguide/tree/master/javascript) - - **React**: [/facebook/react/blob/master/CONTRIBUTING.md#style-guide](https://github.com/facebook/react/blob/master/CONTRIBUTING.md#style-guide) - - **REI**: [reidev/js-style-guide](https://github.com/rei/code-style-guides/blob/master/docs/javascript.md) - - **Ripple**: [ripple/javascript-style-guide](https://github.com/ripple/javascript-style-guide) - - **SeekingAlpha**: [seekingalpha/javascript-style-guide](https://github.com/seekingalpha/javascript-style-guide) - - **Shutterfly**: [shutterfly/javascript](https://github.com/shutterfly/javascript) - - **Springload**: [springload/javascript](https://github.com/springload/javascript) - - **StratoDem Analytics**: [stratodem/javascript](https://github.com/stratodem/javascript) - - **SteelKiwi Development**: [steelkiwi/javascript](https://github.com/steelkiwi/javascript) - - **StudentSphere**: [studentsphere/javascript](https://github.com/studentsphere/guide-javascript) - - **SysGarage**: [sysgarage/javascript-style-guide](https://github.com/sysgarage/javascript-style-guide) - - **Syzygy Warsaw**: [syzygypl/javascript](https://github.com/syzygypl/javascript) - - **Target**: [target/javascript](https://github.com/target/javascript) - - **TheLadders**: [TheLadders/javascript](https://github.com/TheLadders/javascript) - - **The Nerdery**: [thenerdery/javascript-standards](https://github.com/thenerdery/javascript-standards) - - **T4R Technology**: [T4R-Technology/javascript](https://github.com/T4R-Technology/javascript) - - **VoxFeed**: [VoxFeed/javascript-style-guide](https://github.com/VoxFeed/javascript-style-guide) - - **WeBox Studio**: [weboxstudio/javascript](https://github.com/weboxstudio/javascript) - - **Weggo**: [Weggo/javascript](https://github.com/Weggo/javascript) - - **Zillow**: [zillow/javascript](https://github.com/zillow/javascript) - - **ZocDoc**: [ZocDoc/javascript](https://github.com/ZocDoc/javascript) - -**[⬆ back to top](#table-of-contents)** - -## Translation - - This style guide is also available in other languages: - - - ![br](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Brazil.png) **Brazilian Portuguese**: [armoucar/javascript-style-guide](https://github.com/armoucar/javascript-style-guide) - - ![bg](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Bulgaria.png) **Bulgarian**: [borislavvv/javascript](https://github.com/borislavvv/javascript) - - ![ca](https://raw.githubusercontent.com/fpmweb/javascript-style-guide/master/img/catala.png) **Catalan**: [fpmweb/javascript-style-guide](https://github.com/fpmweb/javascript-style-guide) - - ![cn](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/China.png) **Chinese (Simplified)**: [sivan/javascript-style-guide](https://github.com/sivan/javascript-style-guide) - - ![tw](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Taiwan.png) **Chinese (Traditional)**: [jigsawye/javascript](https://github.com/jigsawye/javascript) - - ![fr](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/France.png) **French**: [nmussy/javascript-style-guide](https://github.com/nmussy/javascript-style-guide) - - ![de](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Germany.png) **German**: [timofurrer/javascript-style-guide](https://github.com/timofurrer/javascript-style-guide) - - ![it](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Italy.png) **Italian**: [sinkswim/javascript-style-guide](https://github.com/sinkswim/javascript-style-guide) - - ![jp](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Japan.png) **Japanese**: [mitsuruog/javascript-style-guide](https://github.com/mitsuruog/javascript-style-guide) - - ![kr](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/South-Korea.png) **Korean**: [tipjs/javascript-style-guide](https://github.com/tipjs/javascript-style-guide) - - ![pl](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Poland.png) **Polish**: [mjurczyk/javascript](https://github.com/mjurczyk/javascript) - - ![ru](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Russia.png) **Russian**: [uprock/javascript](https://github.com/uprock/javascript) - - ![es](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Spain.png) **Spanish**: [paolocarrasco/javascript-style-guide](https://github.com/paolocarrasco/javascript-style-guide) - - ![th](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Thailand.png) **Thai**: [lvarayut/javascript-style-guide](https://github.com/lvarayut/javascript-style-guide) - - ![vn](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Vietnam.png) **Vietnam**: [giangpii/javascript-style-guide](https://github.com/giangpii/javascript-style-guide) - -## The JavaScript Style Guide Guide - - - [Reference](https://github.com/airbnb/javascript/wiki/The-JavaScript-Style-Guide-Guide) - -## Chat With Us About JavaScript - - - Find us on [gitter](https://gitter.im/airbnb/javascript). - -## Contributors - - - [View Contributors](https://github.com/airbnb/javascript/graphs/contributors) - - ## License (The MIT License) @@ -2997,3 +2558,5 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. We encourage you to fork this guide and change the rules to fit your team's style guide. Below, you may list some amendments to the style guide. This allows you to periodically update your style guide without having to deal with merge conflicts. # }; + +TODO: List edited sections here From d02b6273d284b10764c60dd6626d5bdea2ca4a37 Mon Sep 17 00:00:00 2001 From: sfletche Date: Fri, 18 Nov 2016 14:38:13 -0800 Subject: [PATCH 10/30] cleaning up table of contents --- README.md | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index d490f0c63c..01de33cccf 100644 --- a/README.md +++ b/README.md @@ -35,18 +35,6 @@ Other Style Guides 1. [Type Casting & Coercion](#type-casting--coercion) 1. [Naming Conventions](#naming-conventions) 1. [Accessors](#accessors) - 1. [Events](#events) - 1. [jQuery](#jquery) - 1. [ECMAScript 5 Compatibility](#ecmascript-5-compatibility) - 1. [ECMAScript 6+ (ES 2015+) Styles](#ecmascript-6-es-2015-styles) - 1. [Testing](#testing) - 1. [Performance](#performance) - 1. [Resources](#resources) - 1. [In the Wild](#in-the-wild) - 1. [Translation](#translation) - 1. [The JavaScript Style Guide Guide](#the-javascript-style-guide-guide) - 1. [Chat With Us About JavaScript](#chat-with-us-about-javascript) - 1. [Contributors](#contributors) 1. [License](#license) ## Types @@ -1360,7 +1348,7 @@ Other Style Guides ``` - - [13.4](#variables--define-where-used) Assign variables where you need them, but place them in a reasonable place. + - [13.3](#variables--define-where-used) Assign variables where you need them, but place them in a reasonable place. > Why? `let` and `const` are block scoped and not function scoped. @@ -1398,7 +1386,7 @@ Other Style Guides } ``` - - [13.5](#variables--no-chain-assignment) Don't chain variable assignments. + - [13.4](#variables--no-chain-assignment) Don't chain variable assignments. > Why? Chaining variable assignments creates implicit global variables. From 9ba0d49bbc0ecef6954ebeada790e4afd5246961 Mon Sep 17 00:00:00 2001 From: sfletche Date: Fri, 18 Nov 2016 14:40:15 -0800 Subject: [PATCH 11/30] removing translation section from react readme --- react/README.md | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/react/README.md b/react/README.md index d1005d121b..9ed3297c23 100644 --- a/react/README.md +++ b/react/README.md @@ -1,6 +1,6 @@ # RenewFinancial React/JSX Style Guide -*A mostly reasonable approach to React and JSX (and mostly borrowed from Airbnb)* +*A mostly reasonable approach to React and JSX (mostly borrowed from Airbnb)* ## Table of Contents @@ -540,14 +540,4 @@ [anti-pattern]: https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html -## Translation - - This JSX/React style guide is also available in other languages: - - - ![cn](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/China.png) **Chinese (Simplified)**: [JasonBoy/javascript](https://github.com/JasonBoy/javascript/tree/master/react) - - ![pl](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Poland.png) **Polish**: [pietraszekl/javascript](https://github.com/pietraszekl/javascript/tree/master/react) - - ![kr](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/South-Korea.png) **Korean**: [apple77y/javascript](https://github.com/apple77y/javascript/tree/master/react) - - ![Br](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Brazil.png) **Portuguese**: [ronal2do/javascript](https://github.com/ronal2do/airbnb-react-styleguide) - - ![jp](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Japan.png) **Japanese**: [mitsuruog/javascript-style-guide](https://github.com/mitsuruog/javascript-style-guide/tree/master/react) - **[⬆ back to top](#table-of-contents)** From c5ff99ae33e7891378eac2135fa08ec4c05dcd29 Mon Sep 17 00:00:00 2001 From: sfletche Date: Fri, 18 Nov 2016 14:43:32 -0800 Subject: [PATCH 12/30] adjusting section numbers --- README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 01de33cccf..f59cc50bc7 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ Other Style Guides ``` - - [3.4](#es6-computed-properties) Use computed property names when creating objects with dynamic property names. + - [3.2](#es6-computed-properties) Use computed property names when creating objects with dynamic property names. > Why? They allow you to define all the properties of an object in one place. @@ -166,7 +166,7 @@ Other Style Guides ``` - - [3.5](#es6-object-shorthand) Use object method shorthand. eslint: [`object-shorthand`](http://eslint.org/docs/rules/object-shorthand.html) jscs: [`requireEnhancedObjectLiterals`](http://jscs.info/rule/requireEnhancedObjectLiterals) + - [3.3](#es6-object-shorthand) Use object method shorthand. eslint: [`object-shorthand`](http://eslint.org/docs/rules/object-shorthand.html) jscs: [`requireEnhancedObjectLiterals`](http://jscs.info/rule/requireEnhancedObjectLiterals) ```javascript // bad @@ -189,7 +189,7 @@ Other Style Guides ``` - - [3.6](#es6-object-concise) Use property value shorthand. eslint: [`object-shorthand`](http://eslint.org/docs/rules/object-shorthand.html) jscs: [`requireEnhancedObjectLiterals`](http://jscs.info/rule/requireEnhancedObjectLiterals) + - [3.4](#es6-object-concise) Use property value shorthand. eslint: [`object-shorthand`](http://eslint.org/docs/rules/object-shorthand.html) jscs: [`requireEnhancedObjectLiterals`](http://jscs.info/rule/requireEnhancedObjectLiterals) > Why? It is shorter to write and descriptive. @@ -208,7 +208,7 @@ Other Style Guides ``` - - [3.7](#objects--grouped-shorthand) Group your shorthand properties at the beginning of your object declaration. + - [3.5](#objects--grouped-shorthand) Group your shorthand properties at the beginning of your object declaration. > Why? It's easier to tell which properties are using the shorthand. @@ -238,7 +238,7 @@ Other Style Guides ``` - - [3.8](#objects--quoted-props) Only quote properties that are invalid identifiers. eslint: [`quote-props`](http://eslint.org/docs/rules/quote-props.html) jscs: [`disallowQuotedKeysInObjects`](http://jscs.info/rule/disallowQuotedKeysInObjects) + - [3.6](#objects--quoted-props) Only quote properties that are invalid identifiers. eslint: [`quote-props`](http://eslint.org/docs/rules/quote-props.html) jscs: [`disallowQuotedKeysInObjects`](http://jscs.info/rule/disallowQuotedKeysInObjects) > Why? In general we consider it subjectively easier to read. It improves syntax highlighting, and is also more easily optimized by many JS engines. @@ -259,7 +259,7 @@ Other Style Guides ``` - - [3.9](#objects--prototype-builtins) Do not call `Object.prototype` methods directly, such as `hasOwnProperty`, `propertyIsEnumerable`, and `isPrototypeOf`. + - [3.7](#objects--prototype-builtins) Do not call `Object.prototype` methods directly, such as `hasOwnProperty`, `propertyIsEnumerable`, and `isPrototypeOf`. > Why? These methods may be shadowed by properties on the object in question - consider `{ hasOwnProperty: false }` - or, the object may be a null object (`Object.create(null)`). @@ -469,7 +469,7 @@ Other Style Guides ``` - - [6.4](#es6-template-literals) When programmatically building up strings, use template strings instead of concatenation. eslint: [`prefer-template`](http://eslint.org/docs/rules/prefer-template.html) [`template-curly-spacing`](http://eslint.org/docs/rules/template-curly-spacing) jscs: [`requireTemplateStrings`](http://jscs.info/rule/requireTemplateStrings) + - [6.2](#es6-template-literals) When programmatically building up strings, use template strings instead of concatenation. eslint: [`prefer-template`](http://eslint.org/docs/rules/prefer-template.html) [`template-curly-spacing`](http://eslint.org/docs/rules/template-curly-spacing) jscs: [`requireTemplateStrings`](http://jscs.info/rule/requireTemplateStrings) > Why? Template strings give you a readable, concise syntax with proper newlines and string interpolation features. @@ -496,10 +496,10 @@ Other Style Guides ``` - - [6.5](#strings--eval) Never use `eval()` on a string, it opens too many vulnerabilities. + - [6.3](#strings--eval) Never use `eval()` on a string, it opens too many vulnerabilities. - - [6.6](#strings--escaping) Do not unnecessarily escape characters in strings. eslint: [`no-useless-escape`](http://eslint.org/docs/rules/no-useless-escape) + - [6.4](#strings--escaping) Do not unnecessarily escape characters in strings. eslint: [`no-useless-escape`](http://eslint.org/docs/rules/no-useless-escape) > Why? Backslashes harm readability, thus they should only be present when necessary. @@ -1717,7 +1717,7 @@ Other Style Guides ## Comments - - [17.2](#comments--singleline) Use `//` for single line comments. Place single line comments on a newline above the subject of the comment. Put an empty line before the comment unless it's on the first line of a block. + - [17.1](#comments--singleline) Use `//` for single line comments. Place single line comments on a newline above the subject of the comment. Put an empty line before the comment unless it's on the first line of a block. ```javascript // bad @@ -1756,10 +1756,10 @@ Other Style Guides ``` - - [17.3](#comments--actionitems) Prefixing your comments with `FIXME` or `TODO` helps other developers quickly understand if you're pointing out a problem that needs to be revisited, or if you're suggesting a solution to the problem that needs to be implemented. These are different than regular comments because they are actionable. The actions are `FIXME: -- need to figure this out` or `TODO: -- need to implement`. + - [17.2](#comments--actionitems) Prefixing your comments with `FIXME` or `TODO` helps other developers quickly understand if you're pointing out a problem that needs to be revisited, or if you're suggesting a solution to the problem that needs to be implemented. These are different than regular comments because they are actionable. The actions are `FIXME: -- need to figure this out` or `TODO: -- need to implement`. - - [17.4](#comments--fixme) Use `// FIXME:` to annotate problems. + - [17.3](#comments--fixme) Use `// FIXME:` to annotate problems. ```javascript class Calculator extends Abacus { @@ -1773,7 +1773,7 @@ Other Style Guides ``` - - [17.5](#comments--todo) Use `// TODO:` to annotate solutions to problems. + - [17.4](#comments--todo) Use `// TODO:` to annotate solutions to problems. ```javascript class Calculator extends Abacus { @@ -2419,7 +2419,7 @@ Other Style Guides ``` - - [22.7](#naming--camelCase-default-export) Use camelCase when you export-default a function. + - [22.6](#naming--camelCase-default-export) Use camelCase when you export-default a function. ```javascript function makeStyleGuide() { @@ -2429,7 +2429,7 @@ Other Style Guides ``` - - [22.8](#naming--PascalCase-singleton) Use PascalCase when you export a constructor / class / singleton / function library / bare object. + - [22.7](#naming--PascalCase-singleton) Use PascalCase when you export a constructor / class / singleton / function library / bare object. ```javascript const AirbnbStyleGuide = { From 814a1dc06ecb613e0a46b40b05c279e166673775 Mon Sep 17 00:00:00 2001 From: sfletche Date: Fri, 18 Nov 2016 14:57:37 -0800 Subject: [PATCH 13/30] adding airbnb link --- README.md | 6 +----- react/README.md | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f59cc50bc7..00a55ca677 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,6 @@ # RenewFinancial JavaScript Style Guide() { -*A mostly reasonable approach to JavaScript (and mostly borrowed from Airbnb)* - -[![Downloads](https://img.shields.io/npm/dm/eslint-config-airbnb.svg)](https://www.npmjs.com/package/eslint-config-airbnb) -[![Downloads](https://img.shields.io/npm/dm/eslint-config-airbnb-base.svg)](https://www.npmjs.com/package/eslint-config-airbnb-base) -[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/airbnb/javascript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) +*A mostly reasonable approach to JavaScript (mostly borrowed from [Airbnb](https://github.com/airbnb/javascript))* Other Style Guides - [ES5 (Deprecated)](https://github.com/airbnb/javascript/tree/es5-deprecated/es5) diff --git a/react/README.md b/react/README.md index 9ed3297c23..36380fc501 100644 --- a/react/README.md +++ b/react/README.md @@ -1,6 +1,6 @@ # RenewFinancial React/JSX Style Guide -*A mostly reasonable approach to React and JSX (mostly borrowed from Airbnb)* +*A mostly reasonable approach to React and JSX (mostly borrowed from [Airbnb](https://github.com/airbnb/javascript))* ## Table of Contents From 55b63f3440f2cfb5aa8844e1f5453be5d2aabfc8 Mon Sep 17 00:00:00 2001 From: sfletche Date: Fri, 18 Nov 2016 16:25:42 -0800 Subject: [PATCH 14/30] removing amendments section --- README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/README.md b/README.md index 00a55ca677..5f2376d36b 100644 --- a/README.md +++ b/README.md @@ -2537,10 +2537,3 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **[⬆ back to top](#table-of-contents)** -## Amendments - -We encourage you to fork this guide and change the rules to fit your team's style guide. Below, you may list some amendments to the style guide. This allows you to periodically update your style guide without having to deal with merge conflicts. - -# }; - -TODO: List edited sections here From 97593a371dbf7c248528f3b9ad185a44a62e36c3 Mon Sep 17 00:00:00 2001 From: Scott Fletcher Date: Wed, 30 Nov 2016 15:34:07 -0800 Subject: [PATCH 15/30] updating title --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5f2376d36b..c3c10f58b5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# RenewFinancial JavaScript Style Guide() { +# RenewFinancial JavaScript Style Guide *A mostly reasonable approach to JavaScript (mostly borrowed from [Airbnb](https://github.com/airbnb/javascript))* From 20e768438d34fc1ef485660df66150a02dff3560 Mon Sep 17 00:00:00 2001 From: sfletche Date: Tue, 24 Jan 2017 09:14:37 -0800 Subject: [PATCH 16/30] adjusting quoted strings --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c3c10f58b5..e1d3b5de1d 100644 --- a/README.md +++ b/README.md @@ -504,8 +504,8 @@ Other Style Guides const foo = '\'this\' \i\s \"quoted\"'; // good - const foo = '\'this\' is "quoted"'; - const foo = `'this' is "quoted"`; + const foo = 'this is "quoted"'; + const foo = `and 'this' is also "quoted"`; ``` **[⬆ back to top](#table-of-contents)** From 7ffb1a36d80c38981f3553f9a7b21ce6495259e4 Mon Sep 17 00:00:00 2001 From: manjumuthaiya Date: Fri, 2 Jun 2017 13:07:50 -0700 Subject: [PATCH 17/30] Add proptypes guidelines --- react/README.md | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/react/README.md b/react/README.md index 36380fc501..9900354d71 100644 --- a/react/README.md +++ b/react/README.md @@ -12,6 +12,7 @@ 1. [Quotes](#quotes) 1. [Spacing](#spacing) 1. [Props](#props) + 1. [Proptypes](#proptypes) 1. [Refs](#refs) 1. [Parentheses](#parentheses) 1. [Tags](#tags) @@ -297,6 +298,72 @@ ))} ``` +## Proptypes + - Always use `PropTypes.shape` to define object proptypes. Avoid `PropTypes.object`. + ``` + UserDisplay.propTypes = { + user: PropTypes.shape({ + name: PropTypes.string, + email: PropTypes.string, + birthday: PropTypes.instanceOf(Date), + }), + }; + ``` + - When a component's proptypes can be used in multiple components, export it as a `const` from the component file. + ``` + export const statusPropTypes = { + active: PropTypes.bool.isRequired, + message: PropTypes.string.isRequired, + }; + StatusMessage.propTypes = statusPropTypes; + export default StatusMessage; + ``` + + Usage: + ``` + import StatusMessage, { statusPropTypes } from './status-message'; + + class AppContainer { }; + AppContainer.propTypes = { + status: statusPropTypes, + data: PropTypes.string.isRequired, + }; + ``` + - When a subset of a component's proptypes can be used in multiple components, export it as a `const` from the component file. + + ``` + export const partialFilterPropTypes = { + searchString: PropTypes.string, + }; + FilterData.propTypes = { + ...partialFilterPropTypes, + }; + ``` + - When a set of proptypes are not associated with a single component, but can be used across multiple components, define them in a `constants/proptypes.js` file. Example: + *constants/proptypes.js* + ``` + export const userDataPropTypes = { + name: PropTypes.string, + email: PropTypes.string, + birthday: PropTypes.instanceOf(Date), + } + ``` + + *Users.jsx* + ``` + Users.propTypes = { + users: PropTypes.arrayOf(PropTypes.shape(userDataPropTypes)).isRequired, + }; + ``` + + *UserDisplay.jsx* + ``` + UserDisplay.propTypes = { + user: PropTypes.shape(userDataPropTypes).isRequired, + }; + ``` + + ## Refs - Always use ref callbacks. eslint: [`react/no-string-refs`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md) From 39f6283f73d774f2f9b6e455000ae1baf2e1e6e4 Mon Sep 17 00:00:00 2001 From: manjumuthaiya Date: Fri, 2 Jun 2017 13:15:03 -0700 Subject: [PATCH 18/30] Add extra prop --- react/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/react/README.md b/react/README.md index 9900354d71..f3956cb8c1 100644 --- a/react/README.md +++ b/react/README.md @@ -334,9 +334,11 @@ ``` export const partialFilterPropTypes = { searchString: PropTypes.string, + onFilter: PropTypes.func, }; FilterData.propTypes = { ...partialFilterPropTypes, + isFilterActive: PropTypes.bool.isRequired, }; ``` - When a set of proptypes are not associated with a single component, but can be used across multiple components, define them in a `constants/proptypes.js` file. Example: From 4a36b8a350856f1e215a2d62970e56678707e80d Mon Sep 17 00:00:00 2001 From: manjumuthaiya Date: Mon, 5 Jun 2017 10:08:02 -0700 Subject: [PATCH 19/30] Modify some text --- react/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/README.md b/react/README.md index f3956cb8c1..b4f878c5ac 100644 --- a/react/README.md +++ b/react/README.md @@ -341,7 +341,7 @@ isFilterActive: PropTypes.bool.isRequired, }; ``` - - When a set of proptypes are not associated with a single component, but can be used across multiple components, define them in a `constants/proptypes.js` file. Example: + - When describing a shape that is associated with multiple components, define them in a `constants/proptypes.js` file. Example: *constants/proptypes.js* ``` export const userDataPropTypes = { From fb4f387751c448c0ccb1a6757c45b0a78d3a8173 Mon Sep 17 00:00:00 2001 From: manjumuthaiya Date: Mon, 5 Jun 2017 10:12:33 -0700 Subject: [PATCH 20/30] code review edits --- react/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/react/README.md b/react/README.md index b4f878c5ac..f70b769547 100644 --- a/react/README.md +++ b/react/README.md @@ -309,7 +309,7 @@ }), }; ``` - - When a component's proptypes can be used in multiple components, export it as a `const` from the component file. + - When a component's proptypes can be used in multiple (3 or more) components, export it as a `const` from the component file. ``` export const statusPropTypes = { active: PropTypes.bool.isRequired, @@ -329,7 +329,7 @@ data: PropTypes.string.isRequired, }; ``` - - When a subset of a component's proptypes can be used in multiple components, export it as a `const` from the component file. + - When a subset of a component's proptypes can be used in multiple (3 or more) components, export it as a `const` from the component file. ``` export const partialFilterPropTypes = { @@ -341,7 +341,7 @@ isFilterActive: PropTypes.bool.isRequired, }; ``` - - When describing a shape that is associated with multiple components, define them in a `constants/proptypes.js` file. Example: + - When describing a shape that is associated with multiple (3 or more) components, define the shape in a `constants/proptypes.js` file. Example: *constants/proptypes.js* ``` export const userDataPropTypes = { From abce508e166971ed0cc6ded9c44083c94d377c34 Mon Sep 17 00:00:00 2001 From: sfletche Date: Mon, 5 Jun 2017 13:23:37 -0700 Subject: [PATCH 21/30] allowing wildcard imports AND requiring api def --- README.md | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index e1d3b5de1d..37885bed69 100644 --- a/README.md +++ b/README.md @@ -1089,22 +1089,34 @@ Other Style Guides export default es6; ``` - - - [10.2](#modules--no-wildcard) Do not use wildcard imports. - - > Why? This makes sure you have a single default export, - > and forces you to define the API (keeping things organized) + + - [10.2](#modules--define-api) Always define your module's API at the bottom of the file. ```javascript - // bad - import * as AirbnbStyleGuide from './AirbnbStyleGuide'; + // bad named exports + export const foo = 23; + export const bar = 42; - // good - import AirbnbStyleGuide from './AirbnbStyleGuide'; + // good named exports + const foo = 23; + const bar = 42; + export { foo, bar }; + + // bad default export + export default function foo() { ... } + ... + + // good defualt export + ... + export default function foo() { ... } + + // also good default export + function foo() { ... } + export default foo; ``` - - [10.3](#modules--no-export-from-import) And do not export directly from an import. + - [10.3](#modules--no-export-from-import) Do not export directly from an import. > Why? Although the one-liner is concise, having one clear way to import and one clear way to export makes things consistent. From 91dbd4976a7a54c5d1fd9a19a074cc3ab8a9f2ba Mon Sep 17 00:00:00 2001 From: sfletche Date: Mon, 5 Jun 2017 15:06:15 -0700 Subject: [PATCH 22/30] correcting typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 37885bed69..20b7782073 100644 --- a/README.md +++ b/README.md @@ -1106,7 +1106,7 @@ Other Style Guides export default function foo() { ... } ... - // good defualt export + // good default export ... export default function foo() { ... } From a90a3cf6c6c1ea4c7bf121b00cf9d9b72142ff8d Mon Sep 17 00:00:00 2001 From: sfletche Date: Thu, 8 Jun 2017 19:50:01 -0700 Subject: [PATCH 23/30] default exports for Component and Reducer files --- react/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/react/README.md b/react/README.md index f70b769547..eb7c7fbdca 100644 --- a/react/README.md +++ b/react/README.md @@ -26,6 +26,7 @@ - eslint: [`react/no-multi-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md#ignorestateless) - Always use JSX syntax - Do not use `React.createElement` unless you're initializing the app from a file that is not JSX + - Use default exports for Component and Reducer files, use named exports for everything else. ## Class vs `React.createClass` vs stateless From 868eef2907366e6d508d98e0f34cec3cb17a58da Mon Sep 17 00:00:00 2001 From: sfletche Date: Mon, 12 Jun 2017 15:23:17 -0700 Subject: [PATCH 24/30] adding more named exports examples --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 20b7782073..ac853a4a64 100644 --- a/README.md +++ b/README.md @@ -1102,6 +1102,19 @@ Other Style Guides const bar = 42; export { foo, bar }; + // bad named export + export const foo = 23; // not the last thing in the file + ... + + // good named export + ... + export const foo = 23; // the last thing and the only exported thing + + // also good named export + ... + const foo = 23; + export { foo }; + // bad default export export default function foo() { ... } ... From 497790f6d6b6d93d03e818c488d0bae004706f7a Mon Sep 17 00:00:00 2001 From: lpoehler Date: Tue, 13 Jun 2017 14:21:35 -0700 Subject: [PATCH 25/30] FE-1002: Cleaning up the styles to better represent out default export rules. --- .gitignore | 1 + README.md | 29 +++++++++-------------------- 2 files changed, 10 insertions(+), 20 deletions(-) diff --git a/.gitignore b/.gitignore index 3c3629e647..eb79dd5fc7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +.idea diff --git a/README.md b/README.md index ac853a4a64..267ede4bb9 100644 --- a/README.md +++ b/README.md @@ -1082,11 +1082,12 @@ Other Style Guides // ok import AirbnbStyleGuide from './AirbnbStyleGuide'; - export default AirbnbStyleGuide.es6; + const es6 = AirbnbStyleGuide.es6; + export { es6 }; // best import { es6 } from './AirbnbStyleGuide'; - export default es6; + export { es6 }; ``` @@ -1116,16 +1117,16 @@ Other Style Guides export { foo }; // bad default export - export default function foo() { ... } + export default function Foo() { ... } ... // good default export ... - export default function foo() { ... } + export default function Foo() { ... } // also good default export - function foo() { ... } - export default foo; + function Foo() { ... } + export default Foo; ``` @@ -1136,12 +1137,12 @@ Other Style Guides ```javascript // bad // filename es6.js - export { es6 as default } from './airbnbStyleGuide'; + export { es6 } from './airbnbStyleGuide'; // good // filename es6.js import { es6 } from './AirbnbStyleGuide'; - export default es6; + export es6; ``` @@ -1180,18 +1181,6 @@ Other Style Guides export { foo } ``` - - - [10.6](#modules--prefer-default-export) In modules with a single export, prefer default export over named export. - eslint: [`import/prefer-default-export`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/prefer-default-export.md) - - ```javascript - // bad - export function foo() {} - - // good - export default function foo() {} - ``` - - [10.7](#modules--imports-first) Put all `import`s above non-import statements. eslint: [`import/imports-first`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/imports-first.md) From 5a6e6a3ad3c9aa6e9d4494908e2c01812dec4861 Mon Sep 17 00:00:00 2001 From: lpoehler Date: Tue, 13 Jun 2017 15:52:06 -0700 Subject: [PATCH 26/30] FE-1033 updating index number --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 267ede4bb9..d62f2ab3cf 100644 --- a/README.md +++ b/README.md @@ -1182,7 +1182,7 @@ Other Style Guides ``` - - [10.7](#modules--imports-first) Put all `import`s above non-import statements. + - [10.6](#modules--imports-first) Put all `import`s above non-import statements. eslint: [`import/imports-first`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/imports-first.md) > Why? Since `import`s are hoisted, keeping them all at the top prevents surprising behavior. From bdbe4ea9c684b6b3c170ce20585485a17b4f4e26 Mon Sep 17 00:00:00 2001 From: lpoehler Date: Tue, 13 Jun 2017 16:01:20 -0700 Subject: [PATCH 27/30] FE-1033 adding note about how to export --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d62f2ab3cf..83d919f02f 100644 --- a/README.md +++ b/README.md @@ -1181,8 +1181,32 @@ Other Style Guides export { foo } ``` + + - [10.6](#modules--named-export) In general, excluding React Component and Reducer files, named exports should be preferred. + eslint: [`import/prefer-default-export`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/prefer-default-export.md) + + ```javascript + // bad + ... + export default function foo() {} + + // good + ... + export function foo() {} + + // also good + ... + function foo() {} + export foo; + + // also good + ... + function foo() {} + export { foo }; + ``` + - - [10.6](#modules--imports-first) Put all `import`s above non-import statements. + - [10.7](#modules--imports-first) Put all `import`s above non-import statements. eslint: [`import/imports-first`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/imports-first.md) > Why? Since `import`s are hoisted, keeping them all at the top prevents surprising behavior. From 3e09108e884bef27768f950e4c23adf1f2615db7 Mon Sep 17 00:00:00 2001 From: sschwalbe Date: Wed, 18 Oct 2017 11:28:03 -0700 Subject: [PATCH 28/30] add multiline import rule --- README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/README.md b/README.md index 83d919f02f..7b7e18dc96 100644 --- a/README.md +++ b/README.md @@ -1224,6 +1224,23 @@ Other Style Guides foo.init(); ``` + + - [10.8](#modules--multiline-imports) For multiline imports, put all imports on their own line. + + ```javascript + //bad + import { a, b + c, d } from 'module'; + + //good + import { + a, + b, + c, + d, + } from 'module'; + ``` + **[⬆ back to top](#table-of-contents)** ## Iterators and Generators From 23234f2f142b7d97f8da67248f1698afc33dfa8f Mon Sep 17 00:00:00 2001 From: sschwalbe Date: Wed, 18 Oct 2017 11:30:12 -0700 Subject: [PATCH 29/30] typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7b7e18dc96..e579c0420c 100644 --- a/README.md +++ b/README.md @@ -1224,7 +1224,7 @@ Other Style Guides foo.init(); ``` - + - [10.8](#modules--multiline-imports) For multiline imports, put all imports on their own line. ```javascript From 1e0f86521d62f5cec9a9717692ab3ccaaaf2f699 Mon Sep 17 00:00:00 2001 From: sschwalbe Date: Thu, 19 Oct 2017 09:31:27 -0700 Subject: [PATCH 30/30] language --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index e579c0420c..ae59d61b53 100644 --- a/README.md +++ b/README.md @@ -1225,7 +1225,7 @@ Other Style Guides ``` - - [10.8](#modules--multiline-imports) For multiline imports, put all imports on their own line. + - [10.8](#modules--multiline-imports) For imports that don't fit in one line, put all imports on their own line. If imports fit in one line, they can stay in one line. ```javascript //bad @@ -1239,6 +1239,9 @@ Other Style Guides c, d, } from 'module'; + + //good + import { a, b } from 'module'; ``` **[⬆ back to top](#table-of-contents)**