Setup eslint (#1168)

*  Install eslint deps
* 🔧 Setup eslint
* 🔧 Add `react.runtime=automatic` to flowconfig
* 🎨 Fix eslint issues
* 🎨 Fix flow issues
* 📸 Update snapshots
* 🙈 Update gitignore
This commit is contained in:
Carlos Cuesta 2022-10-30 19:20:25 +01:00 committed by GitHub
parent 0bb0b67372
commit 9fec13469a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 1244 additions and 65 deletions

View File

@ -10,5 +10,6 @@
[lints]
[options]
module.name_mapper='src\/\(.*\)$' -> '<PROJECT_ROOT>/src/\1'
exact_by_default=true
react.runtime=automatic

1
.gitignore vendored
View File

@ -7,6 +7,7 @@ out/
coverage/
public/robots.txt
public/sitemap.xml
.eslintcache
# next-pwa
public/workbox-*.js

View File

@ -14,7 +14,7 @@
"build": "next build",
"dev": "next dev",
"flow": "flow",
"lint": "prettier --check src/**/*.{js,json,css}",
"lint": "eslint src && prettier --check src/**/*.{js,json,css}",
"postbuild": "next-sitemap",
"start": "next start",
"test": "jest --coverage",
@ -23,8 +23,18 @@
"prepare": "husky install"
},
"devDependencies": {
"@babel/core": "^7.19.6",
"@babel/eslint-parser": "^7.19.1",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.18.6",
"clipboard": "^2.0.4",
"eslint": "^8.26.0",
"eslint-config-next": "^13.0.0",
"eslint-config-prettier": "^8.5.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-flowtype": "^8.0.3",
"eslint-plugin-jest": "^27.1.3",
"eslint-plugin-react": "^7.31.10",
"flow-bin": "^0.190.0",
"focus-trap-react": "^10.0.0",
"husky": "^8.0.0",
@ -71,6 +81,7 @@
},
"lint-staged": {
"*.{js,jsx}": [
"eslint --cache --fix",
"prettier --write src/**/*.{js,json,css}",
"git add"
]
@ -91,5 +102,79 @@
"volta": {
"node": "16.15.0"
},
"eslintConfig": {
"parser": "@babel/eslint-parser",
"env": {
"jest": true,
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:flowtype/recommended",
"plugin:react/recommended",
"prettier",
"plugin:@next/next/recommended"
],
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module",
"requireConfigFile": false,
"babelOptions": {
"presets": [
"next/babel",
"@babel/preset-react",
"@babel/preset-flow"
]
}
},
"plugins": [
"react",
"flowtype"
],
"rules": {
"flowtype/require-valid-file-annotation": [
2,
"always",
{
"annotationStyle": "line"
}
],
"react/react-in-jsx-scope": "off",
"@next/next/no-img-element": "off",
"react/no-unknown-property": ["error", { "ignore": ["jsx", "global"] }]
},
"overrides": [
{
"files": [
"*.spec.js",
"stubs.js",
"**/__mocks__/*.js"
],
"rules": {
"flowtype/require-valid-file-annotation": 0
}
}
],
"settings": {
"react": {
"version": "detect",
"flowVersion": "detect"
},
"import/resolver": {
"alias": {
"map": [
[
"src",
"./src"
]
]
}
}
}
},
"dependencies": {}
}

View File

