Skip to content

Commit aa3c068

Browse files
committed
feat(lint): add prettier and eslint
1 parent f1da409 commit aa3c068

File tree

18 files changed

+283
-83
lines changed

18 files changed

+283
-83
lines changed

.eslintrc.json

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"plugins": ["prettier"],
3+
"parser": "babel-eslint",
4+
"parserOptions": {
5+
"ecmaVersion": 2019,
6+
"sourceType": "module"
7+
},
8+
"extends": ["airbnb"],
9+
"env": {
10+
"browser": true,
11+
"jest": true
12+
},
13+
"rules": {
14+
"import/first": 0,
15+
"import/prefer-default-export": 0,
16+
"import/no-extraneous-dependencies": 0,
17+
"object-curly-newline": ["error", { "consistent": true }],
18+
"no-return-assign": 0,
19+
"no-underscore-dangle": 0,
20+
"react/jsx-filename-extension": 0,
21+
"react/prefer-stateless-function": 0,
22+
"react/forbid-prop-types": 0,
23+
"react/destructuring-assignment": 0,
24+
"react/state-in-constructor": 0,
25+
"react/button-has-type": 0,
26+
"react/jsx-one-expression-per-line": 0,
27+
"jsx-a11y/label-has-associated-control": 0,
28+
"jsx-a11y/click-events-have-key-events": 0,
29+
"jsx-a11y/control-has-associated-label": 0,
30+
"jsx-a11y/no-noninteractive-element-interactions": 0,
31+
"jsx-a11y/anchor-is-valid": 0,
32+
"max-len": ["error", { "code": 120 }],
33+
"comma-dangle": ["error", "never"],
34+
"arrow-parens": ["error", "as-needed"]
35+
}
36+
}

.prettierrc

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"bracketSpacing": true,
3+
"trailingComma": "none",
4+
"singleQuote": true,
5+
"semi": true,
6+
"useTabs": false,
7+
"tabWidth": 2,
8+
"arrowParens": "avoid",
9+
"endOfLine": "lf",
10+
"printWidth": 120
11+
}

README.md

+12
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ The well-known TodoMVC built with React Hooks and Redux in a structured and test
1919
- [PropTypes](https://github.com/facebook/prop-types)
2020
- [Classnames](https://github.com/JedWatson/classnames)
2121

22+
## Usage
23+
24+
After installing the dependencies the following NPM scripts become available:
25+
26+
- `start`: starts the application in development mode on [http://localhost:9300](http://localhost:9300)
27+
- `build`: bundles the application for production into the `build` folder
28+
- `test`: runs unit and E2E tests
29+
- `test:unit`: runs unit tests with [Jest](https://jestjs.io/) in the `src` folder suffixed with `*.spec.js`
30+
- `test:e2e`: runs E2E tests with [Cypress](https://www.cypress.io/) in the `tests/e2e` folder suffixed with `*.spec.js`
31+
- `format`: formats the code with [Prettier](https://prettier.io/) within the `src` folder
32+
- `lint`: lint files with [ESLint](https://eslint.org/) based on [Airbnb's styleguide](https://github.com/airbnb/javascript) and the Prettier config
33+
2234
## Component architecture
2335

2436
![Architecture](./images/architecture.png)

package-lock.json

+160-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
"scripts": {
99
"start": "PORT=9300 BROWSER=none react-scripts start",
1010
"build": "CI=false react-scripts build",
11+
"format": "prettier --write 'src/**/*.{js,jsx}'",
12+
"lint": "eslint 'src/**/*.{js,jsx}'",
1113
"test": "npm run test:unit",
1214
"test:unit": "react-scripts test --watchAll=false",
1315
"test:e2e": "start-server-and-test start http://localhost:9300 cypress",
@@ -30,8 +32,16 @@
3032
"@testing-library/jest-dom": "^5.3.0",
3133
"@testing-library/react": "^10.0.2",
3234
"cypress": "^4.3.0",
35+
"eslint": "^6.8.0",
36+
"eslint-config-airbnb": "^18.1.0",
37+
"eslint-plugin-import": "^2.20.2",
38+
"eslint-plugin-jsx-a11y": "^6.2.3",
39+
"eslint-plugin-prettier": "^3.1.2",
40+
"eslint-plugin-react": "^7.19.0",
41+
"eslint-plugin-react-hooks": "^3.0.0",
3342
"history": "^4.10.1",
3443
"jest-extended": "^0.11.5",
44+
"prettier": "^2.0.4",
3545
"react-scripts": "^3.4.1",
3646
"start-server-and-test": "^1.10.11"
3747
},

src/components/app/app.js

+3-11
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@ export function App() {
1212
const todos = useSelector(state => state.todos);
1313

1414
useEffect(() => {
15-
dispatch(
16-
onLoad(TodoLocal.loadTodos())
17-
);
15+
dispatch(onLoad(TodoLocal.loadTodos()));
1816
}, [dispatch]);
1917

2018
useEffect(() => {
@@ -25,14 +23,8 @@ export function App() {
2523
<div id="app">
2624
<section className="todoapp">
2725
<Header />
28-
{
29-
!!todos.length &&
30-
<List />
31-
}
32-
{
33-
!!todos.length &&
34-
<Footer />
35-
}
26+
{!!todos.length && <List />}
27+
{!!todos.length && <Footer />}
3628
</section>
3729
<CopyRight />
3830
</div>

src/components/copy-right/copy-right.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ export function CopyRight() {
44
return (
55
<footer className="info">
66
<p data-testid="instruction">Double-click to edit a todo</p>
7-
<p>Created by <a href="http://github.com/blacksonic/">blacksonic</a></p>
8-
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
7+
<p>
8+
Created by <a href="http://github.com/blacksonic/">blacksonic</a>
9+
</p>
10+
<p>
11+
Part of <a href="http://todomvc.com">TodoMVC</a>
12+
</p>
913
</footer>
1014
);
1115
}

src/components/footer/footer.js

+12-8
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,18 @@ export function Footer() {
1717
const itemsLeft = useSelector(state => selectNotCompleted(state.todos).length);
1818
const filter = useSelector(state => state.filter);
1919
const clearCompleted = () => dispatch(onClearCompleted());
20-
const filterSelect = filter => dispatch(onFilterSelect(filter));
20+
const filterSelect = selectedFilter => dispatch(onFilterSelect(selectedFilter));
2121

2222
const itemText = itemsLeft === 1 ? 'item' : 'items';
2323

2424
return (
2525
<footer className="footer">
26-
<span className="todo-count"><strong>{itemsLeft}</strong><span> {itemText} left</span></span>
26+
<span className="todo-count">
27+
<strong>{itemsLeft}</strong>
28+
<span> {itemText} left</span>
29+
</span>
2730
<ul className="filters">
28-
{filterTitles.map(filterTitle =>
31+
{filterTitles.map(filterTitle => (
2932
<li key={filterTitle.key}>
3033
<a
3134
href="#"
@@ -35,12 +38,13 @@ export function Footer() {
3538
{filterTitle.value}
3639
</a>
3740
</li>
38-
)}
41+
))}
3942
</ul>
40-
{
41-
!!completedCount &&
42-
<button className="clear-completed" onClick={clearCompleted}>Clear completed</button>
43-
}
43+
{!!completedCount && (
44+
<button className="clear-completed" onClick={clearCompleted}>
45+
Clear completed
46+
</button>
47+
)}
4448
</footer>
4549
);
4650
}

0 commit comments

Comments
 (0)