Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: TS parsing configs 🎊 #243

Merged
merged 2 commits into from Sep 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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',
}