Skip to content

Commit

Permalink
chore: Add linter for typescript code (#45)
Browse files Browse the repository at this point in the history
- Add and configure `eslint`
- Add to build pipeline
- Fix lint failures
  • Loading branch information
bryphe-coder committed Jan 21, 2022
1 parent 2654a93 commit 7b9347b
Show file tree
Hide file tree
Showing 13 changed files with 1,332 additions and 36 deletions.
122 changes: 122 additions & 0 deletions .eslintrc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
env:
browser: true
commonjs: true
es6: true
jest: true
node: true
extends:
- eslint:recommended
- plugin:@typescript-eslint/recommended
- plugin:import/recommended
- plugin:import/typescript
- plugin:react/recommended
- plugin:jsx-a11y/strict
- plugin:compat/recommended
- prettier
parser: "@typescript-eslint/parser"
parserOptions:
ecmaVersion: 2018
project:
- "./tsconfig.json"
- "./site/tsconfig.json"
sourceType: module
ecmaFeatures:
jsx: true
tsconfigRootDir: "./"
plugins:
- "@typescript-eslint"
- import
- react-hooks
- jest
- no-storage
root: true
rules:
"@typescript-eslint/brace-style":
["error", "1tbs", { "allowSingleLine": false }]
"@typescript-eslint/camelcase": "off"
"@typescript-eslint/explicit-function-return-type": "off"
"@typescript-eslint/explicit-module-boundary-types": "error"
"@typescript-eslint/method-signature-style": ["error", "property"]
"@typescript-eslint/no-invalid-void-type": error
# We're disabling the `no-namespace` rule to use a pattern of defining an interface,
# and then defining functions that operate on that data via namespace. This is helpful for
# dealing with immutable objects. This is a common pattern that shows up in some other
# large TypeScript projects, like VSCode.
# More details: https://github.com/coder/m/pull/9720#discussion_r697609528
"@typescript-eslint/no-namespace": "off"
"@typescript-eslint/no-unnecessary-boolean-literal-compare": error
"@typescript-eslint/no-unnecessary-condition": warn
"@typescript-eslint/no-unnecessary-type-assertion": warn
"@typescript-eslint/no-unused-vars":
- error
- argsIgnorePattern: "^_"
varsIgnorePattern: "^_"
"@typescript-eslint/no-use-before-define": "off"
"@typescript-eslint/object-curly-spacing": ["error", "always"]
"@typescript-eslint/triple-slash-reference": "off"
"brace-style": "off"
"curly": ["error", "all"]
eqeqeq: error
import/default: "off"
import/namespace: "off"
import/newline-after-import:
- error
- count: 1
import/no-named-as-default: "off"
import/no-named-as-default-member: "off"
import/prefer-default-export: "off"
jest/no-focused-tests: "error"
jsx-a11y/label-has-for: "off"
jsx-a11y/no-autofocus: "off"
no-console:
- warn
- allow:
- warn
- error
- info
- debug
no-dupe-class-members: "off"
no-restricted-imports:
- error
- paths:
- name: "@material-ui/core"
message:
"Use path imports to avoid pulling in unused modules. See:
https://material-ui.com/guides/minimizing-bundle-size/"
- name: "@material-ui/icons"
message:
"Use path imports to avoid pulling in unused modules. See:
https://material-ui.com/guides/minimizing-bundle-size/"
- name: "@material-ui/styles"
message:
"Use path imports to avoid pulling in unused modules. See:
https://material-ui.com/guides/minimizing-bundle-size/"
- name: "@material-ui/core/Tooltip"
message: "Use the custom Tooltip on componens/Tooltip"
no-storage/no-browser-storage: error
no-unused-vars: "off"
"object-curly-spacing": "off"
react-hooks/exhaustive-deps: warn
react-hooks/rules-of-hooks: error
react/jsx-no-script-url:
- error
- - name: Link
props:
- to
- name: Button
props:
- href
- name: IconButton
props:
- href
react/prop-types: "off"
react/jsx-boolean-value: ["error", "never"]
react/jsx-curly-brace-presence:
- error
- children: ignore
settings:
react:
version: detect
import/resolver:
typescript: {}
22 changes: 22 additions & 0 deletions .github/workflows/coder.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,28 @@ jobs:
with:
version: latest

style-lint-typescript:
name: "style/lint/typescript"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Cache Node
id: cache-node
uses: actions/cache@v2
with:
path: |
**/node_modules
.eslintcache
key: js-${{ runner.os }}-test-${{ hashFiles('**/yarn.lock') }}

- name: Install node_modules
run: yarn install

- name: "yarn lint"
run: yarn lint

gen:
name: "style/gen"
runs-on: ubuntu-latest
Expand Down
13 changes: 13 additions & 0 deletions jest-runner.eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Toggle eslint --fix by specifying the `FIX` env.
const fix = !!process.env.FIX

module.exports = {
cliOptions: {
ext: [".js", ".ts", ".tsx"],
ignorePath: ".eslintignore",
cache: false,
fix,
resolvePluginsRelativeTo: ".",
maxWarnings: 0,
},
}
6 changes: 6 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ module.exports = {
testPathIgnorePatterns: ["/node_modules/", "/__tests__/fakes"],
moduleDirectories: ["node_modules", "<rootDir>"],
},
{
displayName: "lint",
runner: "jest-runner-eslint",
testMatch: ["<rootDir>/site/**/*.js", "<rootDir>/site/**/*.ts", "<rootDir>/site/**/*.tsx"],
testPathIgnorePatterns: ["/.next/", "/out/"],
},
],
collectCoverageFrom: [
"<rootDir>/site/**/*.js",
Expand Down
16 changes: 16 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
"export": "next export site",
"format:check": "prettier --check '**/*.{css,html,js,json,jsx,md,ts,tsx,yaml,yml}'",
"format:write": "prettier --write '**/*.{css,html,js,json,jsx,md,ts,tsx,yaml,yml}' && sql-formatter -l postgresql ./database/query.sql -o ./database/query.sql",
"lint": "jest --selectProjects lint",
"lint:fix": "FIX=true yarn lint",
"test": "jest --selectProjects test",
"test:coverage": "jest --selectProjects test --collectCoverage"
},
Expand All @@ -24,9 +26,23 @@
"@types/react": "17.0.38",
"@types/react-dom": "17.0.11",
"@types/superagent": "4.1.14",
"@typescript-eslint/eslint-plugin": "4.33.0",
"@typescript-eslint/parser": "4.33.0",
"eslint": "7.32.0",
"eslint-config-prettier": "8.3.0",
"eslint-import-resolver-alias": "1.1.2",
"eslint-import-resolver-typescript": "2.5.0",
"eslint-plugin-compat": "4.0.1",
"eslint-plugin-import": "2.25.4",
"eslint-plugin-jest": "25.7.0",
"eslint-plugin-jsx-a11y": "6.5.1",
"eslint-plugin-no-storage": "1.0.2",
"eslint-plugin-react": "7.28.0",
"eslint-plugin-react-hooks": "4.3.0",
"express": "4.17.2",
"http-proxy-middleware": "2.0.1",
"jest": "27.4.7",
"jest-runner-eslint": "1.0.0",
"next": "12.0.7",
"prettier": "2.5.1",
"react": "17.0.2",
Expand Down
2 changes: 1 addition & 1 deletion site/components/EmptyState/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { screen } from "@testing-library/react"
import { render } from "../../test_helpers"
import React from "react"
import { EmptyState, EmptyStateProps } from "./index"
import { EmptyState } from "./index"

