Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

Commit

Permalink
feat: v1.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
grikomsn committed Feb 7, 2023
1 parent 9db30c0 commit a6ac355
Show file tree
Hide file tree
Showing 30 changed files with 974 additions and 825 deletions.
17 changes: 17 additions & 0 deletions .vscode/eslint.code-snippets
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"Base ESLint configuration": {
"scope": "javascript",
"prefix": "!",
"body": [
"// @ts-check",
"",
"/** @type {import(\"eslint\").Linter.Config} */",
"const config = {",
" $0",
"};",
"",
"module.exports = config;",
""
]
}
}
30 changes: 30 additions & 0 deletions README.core.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# @strangelovelabs/style-guide-core

![version](https://badgen.net/npm/v/@strangelovelabs/style-guide-core)
![downloads](https://badgen.net/npm/dt/@strangelovelabs/style-guide-core)
![license](https://badgen.net/npm/license/@strangelovelabs/style-guide-core)

ESLint and Prettier style guide for various personal projects, which includes configs for popular linting and styling tools. Heavily based on [Vercel's style guide](https://github.com/vercel/style-guide).

This is a trimmed down version of [@strangelovelabs/style-guide](https://github.com/strangelovelabs/style-guide) which [does not include packages listed here](./scripts/trim-core.js).

## Installing

```sh
# using npm
npm install --save-dev @strangelovelabs/style-guide-core

# using yarn
yarn add --dev @strangelovelabs/style-guide-core

# using pnpm
pnpm install --save-dev @strangelovelabs/style-guide-core
```

## Usage

Refer to the main readme at https://github.com/strangelovelabs/style-guide.

## License

[Mozilla Public License Version 2.0](./LICENSE.txt)
60 changes: 50 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@ npm install --save-dev @strangelovelabs/style-guide
yarn add --dev @strangelovelabs/style-guide

# using pnpm
pnpm add --dev @strangelovelabs/style-guide
pnpm install --save-dev @strangelovelabs/style-guide
```

Some of our ESLint configs require peer dependencies. We'll note those
alongside the available configs in the [ESLint](#eslint) section.

If you're not working with frontend related projects (React, Next.js, TailwindCSS), you can install [`@strangelovelabs/style-guide-core`](https://npm.im/@strangelovelabs/style-guide-core) which [does not include packages listed here](./scripts/trim-core.js).

## Prettier

> Note: Prettier is a peer-dependency of this package, and should be installed
Expand All @@ -49,17 +54,25 @@ To use the shared Prettier config, set the following in `package.json`.
>
> See: https://eslint.org/docs/user-guide/getting-started#installation-and-usage
This ESLint config is designed to be composable. The base configs,
`@strangelovelabs/style-guide/eslint/node` or `@strangelovelabs/style-guide/eslint/browser`, set
up a project for JavaScript and should always be first in `extends`.
This ESLint config is designed to be composable.

The following optional configs are available:
The following base configs are available. You can use one or both of these
configs, but they should always be first in `extends`:

- `@strangelovelabs/style-guide/eslint/browser`
- `@strangelovelabs/style-guide/eslint/node`

Note that you can scope configs, so that configs only target specific files.
For more information, see: [Scoped configuration with `overrides`](#scoped-configuration-with-overrides).

- `@strangelovelabs/style-guide/eslint/jest` (requires installing [`eslint-plugin-jest`](https://www.npmjs.com/package/eslint-plugin-jest) and [`eslint-plugin-testing-library`](https://www.npmjs.com/package/eslint-plugin-testing-library))
- `@strangelovelabs/style-guide/eslint/next` (requires `@strangelovelabs/style-guide/eslint/react`)
The following additional configs are available:

- `@strangelovelabs/style-guide/eslint/jest` (requires [`eslint-plugin-jest`](https://npm.im/eslint-plugin-jest) and [`eslint-plugin-testing-library`](https://npm.im/eslint-plugin-testing-library) to be installed)
- `@strangelovelabs/style-guide/eslint/next` (requires `@next/eslint-plugin-next` to be installed at the same version as `next`)
- `@strangelovelabs/style-guide/eslint/playwright-test` (requires [`eslint-plugin-playwright`](https://npm.im/eslint-plugin-playwright) to be installed)
- `@strangelovelabs/style-guide/eslint/react`
- `@strangelovelabs/style-guide/eslint/tailwindcss` (requires installing [`eslint-plugin-tailwindcss`](https://www.npmjs.com/package/eslint-plugin-tailwindcss))
- `@strangelovelabs/style-guide/eslint/typescript` (requires [additional configuration](#configuring-eslint-for-typescript))
- `@strangelovelabs/style-guide/eslint/tailwindcss` (requires [`tailwindcss`](https://npm.im/tailwindcss) to be installed)
- `@strangelovelabs/style-guide/eslint/typescript` (requires [`typescript`](https://npm.im/typescript) to be installed and [additional configuration](#configuring-eslint-for-typescript))

> You'll need to use `require.resolve` to provide ESLint with absolute paths,
> due to an issue around ESLint config resolution (see
Expand Down Expand Up @@ -109,6 +122,33 @@ module.exports = {
};
```

### Configuring custom components for `jsx-a11y`

It's common practice for React apps to have shared components like `Button`,
which wrap native elements. You can pass this information along to `jsx-a11y`
via the `components` setting.

The below list is not exhaustive.

```js
module.exports = {
root: true,
extends: [require.resolve("@vercel/style-guide/eslint/react")],
settings: {
"jsx-a11y": {
components: {
Article: "article",
Button: "button",
Image: "img",
Input: "input",
Link: "a",
Video: "video",
},
},
},
};
```

### Scoped configuration with `overrides`

ESLint configs can be scoped to include/exclude specific paths. This ensures
Expand Down Expand Up @@ -143,7 +183,7 @@ module.exports = {
{
files: ["directory/**/*.[jt]s?(x)"],
rules: {
"my-rule": "off",
"my-rule": ["off"],
},
},
],
Expand Down
5 changes: 5 additions & 0 deletions apply-patches
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

for patch in patches/*.patch; do
git apply "$patch"
done
2 changes: 1 addition & 1 deletion eslint/config-authoring.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const config = {
{
files: ["eslint/rules/**", "prettier/**"],
rules: {
"sort-keys": "error",
"sort-keys": ["error"],
},
},
],
Expand Down
3 changes: 2 additions & 1 deletion eslint/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

module.exports = {
JAVASCRIPT_FILES: ["*.js?(x)", "*.mjs", "*.cjs"],
TYPESCRIPT_FILES: ["*.d.ts", "*.ts?(x)"],
JEST_FILES: ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)"],
TYPESCRIPT_FILES: ["*.d.ts", "*.ts?(x)", "*.mts", "*.cts"],
TSUP_FILES: ["tsup.config?(.*).{ts,js,cjs,json}"],
};
13 changes: 12 additions & 1 deletion eslint/jest.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
// @ts-check

const { TYPESCRIPT_FILES } = require("./constants");

/** @type {import("eslint").Linter.Config} */
const config = {
extends: ["plugin:jest/recommended", "plugin:testing-library/react", require.resolve("./rules/jest")],
plugins: ["testing-library"],
extends: ["plugin:jest/recommended", "plugin:testing-library/react"],
overrides: [
{
files: TYPESCRIPT_FILES,
rules: {
"@typescript-eslint/unbound-method": ["off"],
"jest/unbound-method": ["error"],
},
},
],
};

module.exports = config;
9 changes: 4 additions & 5 deletions eslint/next.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// @ts-check

const { JAVASCRIPT_FILES } = require("./constants");
const { requirePackage } = require("./utils/package-manager");

requirePackage("next", "@next/eslint-plugin-next");

const babelOptions = {
presets: (() => {
Expand All @@ -15,11 +18,7 @@ const babelOptions = {

/** @type {import("eslint").Linter.Config} */
const config = {
extends: [
"plugin:@next/next/core-web-vitals",
require.resolve("./rules/next/import"),
require.resolve("./rules/next/jsx-a11y"),
],
extends: ["plugin:@next/next/recommended"],
overrides: [
{
files: JAVASCRIPT_FILES,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

/** @type {import("eslint").Linter.Config} */
const config = {
rules: {
"@typescript-eslint/no-unused-vars": ["off"],
},
extends: ["plugin:playwright/playwright-test", require.resolve("./rules/playwright-test.js")],
};

module.exports = config;
2 changes: 1 addition & 1 deletion eslint/react.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const config = {
"plugin:react-hooks/recommended",
"plugin:jsx-a11y/recommended",
"plugin:import/react",
"prettier",
"plugin:prettier/recommended",
require.resolve("./rules/react"),
require.resolve("./rules/jsx-a11y"),
],
Expand Down
1 change: 0 additions & 1 deletion eslint/rules/best-practice.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const config = {
"grouped-accessor-pairs": ["error"],
"no-alert": ["error"],
"no-caller": ["error"],
"no-constant-binary-expression": ["error"],
"no-constructor-return": ["error"],
"no-else-return": ["warn"],
"no-eval": ["error"],
Expand Down
12 changes: 12 additions & 0 deletions eslint/rules/jest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// @ts-check

/** @type {import("eslint").Linter.Config} */
const config = {
rules: {
"jest/no-duplicate-hooks": ["error"],
"jest/prefer-lowercase-title": ["warn"],
"jest/require-top-level-describe": ["error"],
},
};

module.exports = config;
16 changes: 0 additions & 16 deletions eslint/rules/next/import.js

This file was deleted.

13 changes: 0 additions & 13 deletions eslint/rules/next/jsx-a11y.js

This file was deleted.

1 change: 1 addition & 0 deletions eslint/rules/possible-errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const config = {
rules: {
"no-await-in-loop": ["error"],
"no-console": ["warn"],
"no-constant-binary-expression": ["warn"],
"no-promise-executor-return": ["error"],
"no-template-curly-in-string": ["error"],
"no-unreachable-loop": ["error"],
Expand Down
6 changes: 5 additions & 1 deletion eslint/rules/react.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ const config = {
rules: {
"react/button-has-type": ["warn"],
"react/function-component-definition": ["warn", { namedComponents: "arrow-function" }],
"react/hook-use-state": ["warn"],
"react/jsx-boolean-value": ["warn"],
"react/jsx-curly-brace-presence": ["warn"],
"react/jsx-fragments": ["warn"],
"react/jsx-no-leaked-render": ["warn"],
"react/jsx-no-target-blank": ["error", { allowReferrer: true }],
"react/jsx-no-useless-fragment": ["warn"],
"react/jsx-no-useless-fragment": ["warn", { allowExpressions: true }],
"react/jsx-pascal-case": ["warn"],
"react/jsx-sort-props": ["off"],
"react/no-array-index-key": ["warn"],
"react/no-unknown-property": ["off"],
"react/no-unstable-nested-components": ["error"],
"react/prop-types": ["off"],
"react/react-in-jsx-scope": ["off"],
"react/self-closing-comp": ["warn"],
Expand Down
28 changes: 2 additions & 26 deletions eslint/rules/typescript/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,21 @@
/** @type {import("eslint").Linter.Config} */
const config = {
rules: {
"@typescript-eslint/array-type": ["warn"],
"@typescript-eslint/consistent-indexed-object-style": ["warn"],
"@typescript-eslint/consistent-type-assertions": [
"error",
{ assertionStyle: "as", objectLiteralTypeAssertions: "allow-as-parameter" },
],
"@typescript-eslint/consistent-type-definitions": ["warn"],
"@typescript-eslint/consistent-type-exports": ["warn", { fixMixedExportsWithInlineTypeSpecifier: true }],
"@typescript-eslint/consistent-type-imports": ["warn"],
"@typescript-eslint/method-signature-style": ["warn"],
"@typescript-eslint/naming-convention": [
"error",
{ format: ["PascalCase"], selector: "typeLike" },
{ format: ["PascalCase"], selector: ["typeLike", "enumMember"] },
{
custom: { match: false, regex: "^I[A-Z]|^(Interface|Props|State)$" },
format: ["PascalCase"],
selector: "interface",
},
],
"@typescript-eslint/no-base-to-string": ["error"],
"@typescript-eslint/no-confusing-non-null-assertion": ["warn"],
"@typescript-eslint/no-duplicate-imports": ["error"],
"@typescript-eslint/no-explicit-any": ["warn"],
"@typescript-eslint/no-extraneous-class": ["error"],
"@typescript-eslint/no-invalid-void-type": ["error"],
"@typescript-eslint/no-meaningless-void-operator": ["error"],
"@typescript-eslint/no-unnecessary-boolean-literal-compare": ["warn"],
"@typescript-eslint/no-unnecessary-condition": ["warn"],
"@typescript-eslint/no-redundant-type-constituents": ["warn"],
"@typescript-eslint/no-unnecessary-qualifier": ["warn"],
"@typescript-eslint/no-unnecessary-type-arguments": ["warn"],
"@typescript-eslint/no-unsafe-assignment": ["warn"],
"@typescript-eslint/prefer-includes": ["warn"],
"@typescript-eslint/prefer-literal-enum-member": ["error"],
"@typescript-eslint/prefer-optional-chain": ["error"],
"@typescript-eslint/prefer-reduce-type-parameter": ["warn"],
"@typescript-eslint/prefer-regexp-exec": ["warn"],
"@typescript-eslint/prefer-string-starts-ends-with": ["warn"],
"@typescript-eslint/prefer-ts-expect-error": ["warn"],
"@typescript-eslint/restrict-template-expressions": ["off"],
"@typescript-eslint/switch-exhaustiveness-check": ["error"],
},
};
Expand Down
12 changes: 12 additions & 0 deletions eslint/rules/typescript/strict.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// @ts-check

/** @type {import("eslint").Linter.Config} */
const config = {
rules: {
"@typescript-eslint/explicit-function-return-type": ["off"],
"@typescript-eslint/prefer-nullish-coalescing": ["off"],
"@typescript-eslint/restrict-template-expressions": ["off"],
},
};

module.exports = config;
1 change: 1 addition & 0 deletions eslint/rules/unicorn.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const config = {
plugins: ["unicorn"],
rules: {
"unicorn/filename-case": ["error", { cases: { camelCase: true, kebabCase: true, pascalCase: true } }],
"unicorn/prefer-node-protocol": ["warn"],
},
};

Expand Down
1 change: 1 addition & 0 deletions eslint/tsup.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const config = {
files: TSUP_FILES,
rules: {
"import/no-default-export": ["off"],
"import/prefer-default-export": ["error"],
},
},
],
Expand Down
Loading

0 comments on commit a6ac355

Please sign in to comment.