Skip to content

Commit

Permalink
Eslint Plugin: Add TypeScript as peer dependency and make it optional (
Browse files Browse the repository at this point in the history
…#29942)

* Add explicit dependency on TypeScript

* Move typescript to a peer dependency

* Run TypeScript validation only when it is installed

* ESLint Pluging: Add the changelog entry

* Clarify the TS integration in the README file

* Mark typescript as an optional peer dependency

Co-authored-by: Grzegorz Ziolkowski <[email protected]>
  • Loading branch information
sarayourfriend and gziolo authored Mar 19, 2021
1 parent cdeaf87 commit f790903
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 16 deletions.
4 changes: 4 additions & 0 deletions packages/eslint-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

### Bug Fix

- Adds TypeScript as a peer dependency and makes it optional when not installed ([#29942](https://github.com/WordPress/gutenberg/pull/29942)).

## 9.0.0 (2021-03-17)

### Breaking Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ To opt-in to the default configuration, extend your own project's `.eslintrc` fi

Refer to the [ESLint documentation on Shareable Configs](http://eslint.org/docs/developer-guide/shareable-configs) for more information.

The `recommended` preset will include rules governing an ES2015+ environment, and includes rules from the [`eslint-plugin-jsx-a11y`](https://github.com/evcohen/eslint-plugin-jsx-a11y), [`eslint-plugin-react`](https://github.com/yannickcr/eslint-plugin-react), and [`eslint-plugin-prettier`](https://github.com/prettier/eslint-plugin-prettier) projects.
The `recommended` preset will include rules governing an ES2015+ environment, and includes rules from the [`eslint-plugin-jsx-a11y`](https://github.com/evcohen/eslint-plugin-jsx-a11y), [`eslint-plugin-react`](https://github.com/yannickcr/eslint-plugin-react), and [`eslint-plugin-prettier`](https://github.com/prettier/eslint-plugin-prettier) projects. It also includes an optional integration with [`@typescript-eslint/eslint-plugin`](https://github.com/typescript-eslint/typescript-eslint) that gets activated when the [`typescript`](https://www.npmjs.com/package/typescript) package is installed in the project.

There is also `recommended-with-formatting` ruleset for projects that want to opt out from [Prettier](https://prettier.io). It has the native ESLint code formatting rules enabled instead.

Expand Down
38 changes: 24 additions & 14 deletions packages/eslint-plugin/configs/recommended.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,38 @@ const { cosmiconfigSync } = require( 'cosmiconfig' );
*/
const defaultPrettierConfig = require( '@wordpress/prettier-config' );

/**
* Internal dependencies
*/
const { isPackageInstalled } = require( '../utils' );

const { config: localPrettierConfig } =
cosmiconfigSync( 'prettier' ).search() || {};
const prettierConfig = { ...defaultPrettierConfig, ...localPrettierConfig };

module.exports = {
settings: {
'import/resolver': {
node: {
extensions: [ '.js', '.jsx', '.ts', '.tsx' ],
},
},
'import/core-modules': [ 'react' ],
},
const config = {
extends: [
require.resolve( './recommended-with-formatting.js' ),
'plugin:prettier/recommended',
'prettier/react',
'plugin:@typescript-eslint/eslint-recommended',
],
ignorePatterns: [ '**/*.d.ts' ],
rules: {
'prettier/prettier': [ 'error', prettierConfig ],
},
overrides: [
};

if ( isPackageInstalled( 'typescript' ) ) {
config.settings = {
'import/resolver': {
node: {
extensions: [ '.js', '.jsx', '.ts', '.tsx' ],
},
},
'import/core-modules': [ 'react' ],
};
config.extends.push( 'plugin:@typescript-eslint/eslint-recommended' );
config.ignorePatterns = [ '**/*.d.ts' ];
config.overrides = [
{
files: [ '**/*.ts', '**/*.tsx' ],
parser: '@typescript-eslint/parser',
Expand All @@ -43,5 +51,7 @@ module.exports = {
'no-unused-vars': 'off',
},
},
],
};
];
}

module.exports = config;
8 changes: 7 additions & 1 deletion packages/eslint-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,13 @@
"requireindex": "^1.2.0"
},
"peerDependencies": {
"eslint": "^6 || ^7"
"eslint": "^6 || ^7",
"typescript": "^4"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
},
"publishConfig": {
"access": "public"
Expand Down
2 changes: 2 additions & 0 deletions packages/eslint-plugin/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const {
const { getTranslateFunctionArgs } = require( './get-translate-function-args' );
const { getTextContentFromNode } = require( './get-text-content-from-node' );
const { getTranslateFunctionName } = require( './get-translate-function-name' );
const isPackageInstalled = require( './is-package-installed' );

module.exports = {
TRANSLATION_FUNCTIONS,
Expand All @@ -17,4 +18,5 @@ module.exports = {
getTranslateFunctionArgs,
getTextContentFromNode,
getTranslateFunctionName,
isPackageInstalled,
};
16 changes: 16 additions & 0 deletions packages/eslint-plugin/utils/is-package-installed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Checks whether the passed package name is installed in the project.
*
* @param {string} packageName The name of npm package.
* @return {boolean} Returns true when the package is installed or false otherwise.
*/
const isPackageInstalled = ( packageName ) => {
try {
if ( require.resolve( packageName ) ) {
return true;
}
} catch ( error ) {}
return false;
};

module.exports = isPackageInstalled;
18 changes: 18 additions & 0 deletions packages/eslint-plugin/utils/test/is-package-installed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Internal dependencies
*/
import isPackageInstalled from '../is-package-installed';

describe( 'isPackageInstalled', () => {
test( 'returns false when package not installed', () => {
const result = isPackageInstalled( 'nonexistent-package-name' );

expect( result ).toBe( false );
} );

test( 'returns true when package installed', () => {
const result = isPackageInstalled( 'eslint' );

expect( result ).toBe( true );
} );
} );

0 comments on commit f790903

Please sign in to comment.