describe("EmptyState", () => {
it("renders (smoke test)", async () => {
Expand Down
4 changes: 2 additions & 2 deletions site/components/Icons/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React from "react"
import { SvgIcon } from "@material-ui/core"
import SvgIcon from "@material-ui/core/SvgIcon"
import { render } from "./../../test_helpers"

import * as Icons from "./index"

const getAllIcons = (): [string, typeof SvgIcon][] => {
let k: keyof typeof Icons
let ret: [string, typeof SvgIcon][] = []
const ret: [string, typeof SvgIcon][] = []
for (k in Icons) {
ret.push([k, Icons[k]])
}
Expand Down
4 changes: 3 additions & 1 deletion site/components/Navbar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from "react"
import Button from "@material-ui/core/Button"
import List from "@material-ui/core/List"
import ListSubheader from "@material-ui/core/ListSubheader"
import { makeStyles } from "@material-ui/core/styles"
import { Button, List, ListSubheader } from "@material-ui/core"

import Link from "next/link"

Expand Down
2 changes: 1 addition & 1 deletion site/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module.exports = {
// Allows us to import TS files from outside product/coder/site.
externalDir: true,
},
webpack: (config, { dev, isServer, webpack }) => {
webpack: (config, { isServer, webpack }) => {
// Inject CODERD_HOST environment variable for clients
if (!isServer) {
config.plugins.push(
Expand Down
5 changes: 2 additions & 3 deletions site/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React from "react"

import CssBaseline from "@material-ui/core/CssBaseline"
import { makeStyles } from "@material-ui/core/styles"
import ThemeProvider from "@material-ui/styles/ThemeProvider"

import { dark } from "../theme"
import { AppProps } from "next/app"
import { makeStyles } from "@material-ui/core"
import { Navbar } from "../components/Navbar"
import { Footer } from "../components/Page"

Expand Down Expand Up @@ -64,7 +63,7 @@ const MyApp: React.FC<AppProps> = (appProps) => {
)
}

const useStyles = makeStyles((theme) => ({
const useStyles = makeStyles(() => ({
root: {
display: "flex",
flexDirection: "column",
Expand Down
6 changes: 4 additions & 2 deletions site/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from "react"
import { makeStyles, Box, Paper } from "@material-ui/core"
import { AddToQueue as AddWorkspaceIcon } from "@material-ui/icons"
import Box from "@material-ui/core/Box"
import { makeStyles } from "@material-ui/core/styles"
import Paper from "@material-ui/core/Paper"
import AddWorkspaceIcon from "@material-ui/icons/AddToQueue"

import { EmptyState, SplitButton } from "../components"

Expand Down
3 changes: 0 additions & 3 deletions site/theme/theme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ import { CustomPalette, darkPalette, lightPalette } from "./palettes"
import { typography } from "./typography"

const makeTheme = (palette: CustomPalette) => {
// Grab defaults to re-use in overrides
const { breakpoints } = createMuiTheme()

return createMuiTheme({
palette,
typography,
Expand Down

0 comments on commit 7b9347b

Please sign in to comment.