Skip to content

Commit 5d62b55

Browse files
committed
feat: add @rxts/mdx/no-unused-expressions rule to replace eslint's
1 parent c6e56ae commit 5d62b55

File tree

10 files changed

+77
-24
lines changed

10 files changed

+77
-24
lines changed

.eslintrc.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,6 @@ module.exports = {
2828
{
2929
files: ['*.mdx'],
3030
extends: ['plugin:@rxts/mdx/recommended'],
31-
parserOptions: {
32-
parser: 'babel-eslint',
33-
},
34-
rules: {
35-
'no-unused-expressions': 0,
36-
},
3731
},
3832
{
3933
files: ['*.ts', '*.tsx'],

CHANGELOG.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5-
### [0.4.1](https://github.com/rx-ts/eslint-plugin-mdx/compare/v0.4.0...v0.4.1) (2019-07-31)
5+
## [0.4.1](https://github.com/rx-ts/eslint-plugin-mdx/compare/v0.4.0...v0.4.1) (2019-07-31)
6+
7+
8+
### Features
9+
10+
* perf: extract `parseMdx`, exports everything in package ([1f965a1](https://github.com/rx-ts/eslint-plugin-mdx/commit/1f965a1))
611

712
## [0.4.0](https://github.com/rx-ts/eslint-plugin-mdx/compare/v0.3.1...v0.4.0) (2019-07-31)
813

@@ -16,7 +21,7 @@ All notable changes to this project will be documented in this file. See [standa
1621

1722
### Bug Fixes
1823

19-
* .* could not match multi lines, use [\s\S]* instead, close [#4](https://github.com/rx-ts/eslint-plugin-mdx/issues/4) ([f7e7efe](https://github.com/rx-ts/eslint-plugin-mdx/commit/f7e7efe))
24+
* `.*` could not match multi lines, use `[\s\S]*` instead, close [#4](https://github.com/rx-ts/eslint-plugin-mdx/issues/4) ([f7e7efe](https://github.com/rx-ts/eslint-plugin-mdx/commit/f7e7efe))
2025

2126
## [0.3.0](https://github.com/rx-ts/eslint-plugin-mdx/compare/v0.2.1...v0.3.0) (2019-07-30)
2227

@@ -39,35 +44,27 @@ All notable changes to this project will be documented in this file. See [standa
3944

4045
* support custom parser like babel-eslint ([b718574](https://github.com/rx-ts/eslint-plugin-mdx/commit/b718574))
4146

42-
43-
4447
### [0.1.3](https://github.com/rx-ts/eslint-plugin-mdx/compare/v0.1.2...v0.1.3) (2019-07-29)
4548

4649

4750
### Bug Fixes
4851

4952
* upgrade peer dependency eslint to >= 6.0.0 ([#3](https://github.com/rx-ts/eslint-plugin-mdx/issues/3) [#4](https://github.com/rx-ts/eslint-plugin-mdx/issues/4)) ([f0ab288](https://github.com/rx-ts/eslint-plugin-mdx/commit/f0ab288))
5053

51-
52-
5354
### [0.1.2](https://github.com/rx-ts/eslint-plugin-mdx/compare/v0.1.1...v0.1.2) (2019-07-29)
5455

5556

5657
### Bug Fixes
5758

5859
* show correct column and line on lint error ([90c5390](https://github.com/rx-ts/eslint-plugin-mdx/commit/90c5390))
5960

60-
61-
6261
### [0.1.1](https://github.com/rx-ts/eslint-plugin-mdx/compare/v0.1.0...v0.1.1) (2019-07-29)
6362

6463

6564
### Bug Fixes
6665

6766
* overrides in node_modules seems not working ([d2f1535](https://github.com/rx-ts/eslint-plugin-mdx/commit/d2f1535))
6867

69-
70-
7168
## 0.1.0 (2019-07-29)
7269

7370

README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ npm i -D @rxts/eslint-plugin-mdx
5757
"parser": "@rxts/eslint-plugin-mdx",
5858
"plugins": ["@rxts/mdx"],
5959
"rules": {
60+
"@rxts/mdx/no-unused-expressions": 2,
61+
"no-unused-expressions": 0,
6062
"react/react-in-jsx-scope": 0
6163
}
6264
}
@@ -86,12 +88,9 @@ npm i -D @rxts/eslint-plugin-mdx
8688
}
8789
```
8890

89-
## Limitations
91+
## Limitation
9092

91-
1. This parser/plugin can only handle ES syntaxes for you, markdown related syntaxes will just be ignored, you can use [markdownlint](https://github.com/markdownlint/markdownlint) to lint that part.
92-
93-
2. `MDX` can render `jsx` block automatically without exporting them, but `eslint` will report `no-unused-expressions` issue which could be unexpected, so you may need to disable this rule for `*.mdx`.
94-
I'm not going to disable this rule in the recommended config, because I'm going to add a custom `mdx/no-unused-expressions` rule to replace the incompatible one, which should not affect the `jsx` codes.
93+
> This parser/plugin can only handle ES syntaxes for you, markdown related syntaxes will just be ignored, you can use [markdownlint](https://github.com/markdownlint/markdownlint) to lint that part.
9594
9695
## Changelog
9796

package.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rxts/eslint-plugin-mdx",
3-
"version": "0.4.1",
3+
"version": "0.5.0",
44
"description": "ESLint Parser/Plugin for MDX",
55
"repository": "[email protected]:rx-ts/eslint-plugin-mdx.git",
66
"author": "JounQin <[email protected]>",
@@ -16,6 +16,15 @@
1616
"test": "jest",
1717
"lint": "eslint . --ext js,mdx,ts,tsx"
1818
},
19+
"keywords": [
20+
"eslint",
21+
"eslint-parser",
22+
"eslint-plugin",
23+
"eslint-parser-mdx",
24+
"eslint-plugin-mdx",
25+
"mdx",
26+
"eslint-mdx"
27+
],
1928
"peerDependencies": {
2029
"eslint": ">=5.0.0"
2130
},

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ import path from 'path'
33
export * from './helper'
44
export * from './parser'
55
export * from './regexp'
6+
export * from './rules'
67
export * from './traverse'
78

89
export const configs = {
910
recommended: {
1011
parser: path.resolve(__dirname, 'parser'),
1112
plugins: ['@rxts/mdx'],
1213
rules: {
14+
'@rxts/mdx/no-unused-expressions': 2,
15+
'no-unused-expressions': 0,
1316
'react/react-in-jsx-scope': 0,
1417
},
1518
},

src/parser.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const parseMdx = unified()
2727

2828
export const parseForESLint = (
2929
code: string,
30-
options: Linter.ParserOptions,
30+
options: Linter.ParserOptions = {},
3131
): Linter.ESLintParseResult => {
3232
let { parser } = options
3333

@@ -45,7 +45,12 @@ export const parseForESLint = (
4545
}
4646
}
4747
} else {
48-
parser = esParse
48+
try {
49+
// try to load babel-eslint automatically
50+
parser = require(require.resolve('babel-eslint')).parse
51+
} catch (e) {
52+
parser = esParse
53+
}
4954
}
5055

5156
const root = parseMdx(code) as Parent

src/rules/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { noUnUsedExpressions } from './no-unused-expressions'
2+
3+
export const rules = {
4+
'no-unused-expressions': noUnUsedExpressions,
5+
}

src/rules/no-unused-expressions.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// eslint-disable-next-line @typescript-eslint/no-triple-slash-reference
2+
/// <reference path="../../types.d.ts" />
3+
4+
import ESLintNoUnUsedExpressions from 'eslint/lib/rules/no-unused-expressions'
5+
6+
import { Rule } from 'eslint'
7+
import { ExpressionStatement, Node } from 'estree'
8+
9+
export const JSX_TYPES = ['JSXElement', 'JSXFragment'] as const
10+
11+
export type JsxType = (typeof JSX_TYPES)[number]
12+
13+
export interface ExpressionStatementWithParent extends ExpressionStatement {
14+
parent?: {
15+
type: Node['type']
16+
}
17+
}
18+
19+
export const noUnUsedExpressions: Rule.RuleModule = {
20+
create(context) {
21+
const esLintRuleListener = ESLintNoUnUsedExpressions.create(context)
22+
return {
23+
ExpressionStatement(node: ExpressionStatementWithParent) {
24+
if (
25+
JSX_TYPES.includes(node.expression.type as JsxType) &&
26+
node.parent.type === 'Program'
27+
) {
28+
return
29+
}
30+
esLintRuleListener.ExpressionStatement(node)
31+
},
32+
}
33+
},
34+
}

tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"outDir": "dist",
1212
"sourceMap": true,
1313
"strict": true,
14+
"strictFunctionTypes": false,
1415
"strictNullChecks": false,
1516
"target": "es5"
1617
}

types.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ declare interface SyntaxError {
44
lineNumber?: number
55
}
66

7+
declare module 'eslint/lib/rules/no-unused-expressions' {
8+
import { Rule } from 'eslint'
9+
const noUnUsedExpressions: Rule.RuleModule
10+
export = noUnUsedExpressions
11+
}
12+
713
declare module 'espree' {
814
import * as estree from 'estree'
915

0 commit comments

Comments
 (0)