Skip to content

Commit

Permalink
New: Use XO as baseline instead of Standard (#240)
Browse files Browse the repository at this point in the history
  • Loading branch information
stormwarning authored Feb 4, 2022
1 parent b4e0b30 commit 413dff9
Show file tree
Hide file tree
Showing 16 changed files with 3,511 additions and 1,092 deletions.
9 changes: 9 additions & 0 deletions .changeset/beige-dingos-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@zazen/eslint-config': major
---

Use XO instead of Standard as a baseline

Extends `eslint-config-xo` (and `eslint-config-xo-typescript`) rules, as well as the config for `import`, `promise`, and `node` plugins from the XO CLI.

Internal configs do not extend each other, in order to keep things flexible.
13 changes: 13 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
plugins: ['unicorn'],
extends: ['./index.js'],
parserOptions: {
sourceType: 'module',
},
env: {
node: true,
},
rules: {
'unicorn/prefer-module': 'off',
},
}
4 changes: 0 additions & 4 deletions .eslintrc.js

This file was deleted.

21 changes: 0 additions & 21 deletions .github/dependabot.yml

This file was deleted.

4 changes: 4 additions & 0 deletions .github/renovate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["github>tidaltheory/.github:renovate-config"]
}
30 changes: 30 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: CI

on: [push]

jobs:
test:
name: Node ${{ matrix.node }}

runs-on: ubuntu-latest
strategy:
matrix:
node: ['16.x']

steps:
# https://github.com/actions/checkout
- name: Checkout repo
uses: actions/checkout@v2

# https://github.com/actions/setup-node
- name: Setup Node ${{ matrix.node }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node }}

# https://github.com/bahmutov/npm-install
- name: Install dependencies
uses: bahmutov/npm-install@v1

- name: Test
run: npm test
26 changes: 14 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,28 @@ on:
jobs:
release:
name: Release

runs-on: ubuntu-latest

steps:
- name: Checkout Repo
uses: actions/checkout@master
with:
# This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
fetch-depth: 0
# https://github.com/actions/checkout
- name: Checkout repo
uses: actions/checkout@v2

- name: Setup Node.js 12.x
uses: actions/setup-node@master
# https://github.com/actions/setup-node
- name: Setup Node 16.x
uses: actions/setup-node@v2.1.5
with:
node-version: 12.x
node-version: 16.x

- name: Install Dependencies
run: npm ci
# https://github.com/bahmutov/npm-install
- name: Install dependencies
uses: bahmutov/npm-install@v1

# https://github.com/changesets/action
- name: Create Release Pull Request or Publish to npm
- name: Create release PR or publish to npm
id: changesets
uses: changesets/action@master
uses: changesets/action@v1
with:
# This expects you to have a script called release which does a build
# for your packages and calls changeset publish
Expand Down
36 changes: 30 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,47 @@ Add the Prettier settings to your `package.json`:
},
```

### Vue.js projects
### Node projects

Includes TypeScript rules as well. Install the optionalDependencies:
Extend the base config as well as the Node-specific rules:

```shell
npm install --save-dev @typescript-eslint/{eslint-plugin,parser} eslint-config-standard-with-typescript eslint-plugin-vue
```js
{
extends: ['@zazen', '@zazen/eslint-config/node'],
rules: { /**/ },
}
```

### TypeScript projects

Extend the base config as well as the TypeScript-specific rules:

```js
{
extends: ['@zazen', '@zazen/eslint-config/typescript'],
rules: { /**/ },
}
```

Extend the Vue-specific settings in `.eslintrc.js`:
This can be used for JavaScript code as well, but will require a `tsconfig.json` file to be present.

### Vue.js projects

Removed for now until/unless I get more opinionated about Vue code. For now, install `eslint-plugin-vue` per-project, and extend the recommended config in addition to the base config here.

```js
{
extends: ['@zazen/eslint-config/vue'],
extends: [
'plugin:vue/[vue3-]recommended',
'@zazen',
'plugin:prettier/recommended',
],
rules: { /**/ },
}
```

The TypeScript rules can be included as well, but remember to [set the `parser` option correctly](https://eslint.vuejs.org/user-guide/#what-is-the-use-the-latest-vue-eslint-parser-error).

[npm-url]: https://www.npmjs.com/package/@zazen/eslint-config
[npm-img]: https://img.shields.io/npm/v/@zazen/eslint-config.svg?style=flat-square
[npm-dls]: https://img.shields.io/npm/dt/@zazen/eslint-config.svg?style=flat-square
Expand Down
12 changes: 12 additions & 0 deletions __tests__/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "test-package",
"version": "0.0.0",
"type": "module",
"dependencies": {
"eslint": "8.8.0",
"is-plain-obj": "4.0.0"
},
"engines": {
"node": ">=16"
}
}
53 changes: 53 additions & 0 deletions __tests__/test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { createRequire } from 'node:module'

import test from 'ava'
import { ESLint } from 'eslint'
import isPlainObj from 'is-plain-obj'

const require = createRequire(import.meta.url)
const hasRule = (errors, ruleId) =>
errors.some((error) => error.ruleId === ruleId)

async function runEslint(string, config) {
let eslint = new ESLint({
useEslintrc: false,
overrideConfig: config,
})

let [firstResult] = await eslint.lintText(string)

return firstResult.messages
}

