Skip to content

Commit

Permalink
New: TS by default support 💖 (#243)
Browse files Browse the repository at this point in the history
Updates Eloquence to support TypeScript out of the box, with the option to disable when necessary.

BREAKING CHANGE: Use `enableTS` and `enableESM` to disable TypeScript and ESModule configs when
necessary.
  • Loading branch information
DHedgecock committed Sep 12, 2020
1 parent 7c4af19 commit 7ade772
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 87 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.js
@@ -1,4 +1,5 @@
'use strict'

const eloquence = require('./src/index')
module.exports = eloquence({ target: 'node', esm: false })

module.exports = eloquence({ target: 'node', enableESM: false, enableTS: false })
73 changes: 36 additions & 37 deletions src/__snapshots__/index.spec.js.snap
Expand Up @@ -11,7 +11,11 @@ Object {
"prettier",
"plugin:node/recommended",
],
"ignorePatterns": Array [],
"ignorePatterns": Array [
"!.*",
"public/*",
"dist/*",
],
"overrides": Array [
Object {
"files": Array [
Expand Down Expand Up @@ -41,9 +45,6 @@ Object {
"project": "./tsconfig.json",
"sourceType": "module",
},
"plugins": Array [
"@typescript-eslint",
],
"rules": Object {
"@typescript-eslint/adjacent-overload-signatures": "error",
"@typescript-eslint/ban-ts-comment": Array [
Expand Down Expand Up @@ -113,19 +114,6 @@ Object {
"prefer-spread": "error",
"valid-typeof": "off",
},
"settings": Object {
"import/external-module-folders": Array [
"node_modules",
"node_modules/@types",
],
"import/parsers": Object {
"@typescript-eslint/parser": Array [
".ts",
".tsx",
".d.ts",
],
},
},
},
Object {
"env": Object {
Expand Down Expand Up @@ -180,10 +168,11 @@ Object {
"ecmaFeatures": Object {
"jsx": true,
},
"ecmaVersion": 11,
"ecmaVersion": 12,
"sourceType": "module",
},
"plugins": Array [
"@typescript-eslint",
"import",
"prettier",
"node",
Expand Down Expand Up @@ -1014,7 +1003,18 @@ Object {
".tsx",
".d.ts",
],
"import/external-module-folders": Array [
"node_modules",
"node_modules/@types",
],
"import/internal-regex": /\\^@\\\\//,
"import/parsers": Object {
"@typescript-eslint/parser": Array [
".ts",
".tsx",
".d.ts",
],
},
"import/resolver": "/mock/test/path",
"react": Object {
"linkComponents": Array [
Expand All @@ -1039,9 +1039,12 @@ Object {
},
"extends": Array [
"prettier",
"prettier/react",
],
"ignorePatterns": Array [],
"ignorePatterns": Array [
"!.*",
"public/*",
"dist/*",
],
"overrides": Array [
Object {
"files": Array [
Expand Down Expand Up @@ -1069,9 +1072,6 @@ Object {
"project": "./tsconfig.json",
"sourceType": "module",
},
"plugins": Array [
"@typescript-eslint",
],
"rules": Object {
"@typescript-eslint/adjacent-overload-signatures": "error",
"@typescript-eslint/ban-ts-comment": Array [
Expand Down Expand Up @@ -1141,19 +1141,6 @@ Object {
"prefer-spread": "error",
"valid-typeof": "off",
},
"settings": Object {
"import/external-module-folders": Array [
"node_modules",
"node_modules/@types",
],
"import/parsers": Object {
"@typescript-eslint/parser": Array [
".ts",
".tsx",
".d.ts",
],
},
},
},
Object {
"env": Object {
Expand Down Expand Up @@ -1208,10 +1195,11 @@ Object {
"ecmaFeatures": Object {
"jsx": true,
},
"ecmaVersion": 11,
"ecmaVersion": 12,
"sourceType": "module",
},
"plugins": Array [
"@typescript-eslint",
"import",
"prettier",
"jest-dom",
Expand Down Expand Up @@ -2463,7 +2451,18 @@ Object {
".tsx",
".d.ts",
],
"import/external-module-folders": Array [
"node_modules",
"node_modules/@types",
],
"import/internal-regex": /\\^@\\\\//,
"import/parsers": Object {
"@typescript-eslint/parser": Array [
".ts",
".tsx",
".d.ts",
],
},
"import/resolver": "/mock/test/path",
"react": Object {
"linkComponents": Array [
Expand Down
87 changes: 54 additions & 33 deletions src/index.js
@@ -1,10 +1,12 @@
/** Eloquence ESLint
* -----------------------------------------------------------------------------
*
* ## ℹ️ Notes
* ℹ️ Package notes
*
* ESModules: Package defaults to using ESM for ESLint `sourceType`
* configuration, with overrides for Node executed tooling like Jest. Node ESM
* using cjs and mjs file extensions not yet handled.
*
* @module
*/

Expand Down Expand Up @@ -60,11 +62,11 @@ const targetConfigs = {
},
// --- REACT TARGET CONFIGS
react: {
extends: ['prettier/react'],
extends: [],
plugins: ['jest-dom', 'jsx-a11y', 'react', 'react-hooks', 'testing-library'],
rules: {
...pluginJestDom,
...pluginReact,
...pluginJestDom,
...pluginReactA11y,
...pluginReactHooks,
...pluginTestingLibrary,
Expand All @@ -77,43 +79,48 @@ const targetConfigs = {
/**
* Eloquence ESLint configs generator
* @param {Object} opts
* @param {boolean} [opts.esm]
* @param {boolean} [opts.enableESM] Enables ESModule linting features
* @param {boolean} [opts.enableTS] Enables TypeScript linting features
* @param {string[]} [opts.ignorePatterns] Array of paths that will be ignored
* @param {{[key: string]: unknown}} [opts.rules]
* @param {'node'|'react'} opts.target
*/
module.exports = function eloquence({
esm = true,
ignorePatterns = [],
enableESM = true,
enableTS = true,
ignorePatterns,
rules = {},
target,
}) {
const sourceType = esm ? 'module' : 'script'

return {
const baseConfigs = {
// Default expectation is a single config at root of project, with overrides
// for directory and file customizations
root: true,

ignorePatterns,
// Project custom ignore patterns, defaults to ignoring build directories
// and forcing linting of dot files and directories
ignorePatterns: ignorePatterns || ['!.*', 'public/*', 'dist/*'],

extends: ['prettier', ...targetConfigs[target].extends],

// Override Espree parser with Babel
parser: 'babel-eslint',

// Default parser to latest ECMA version and ESModules with the goal of
// Set parser to Babel using latest ECMA version and ESModules with the goal of
// staying as close to current syntax as possible
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 11,
sourceType,
ecmaVersion: 12,
sourceType: enableESM ? 'module' : 'script',
ecmaFeatures: {
jsx: true,
},
},

// Plugins for imports, accessibility and react
plugins: ['import', 'prettier', ...targetConfigs[target].plugins],
plugins: [
'@typescript-eslint',
'import',
'prettier',
...targetConfigs[target].plugins,
],

settings: {
// Increase import cache lifetime to 60s
Expand All @@ -125,10 +132,20 @@ module.exports = function eloquence({
// Use webpack to resolve projects to handle src alias
'import/resolver': path.resolve(__dirname, 'resolver'),

// ℹ️ Import plugin TS configs apply to all projects, ref plugin:import/typescript

// Extensions that will be parsed to check for exports, including JS, TS,
// React extenions, Node ESM, and type definitions
'import/extensions': ['.js', '.jsx', '.mjs', '.ts', '.tsx', '.d.ts'],

// Ensure that types are considered external imports
'import/external-module-folders': ['node_modules', 'node_modules/@types'],

'import/parsers': {
// Use the ESLint-TS parser when parsing TS and type definition files
'@typescript-eslint/parser': ['.ts', '.tsx', '.d.ts'],
},

// --- React plugin settings ---
'react': {
pragma: 'React',
Expand All @@ -153,18 +170,18 @@ module.exports = function eloquence({
...coreStylisticIssues,
...coreVariables,

// --- Plugin rules ---
// --- Plugin import rules ---
...pluginImport,

// --- Target rules ---
...targetConfigs[target].rules,

// Custom project rules have priority over package rules
...rules,

// Prettier formatting enforcement via Prettier *plugin*
// (this is different from the rule overrides set in the Prettier *config*)
'prettier/prettier': 'error',

// Project specified rules have priority
...rules,
}),

// --------------------------------------------------------
Expand All @@ -174,6 +191,7 @@ module.exports = function eloquence({
// --- 1️⃣ Source --------------------------
{
files: ['src/**'],

rules: {
// ℹ️ Prevent forgotten console.logs only needed in project source
// code
Expand Down Expand Up @@ -205,16 +223,6 @@ module.exports = function eloquence({
project: './tsconfig.json',
},

plugins: ['@typescript-eslint'],
settings: {
// Config from plugin:import/typescript
'import/external-module-folders': ['node_modules', 'node_modules/@types'],
'import/parsers': {
// Use the ESLint-TS parser when parsing TS and type definition files
'@typescript-eslint/parser': ['.ts', '.tsx', '.d.ts'],
},
},

rules: envRuleSeverities(NODE_ENV, {
...pluginTypescript,
...targetTypeScript,
Expand All @@ -224,6 +232,7 @@ module.exports = function eloquence({
// --- ✅ Test files --------------------------
{
files: ['*.spec.js'],

env: {
jest: true,
},
Expand All @@ -238,7 +247,7 @@ module.exports = function eloquence({
// --- 🌲 Cypress files --------------------------
{
files: ['cypress/**/*'],
// Enable Cypress test writing best practice rules

plugins: ['cypress'],
env: {
'cypress/globals': true,
Expand All @@ -256,8 +265,9 @@ module.exports = function eloquence({
'jest.config.js',
'webpack.config.js',
],

parserOptions: {
// Ensure that configs read by Node are scripts (override Cypress)
// Ensure that configs read by Node are scripts
sourceType: 'script',
},
env: {
Expand All @@ -266,4 +276,15 @@ module.exports = function eloquence({
},
],
}

// IF TypeScript isn't enabled remove configs that will break ESLint
if (!enableTS) {
baseConfigs.plugins = baseConfigs.plugins.filter(
(plugin) => !plugin.includes('@typescript-eslint'),
)

delete baseConfigs.settings['import/parsers']['@typescript-eslint/parser']
}

return baseConfigs
}
15 changes: 0 additions & 15 deletions src/rules/plugin-typescript.js
Expand Up @@ -69,19 +69,4 @@ module.exports = {
'@typescript-eslint/prefer-as-const': 'error',
'@typescript-eslint/prefer-namespace-keyword': 'error',
'@typescript-eslint/triple-slash-reference': 'error',

// ℹ️ Disabled Prettier rules
// (https://github.com/prettier/eslint-config-prettier/blob/master/%40typescript-eslint.js)
'@typescript-eslint/brace-style': 'off',
'@typescript-eslint/comma-spacing': 'off',
'@typescript-eslint/func-call-spacing': 'off',
'@typescript-eslint/indent': 'off',
'@typescript-eslint/keyword-spacing': 'off',
'@typescript-eslint/member-delimiter-style': 'off',
'@typescript-eslint/no-extra-parens': 'off',
'@typescript-eslint/no-extra-semi': 'off',
'@typescript-eslint/quotes': 'off',
'@typescript-eslint/semi': 'off',
'@typescript-eslint/space-before-function-paren': 'off',
'@typescript-eslint/type-annotation-spacing': 'off',
}

0 comments on commit 7ade772

Please sign in to comment.