@ -550,6 +550,7 @@ exports[`Pages Contributors should render the page 1`] = `
>
<a
href="https://github.com/profile"
rel="noreferrer"
target="_blank"
>
<img

View File

@ -22,7 +22,7 @@ jest.mock('next/router', () => ({
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
value: jest.fn().mockImplementation(() => ({
addListener: jest.fn(),
})),
})

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
import Icon from 'src/components/Icon'
import styles from './styles.module.css'

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
import styles from './styles.module.css'
@ -7,7 +7,7 @@ type Props = { avatar: string, url: string }
const Contributor = (props: Props): Element<'article'> => (
<article className="col-xs-3 col-sm-2">
<a href={props.url} target="_blank">
<a href={props.url} target="_blank" rel="noreferrer">
<img className={styles.picture} src={props.avatar} />
</a>
</article>

View File

@ -5,6 +5,7 @@ exports[`ContributorsList Contributor should render the component 1`] = `
className="col-xs-3 col-sm-2"
>
<a
rel="noreferrer"
target="_blank"
>
<img
@ -23,6 +24,7 @@ exports[`ContributorsList should render the component 1`] = `
>
<a
href="https://github.com/profile"
rel="noreferrer"
target="_blank"
>
<img

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
import Contributor from './Contributor'

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
import emojiColorsMap from '../emojiColorsMap'
import styles from './styles.module.css'

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
import Icon from 'src/components/Icon'
import styles from './styles.module.css'

View File

@ -1,10 +1,11 @@
import { useEffect, useState } from 'react'
// @flow
import { type Element, useEffect, useState } from 'react'
import { useTheme } from 'next-themes'
import Icon from 'src/components/Icon'
import styles from './styles.module.css'
const ThemeSelector = () => {
const ThemeSelector = (): Element<'div' | 'button'> => {
const [isMounted, setIsMounted] = useState(false)
const { resolvedTheme, setTheme } = useTheme()
const nextTheme = resolvedTheme === 'light' ? 'dark' : 'light'

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element, useEffect, useRef } from 'react'
import { type Element, useEffect, useRef } from 'react'
import ListModeSelector from './ListModeSelector'
import ThemeSelector from './ThemeSelector'

View File

@ -1,9 +1,9 @@
import React from 'react'
import renderer from 'react-test-renderer'
import useLocalStorage from '../useLocalStorage'
import * as stubs from './stubs'
// eslint-disable-next-line react/prop-types
const TestComponent = ({ storageKey, storageValue }) => {
useLocalStorage(storageKey, storageValue)

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
export const IconDefinitions = (): Element<'svg'> => (
<svg

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
export { IconDefinitions } from './definitions'
import styles from './styles.module.css'

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
import Link from 'next/link'
import Icon from 'src/components/Icon'

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
const CloseIcon = (): Element<'svg'> => (
<svg

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Node, type Element } from 'react'
import { type Node, type Element } from 'react'
import Link from 'next/link'
import { useRouter } from 'next/router'

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
const OpenIcon = (): Element<'svg'> => (
<svg

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
export const Joy = (): Element<'g'> => (
<g id="joy" transform="translate(304 32)">

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
export const Loved = (): Element<'g'> => (
<g id="loved" transform="translate(304 32)">

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
export const Sexy = (): Element<'g'> => (
<g id="sexy" transform="translate(304 32)">

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
export const Smiling = (): Element<'g'> => (
<g id="haha" transform="translate(304 32)">

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
export const Sunglasses = (): Element<'g'> => (
<g id="sunglasses" transform="translate(304 32)">

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
export const Tongue = (): Element<'g'> => (
<g id="tongue" transform="translate(304 32)">

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Node } from 'react'
import { type Node } from 'react'
import Joy from './Joy'
import Loved from './Loved'

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Node, type Element } from 'react'
import React, { type Element } from 'react'
import Status, { LOGO_STATUSES } from './Status'
import styles from './styles.module.css'

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Element } from 'react'
import { type Element } from 'react'
import Button from 'src/components/Button'
import Logo from './Logo'

View File

@ -1,8 +1,8 @@
// @flow
import React, { type Node } from 'react'
import { type Node } from 'react'
import Head from 'next/head'
type Props = { pageTitle?: string, pageUrl: string }
type Props = { pageTitle?: string, pageUrl?: string }
const SEO = (props: Props): Node => (
<Head>

View File

@ -3,7 +3,7 @@ import React, { type Node } from 'react'
import { ThemeProvider } from 'next-themes'
import Layout from 'src/components/Layout'
import theme from 'src/utils/theme/theme.css'
import 'src/utils/theme/theme.css'
type Props = { Component: typeof React.Component, pageProps: Object }

View File

@ -1,5 +1,5 @@
// @flow
import React, { type Node } from 'react'
import { type Node } from 'react'
import Document, { Html, Head, Main, NextScript } from 'next/document'
class CustomDocument extends Document {

View File

@ -1,11 +1,12 @@
import React from 'react'
// @flow
import { type Node } from 'react'
import Link from 'next/link'
import CarbonAd from 'src/components/CarbonAd'
import Button from 'src/components/Button'
import SEO from 'src/components/SEO'
const About = () => (
const About = (): Node => (
<>
<SEO pageTitle="About" pageUrl="/about" />
<main>
@ -16,7 +17,7 @@ const About = () => (
<p>
<strong>Gitmoji is an emoji guide for GitHub commit messages</strong>.
Aims to be a standarization cheatsheet - guide for using{' '}
<a href="https://emoji.muan.co">emojis</a> on GitHub's commit
<a href="https://emoji.muan.co">emojis</a> on GitHub&#39;s commit
messages.
</p>
@ -77,7 +78,7 @@ const About = () => (
<p>
In case you need some ideas to integrate gitmoji in your project,
here's a practical way to use it:
here&#39;s a practical way to use it:
</p>
<ul>

View File

@ -1,4 +1,5 @@
import React from 'react'
// @flow
import { type Node } from 'react'
import ContributorsList from 'src/components/ContributorsList'
import CarbonAd from 'src/components/CarbonAd'
@ -8,7 +9,7 @@ type Props = {
contributors: Array<{ avatar: string, url: string, id: string }>,
}
const Contributors = (props: Props) => (
const Contributors = (props: Props): Node => (
<>
<SEO pageTitle="Contributors" pageUrl="/contributors" />
@ -23,7 +24,10 @@ const Contributors = (props: Props) => (
</>
)
export const getStaticProps = async (): Promise<Props> => {
export const getStaticProps = async (): Promise<{
props: Props,
revalidate: number,
}> => {
const response = await fetch(
'https://api.github.com/repos/carloscuesta/gitmoji/contributors'
)

View File

@ -1,12 +1,12 @@
import React from 'react'
import Head from 'next/head'
// @flow
import { type Node } from 'react'
import gitmojis from 'src/data/gitmojis.json'
import GitmojiList from 'src/components/GitmojiList'
import CarbonAd from 'src/components/CarbonAd'
import SEO from 'src/components/SEO'
const Home = () => (
const Home = (): Node => (
<>
<SEO />
<main>

View File

@ -1,7 +1,7 @@
import React from 'react'
// @flow
import { type Node } from 'react'
import CarbonAd from 'src/components/CarbonAd'
import Button from 'src/components/Button'
import SEO from 'src/components/SEO'
const tools: Array<{ name: string, description: string, link: string }> = [
@ -79,7 +79,7 @@ const tools: Array<{ name: string, description: string, link: string }> = [
},
]
const RelatedTools = () => (
const RelatedTools = (): Node => (
<>
<SEO pageTitle="Related tools" pageUrl="/related-tools" />
<main>

1123
yarn.lock

File diff suppressed because it is too large Load Diff