test('main', async (t) => {
let config = require('../index.js')

t.true(isPlainObj(config))
t.true(isPlainObj(config.rules))

let errors = await runEslint(
"'use strict';\nfunction q() { const foo = 'FOO' }\n",
config,
)
t.true(hasRule(errors, 'prefer-let/prefer-let'), JSON.stringify(errors))
})

test('node', async (t) => {
let config = require('../node.js')

t.true(isPlainObj(config))
t.true(isPlainObj(config.rules))

let errors = await runEslint(
"import path from 'path'\nimport foo from './utils/foo'\n",
{
parserOptions: { sourceType: 'module', ecmaVersion: 2020 },
...config,
},
)
/** @todo Figure out why this rule isn't being caught in tests. */
t.false(
hasRule(errors, 'n/file-extension-in-import'),
JSON.stringify(errors),
)
})
81 changes: 58 additions & 23 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use strict'

module.exports = {
root: true,
parserOptions: {
Expand All @@ -6,16 +8,24 @@ module.exports = {
sourceType: 'module',
},
env: {
browser: true,
es2021: true,
node: true,
},
reportUnusedDisableDirectives: true,
plugins: ['prefer-let'],
/**
* @see https://github.com/standard/eslint-config-standard
* @see https://github.com/xojs/eslint-config-xo
* @see https://github.com/sindresorhus/eslint-plugin-unicorn
* @see https://github.com/import-js/eslint-plugin-import
* @see https://github.com/xjamundx/eslint-plugin-promise
* @see https://github.com/prettier/eslint-plugin-prettier
*/
extends: ['standard', 'plugin:prettier/recommended'],
extends: [
'xo',
'plugin:unicorn/recommended',
'plugin:import/recommended',
'plugin:promise/recommended',
'plugin:prettier/recommended',
],
rules: {
'no-console': 'warn',

Expand All @@ -24,25 +34,50 @@ module.exports = {
*/
'prefer-const': 'off',
'prefer-let/prefer-let': 'error',
},
overrides: [
{
files: ['**/*.ts', '**/*.tsx'],
parser: '@typescript-eslint/parser',
extends: [
'standard-with-typescript',
'plugin:prettier/recommended',
],
rules: {
/**
* @see https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-unused-vars.md
*/
'no-unused-vars': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{ argsIgnorePattern: '^_', ignoreRestSiblings: true },

'unicorn/consistent-destructuring': 'off',
'unicorn/consistent-function-scoping': 'off',
/** https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/expiring-todo-comments.md */
'unicorn/expiring-todo-comments': ['warn', { terms: ['@todo'] }],
'unicorn/no-null': 'off',
'unicorn/no-useless-undefined': 'off',
'unicorn/prefer-ternary': ['error', 'only-single-line'],

'promise/param-names': 'error',
'promise/no-return-wrap': ['error', { allowReject: true }],
'promise/no-new-statics': 'error',
'promise/no-return-in-finally': 'error',
'promise/valid-params': 'error',
'promise/prefer-await-to-then': 'error',

'import/default': 'error',
'import/export': 'error',
'import/extensions': ['error', 'always', { ignorePackages: true }],
'import/first': 'error',
'import/named': 'error',
'import/namespace': ['error', { allowComputed: true }],
'import/newline-after-import': 'error',
'import/no-absolute-path': 'error',
'import/no-amd': 'error',
'import/no-anonymous-default-export': 'error',
'import/no-cycle': ['error', { ignoreExternal: true }],
'import/no-duplicates': 'error',
'import/no-extraneous-dependencies': [
'error',
{
devDependencies: [
'**/__tests__/**/*.{mjs,js,ts,tsx}',
'**/*.@(spec|test).{mjs,js,ts,tsx}',
],
},
},
],
],
'import/no-mutable-exports': 'error',
'import/no-named-as-default-member': 'error',
'import/no-named-as-default': 'error',
'import/no-named-default': 'error',
'import/no-self-import': 'error',
'import/no-unresolved': 'off',
'import/no-useless-path-segments': 'error',
'import/no-webpack-loader-syntax': 'error',
},
}
42 changes: 42 additions & 0 deletions node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
'use strict'

module.exports = {
plugins: ['n'],
/**
* @see https://github.com/weiran-zsd/eslint-plugin-node
*/
extends: ['plugin:prettier/recommended'],
rules: {
/**
* We have this enabled in addition to `import/extensions` as
* this one has an auto-fix.
*/
'n/file-extension-in-import': [
'error',
'always',
/**
* TypeScript doesn't yet support using extensions and
* fails with error TS2691.
*/
{ '.ts': 'never', '.tsx': 'never' },
],
'n/no-deprecated-api': 'error',
'n/no-missing-import': 'off',
'n/no-mixed-requires': ['error', { grouping: true, allowCall: true }],
'n/no-new-require': 'error',
'n/no-path-concat': 'error',
'n/no-unpublished-bin': 'error',
'n/no-unpublished-import': 'off',
'n/no-unpublished-require': 'off',
'n/prefer-global/buffer': ['error', 'never'],
'n/prefer-global/console': ['error', 'always'],
'n/prefer-global/process': ['error', 'never'],
'n/prefer-global/text-decoder': ['error', 'always'],
'n/prefer-global/text-encoder': ['error', 'always'],
'n/prefer-global/url-search-params': ['error', 'always'],
'n/prefer-global/url': ['error', 'always'],
'n/prefer-promises/dns': 'error',
'n/prefer-promises/fs': 'error',
'n/process-exit-as-throw': 'error',
},
}
Loading

0 comments on commit 413dff9

Please sign in to comment.