Naoufal Kadhom
9 years ago
6 changed files with 371 additions and 1 deletions
@ -1 +1,291 @@ |
|||
# javascript |
|||
# Unsplash JavaScript Style Guide |
|||
*How we like to JavasScript at [Unsplash](https://www.unsplash.com)*. |
|||
|
|||
## Table of Contents |
|||
- [Airbnb JavaScript Style Guide](https://github.com/unsplash/javascript#airbnb-javascript-style-guide) |
|||
- [Exceptions](https://github.com/unsplash/javascript#exceptions) |
|||
- [Additional Guidelines](https://github.com/unsplash/javascript#additional-guidelines) |
|||
- [Naming Conventions](https://github.com/unsplash/javascript#naming-conventions) |
|||
- [References](https://github.com/unsplash/javascript#references) |
|||
|
|||
## Airbnb JavaScript Style Guide |
|||
Our guide is based off the excellent [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript), with a few exceptions and additional guidelines. |
|||
|
|||
## Exceptions |
|||
#### Objects |
|||
- Do not use trailing commas. [comma-dangle](http://eslint.org/docs/rules/comma-dangle) |
|||
> It breaks your code in IE8. |
|||
|
|||
```js |
|||
// bad |
|||
const user = { |
|||
firstName: 'Han', |
|||
lastName: 'Solo', |
|||
}; |
|||
|
|||
// good |
|||
const user = { |
|||
firstName: 'Han', |
|||
lastName: 'Solo' |
|||
}; |
|||
``` |
|||
|
|||
#### Strings |
|||
- Limit your lines to 80 characters. [max-len](http://eslint.org/docs/rules/max-len) |
|||
> Helps with readability and code reviews. |
|||
|
|||
```js |
|||
// bad |
|||
const user = { name: 'Han Solo', 'best-friend': 'Chewie', ship: 'Millennium Falcon', affiliation: 'Rebel Alliance' }; |
|||
|
|||
// good |
|||
const user = { |
|||
name: 'Han Solo', |
|||
'best-friend': 'Chewie', |
|||
ship: 'Millennium Falcon', |
|||
affiliation: 'Rebel Alliance' |
|||
}; |
|||
``` |
|||
|
|||
#### Variables |
|||
- Do not reference global variables. [no-undef](http://eslint.org/docs/rules/no-undef) |
|||
> Less globals, less headaches |
|||
|
|||
```js |
|||
// bad |
|||
$(window).on("scroll", doSomething); |
|||
|
|||
// good |
|||
import $ form "jquery"; |
|||
|
|||
$(wdinow).on("scroll", doSomething); |
|||
``` |
|||
|
|||
#### Comparison Operators & Equality |
|||
- Variables should always come before literal values in conditions. [yoda](http://eslint.org/docs/rules/yoda) |
|||
> More natural way to describe the comparison. |
|||
|
|||
```js |
|||
// bad |
|||
if ('Han' === firstName) { |
|||
// ... |
|||
} |
|||
|
|||
// good |
|||
if (firstName === 'Han') { |
|||
// ... |
|||
} |
|||
``` |
|||
|
|||
#### Whitespace |
|||
- Avoid leaving multiple empty lines between statements. [no-multiple-empty-lines](http://eslint.org/docs/rules/no-multiple-empty-lines) |
|||
> Consistent spacing across files |
|||
|
|||
```js |
|||
// bad |
|||
function someFunction() { |
|||
// ... |
|||
} |
|||
|
|||
|
|||
someFunction(); |
|||
|
|||
// good |
|||
function someFunction() { |
|||
// ... |
|||
} |
|||
|
|||
someFunction(); |
|||
``` |
|||
|
|||
#### JSX |
|||
- Always use double-quotes in jsx. [jsx-quotes](http://eslint.org/docs/rules/jsx-quotes) |
|||
> It's like html and clearly distinguishes HTML strings from JavaScript strings. |
|||
|
|||
```js |
|||
// bad |
|||
render(firstName) { |
|||
return ( |
|||
<div id='i-am'> |
|||
{`I'm ${firstName}!`} |
|||
</div> |
|||
); |
|||
} |
|||
|
|||
// good |
|||
render(firstName) { |
|||
return ( |
|||
<div id='i-am'> |
|||
{`I'm ${firstName}!`} |
|||
</div> |
|||
); |
|||
} |
|||
``` |
|||
|
|||
## Additional Guidelines |
|||
#### Objects |
|||
- Avoid Object mutations with Object.assign(). |
|||
|
|||
```js |
|||
// bad |
|||
const user = { |
|||
'name': 'Han Solo' |
|||
}; |
|||
user['best-friend'] = 'Chewie'; |
|||
|
|||
const user { |
|||
'name': 'Han Solo' |
|||
}; |
|||
|
|||
const userWithBestie = Object.assign({}, user, { |
|||
'best-friend': 'Chewie' |
|||
}); |
|||
``` |
|||
|
|||
#### Functions |
|||
- Only write 'Pure' functions |
|||
> They are predictable, testable and don't mutate the values passed to them. <br> |
|||
> Learn more about [Pure and Impure Functions](https://egghead.io/lessons/javascript-redux-pure-and-impure-functions). |
|||
|
|||
```js |
|||
// bad |
|||
function square(x) { |
|||
someSideEffect(x); |
|||
return x * x; |
|||
} |
|||
|
|||
// good |
|||
function square(x) { |
|||
return x * x; |
|||
} |
|||
``` |
|||
|
|||
- Always a strict mode directive at the beginning of a script/file. [strict](http://eslint.org/docs/rules/strict) |
|||
|
|||
```js |
|||
// bad |
|||
function someFunction() { |
|||
// ... |
|||
} |
|||
``` |
|||
|
|||
```js |
|||
'use strict'; |
|||
|
|||
function someFunction() { |
|||
// ... |
|||
} |
|||
``` |
|||
|
|||
#### Arrays |
|||
- Use Array#concat or spread to add items to an Array. |
|||
> Array#push is a [mutator method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype#Mutator_methods). <br> |
|||
> Learn more about [avoiding Array mutations](https://egghead.io/lessons/javascript-redux-avoiding-array-mutations-with-concat-slice-and-spread) |
|||
|
|||
```js |
|||
// bad |
|||
const range = [1]; |
|||
range.push(2); |
|||
|
|||
// good |
|||
const range = [1]; |
|||
const biggerRange = [].concat(range, [2]); |
|||
|
|||
// good es2015 |
|||
const range = [1]; |
|||
const biggerRange = [...range, 2]; |
|||
``` |
|||
|
|||
#### Blocks |
|||
- Always use braces and multiple lines for block statements |
|||
|
|||
```js |
|||
// bad |
|||
if (isValid) return console.log('Is valid'); |
|||
|
|||
// good |
|||
if (isValid) { |
|||
return console.log('Is valid'); |
|||
} |
|||
``` |
|||
|
|||
#### Comments |
|||
- Use `//` for single and multi-line comments |
|||
> Less thinking, more typing. |
|||
|
|||
```js |
|||
// bad |
|||
/* |
|||
This is a multiline |
|||
comment. |
|||
*/ |
|||
function someFunction() { |
|||
// ... |
|||
} |
|||
// good |
|||
|
|||
// This is a multiline |
|||
// comment. |
|||
function someFunction() { |
|||
// ... |
|||
} |
|||
``` |
|||
|
|||
## Naming Conventions |
|||
- Always use camelCase when naming variables |
|||
|
|||
```js |
|||
// bad |
|||
const first_name = 'Han Solo'; |
|||
|
|||
// good |
|||
const firstName = 'Han Solo'; |
|||
``` |
|||
|
|||
- Suffix Observable variables names with `$`. |
|||
|
|||
```js |
|||
const input = document.getElementById('input'); |
|||
|
|||
// bad |
|||
const keyup = Rx.Observable.fromEvent(input, 'keyup'); |
|||
|
|||
// good |
|||
const keyup$ = Rx.Observable.fromEvent(input, 'keyup'); |
|||
``` |
|||
|
|||
- Prefix boolean state variable names with `is` or `has`. |
|||
|
|||
```js |
|||
const photos = [1, 2]; |
|||
|
|||
// bad |
|||
const photos = !!photos.length; |
|||
|
|||
// good |
|||
const hasPhotos = !!photos.length; |
|||
|
|||
// bad |
|||
const visible = !!photos.length; |
|||
|
|||
// good |
|||
const isVisible = !!photos.length; |
|||
``` |
|||
|
|||
## References |
|||
#### ES2015 |
|||
- [Understanding ES6](https://github.com/nzakas/understandinges6) |
|||
|
|||
#### Arrays |
|||
- [Array#each](https://egghead.io/lessons/javascript-the-array-foreach-method) |
|||
- [Array#map](https://egghead.io/lessons/javascript-the-array-map-method) |
|||
- [Array#filter](https://egghead.io/lessons/javascript-the-array-filter-method) |
|||
|
|||
#### Functions |
|||
- [Function declaration hoisting](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/function#Function_declaration_hoisting) |
|||
|
|||
#### Coercion |
|||
- [JavaScript Coercion](http://webreflection.blogspot.ca/2010/10/javascript-coercion-demystified.html) |
|||
|
|||
#### Blocks |
|||
- [One True Brace Style](https://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS) |
|||
|
@ -0,0 +1,2 @@ |
|||
.DS_Store |
|||
node_modules |
@ -0,0 +1,20 @@ |
|||
{ |
|||
"extends": "airbnb", |
|||
"parserOptions": { |
|||
"ecmaVersion": 6, |
|||
"sourceType": "module", |
|||
"ecmaFeatures": { |
|||
"jsx": true |
|||
} |
|||
}, |
|||
"rules": { |
|||
"comma-dangle": [2, "never"], |
|||
"no-undef": 2, |
|||
"max-len": [2, 80, 2, { "ignoreUrls": true }], |
|||
"yoda": [2, "never"], |
|||
"no-multiple-empty-lines": [2, {"max": 1, "maxEOF": 1}], |
|||
"jsx-quotes": [2, "prefer-double"], |
|||
"no-console": 1, |
|||
"no-alert": 1 |
|||
} |
|||
} |
@ -0,0 +1 @@ |
|||
module.exports = require("./eslintrc.json"); |
@ -0,0 +1,33 @@ |
|||
{ |
|||
"name": "eslint-config-unsplash", |
|||
"version": "0.1.0", |
|||
"description": "Unsplash's ESLint Config", |
|||
"main": "index.js", |
|||
"scripts": { |
|||
"test": "eslint --config eslintrc.json test" |
|||
}, |
|||
"repository": { |
|||
"type": "git", |
|||
"url": "git+https://github.com/unsplash/javascript.git" |
|||
}, |
|||
"keywords": [ |
|||
"eslint", |
|||
"eslintconfig", |
|||
"config", |
|||
"unsplash", |
|||
"javascript", |
|||
"styleguide" |
|||
], |
|||
"author": "Naoufal Kadhom <naoufal@unsplash.com>", |
|||
"license": "MIT", |
|||
"bugs": { |
|||
"url": "https://github.com/unsplash/javascript/issues" |
|||
}, |
|||
"homepage": "https://github.com/unsplash/javascript#readme", |
|||
"dependencies": { |
|||
"eslint-config-airbnb": "^5.0.1" |
|||
}, |
|||
"devDependencies": { |
|||
"eslint": "^1.10.3" |
|||
} |
|||
} |
@ -0,0 +1,24 @@ |
|||
// Function spacing
|
|||
function foo({ name }) { |
|||
// Max line length 80
|
|||
const string = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' + |
|||
'Quid est, quod ab ea absolvi et perfici debeat? ' + |
|||
'Omnia contraria, quos etiam insanos esse vultis. ' + |
|||
'Mihi enim erit isdem istis fortasse iam utendum. ' + |
|||
'Duo Reges: constructio interrete.'; |
|||
|
|||
return string + name; |
|||
} |
|||
|
|||
// No trailing commas
|
|||
const user = { |
|||
name: 'Han Solo' |
|||
}; |
|||
|
|||
// No Yoda
|
|||
const isHan = user.name === 'Han Solo'; |
|||
if (isHan) { |
|||
foo(user); |
|||
} else { |
|||
foo('Someone else'); |
|||
} |
Loading…
Reference in new issue