Skip to content

Commit 30f1896

Browse files
authored
Merge pull request #37 from rx-ts/develop
feat: support top level JSX with blank lines
2 parents 21934ce + 2ee1b37 commit 30f1896

File tree

13 files changed

+564
-74
lines changed

13 files changed

+564
-74
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,6 @@ deploy:
4242
branch: master
4343
- provider: script
4444
skip_cleanup: true
45-
script: yarn run lerna publish --canary --conventional-prerelease --preid beta --pre-dist-tag beta --yes
45+
script: yarn run lerna publish --canary --conventional-prerelease --force-publish --preid beta --pre-dist-tag beta --yes
4646
on:
4747
branch: develop

README.md

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,35 @@ npm i -D @rxts/eslint-plugin-mdx
6464

6565
2. If you're using `eslint@^5.0.0`, you need to enable this parser/plugin manually, because `eslint@5` does not support `extends` for `overrides` property in its configuration:
6666

67-
```json
68-
{
69-
"extends": ["plugin:@rxts/mdx/recommended"],
70-
"overrides": [
67+
```js
68+
const rebass = require('rebass')
69+
70+
module.exports = {
71+
extends: ['plugin:@rxts/mdx/recommended'],
72+
overrides: [
7173
{
72-
"files": ["*.mdx"],
73-
"globals": {
74-
"React": false
74+
files: ['*.mdx'],
75+
globals: Object.keys(rebass).reduce(
76+
(globals, Component) =>
77+
Object.assign(globals, {
78+
[Component]: false,
79+
}),
80+
{
81+
React: false,
82+
},
83+
),
84+
rules: {
85+
'lines-between-class-members': 0,
86+
'react/jsx-no-undef': [
87+
2,
88+
{
89+
allowGlobals: true,
90+
},
91+
],
92+
'react/react-in-jsx-scope': 0,
7593
},
76-
"rules": {
77-
"lines-between-class-members": 0,
78-
"react/react-in-jsx-scope": 0
79-
}
80-
}
81-
]
94+
},
95+
],
8296
}
8397
```
8498

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"@types/jest": "^24.0.17",
2222
"@types/node": "^12.7.1",
2323
"@types/react": "^16.9.1",
24+
"@types/rebass": "^3.0.4",
2425
"@types/unist": "^2.0.3",
2526
"babel-eslint": "^10.0.2",
2627
"commitlint": "^8.1.0",

packages/eslint-mdx/README.md

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,35 @@ npm i -D @rxts/eslint-plugin-mdx
6464

6565
2. If you're using `eslint@^5.0.0`, you need to enable this parser/plugin manually, because `eslint@5` does not support `extends` for `overrides` property in its configuration:
6666

67-
```json
68-
{
69-
"extends": ["plugin:@rxts/mdx/recommended"],
70-
"overrides": [
67+
```js
68+
const rebass = require('rebass')
69+
70+
module.exports = {
71+
extends: ['plugin:@rxts/mdx/recommended'],
72+
overrides: [
7173
{
72-
"files": ["*.mdx"],
73-
"globals": {
74-
"React": false
74+
files: ['*.mdx'],
75+
globals: Object.keys(rebass).reduce(
76+
(globals, Component) =>
77+
Object.assign(globals, {
78+
[Component]: false,
79+
}),
80+
{
81+
React: false,
82+
},
83+
),
84+
rules: {
85+
'lines-between-class-members': 0,
86+
'react/jsx-no-undef': [
87+
2,
88+
{
89+
allowGlobals: true,
90+
},
91+
],
92+
'react/react-in-jsx-scope': 0,
7593
},
76-
"rules": {
77-
"lines-between-class-members": 0,
78-
"react/react-in-jsx-scope": 0
79-
}
80-
}
81-
]
94+
},
95+
],
8296
}
8397
```
8498

packages/eslint-mdx/src/parser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ export class Parser {
209209
position: { start },
210210
} = node
211211

212-
e.index += start.offset - 3
212+
e.index += start.offset - 2
213213
e.column = e.lineNumber > 1 ? e.column : e.column + start.column - 3
214214
e.lineNumber += start.line - 1
215215

packages/eslint-mdx/src/traverse.ts

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,41 +10,51 @@ import { Traverser, TraverseOptions } from './types'
1010

1111
import { Node, Parent } from 'unist'
1212

13-
export const SKIP_COMBINE_JSX_TYPES: readonly string[] = ['root', 'jsx']
14-
1513
export class Traverse {
1614
private readonly _enter: Traverser
1715

1816
constructor({ enter }: TraverseOptions) {
1917
this._enter = enter
2018
}
2119

20+
combineLeftJsxNodes(jsxNodes: Node[]) {
21+
return {
22+
type: 'jsx',
23+
data: jsxNodes[0].data,
24+
value: jsxNodes.reduce((acc, { value }) => (acc += value), ''),
25+
position: {
26+
start: jsxNodes[0].position.start,
27+
end: last(jsxNodes).position.end,
28+
},
29+
}
30+
}
31+
2232
// fix #7
2333
combineJsxNodes(nodes: Node[]) {
2434
let offset = 0
2535
const jsxNodes: Node[] = []
2636
const { length } = nodes
2737
return nodes.reduce<Node[]>((acc, node, index) => {
2838
if (node.type === 'jsx') {
29-
const rawText = node.value as string
30-
if (isOpenTag(rawText)) {
39+
const value = node.value as string
40+
if (isOpenTag(value)) {
3141
offset++
3242
jsxNodes.push(node)
3343
} else {
34-
if (isCloseTag(rawText)) {
44+
if (isCloseTag(value)) {
3545
offset--
3646
}
3747
// prettier-ignore
3848
/* istanbul ignore next */
3949
else if (
40-
!isComment(rawText) &&
41-
!isSelfClosingTag(rawText) &&
42-
!isOpenCloseTag(rawText)
50+
!isComment(value) &&
51+
!isSelfClosingTag(value) &&
52+
!isOpenCloseTag(value)
4353
) {
4454
// should never happen, just for robustness
4555
const { start } = node.position
4656
throw Object.assign(
47-
new SyntaxError('unknown jsx node: ' + JSON.stringify(rawText)),
57+
new SyntaxError('unknown jsx node: ' + JSON.stringify(value)),
4858
{
4959
lineNumber: start.line,
5060
column: start.column,
@@ -55,16 +65,8 @@ export class Traverse {
5565

5666
jsxNodes.push(node)
5767

58-
if (!offset || index === length - 1) {
59-
acc.push({
60-
type: 'jsx',
61-
data: jsxNodes[0].data,
62-
value: jsxNodes.reduce((acc, { value }) => (acc += value), ''),
63-
position: {
64-
start: jsxNodes[0].position.start,
65-
end: last(jsxNodes).position.end,
66-
},
67-
})
68+
if (!offset) {
69+
acc.push(this.combineLeftJsxNodes(jsxNodes))
6870
jsxNodes.length = 0
6971
}
7072
}
@@ -73,6 +75,9 @@ export class Traverse {
7375
} else {
7476
acc.push(node)
7577
}
78+
if (index === length - 1 && jsxNodes.length) {
79+
acc.push(this.combineLeftJsxNodes(jsxNodes))
80+
}
7681
return acc
7782
}, [])
7883
}
@@ -87,9 +92,7 @@ export class Traverse {
8792
let children = node.children as Node[]
8893

8994
if (children) {
90-
if (!SKIP_COMBINE_JSX_TYPES.includes(node.type)) {
91-
children = node.children = this.combineJsxNodes(children)
92-
}
95+
children = node.children = this.combineJsxNodes(children)
9396
children.forEach(child => this.traverse(child, node as Parent))
9497
}
9598

packages/eslint-plugin-mdx/README.md

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,35 @@ npm i -D @rxts/eslint-plugin-mdx
6464

6565
2. If you're using `eslint@^5.0.0`, you need to enable this parser/plugin manually, because `eslint@5` does not support `extends` for `overrides` property in its configuration:
6666

67-
```json
68-
{
69-
"extends": ["plugin:@rxts/mdx/recommended"],
70-
"overrides": [
67+
```js
68+
const rebass = require('rebass')
69+
70+
module.exports = {
71+
extends: ['plugin:@rxts/mdx/recommended'],
72+
overrides: [
7173
{
72-
"files": ["*.mdx"],
73-
"globals": {
74-
"React": false
74+
files: ['*.mdx'],
75+
globals: Object.keys(rebass).reduce(
76+
(globals, Component) =>
77+
Object.assign(globals, {
78+
[Component]: false,
79+
}),
80+
{
81+
React: false,
82+
},
83+
),
84+
rules: {
85+
'lines-between-class-members': 0,
86+
'react/jsx-no-undef': [
87+
2,
88+
{
89+
allowGlobals: true,
90+
},
91+
],
92+
'react/react-in-jsx-scope': 0,
7593
},
76-
"rules": {
77-
"lines-between-class-members": 0,
78-
"react/react-in-jsx-scope": 0
79-
}
80-
}
81-
]
94+
},
95+
],
8296
}
8397
```
8498

packages/eslint-plugin-mdx/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"eslint-plugin-react": ">=7.0.0"
2323
},
2424
"dependencies": {
25-
"eslint-mdx": "^0.10.0"
25+
"eslint-mdx": "^0.10.0",
26+
"rebass": "^4.0.2"
2627
}
2728
}
Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
import { base } from './base'
22

3+
import * as rebass from 'rebass'
4+
35
export const overrides = {
46
...base,
5-
globals: {
6-
React: false,
7-
},
7+
globals: Object.keys(rebass).reduce<Record<string, false>>(
8+
(globals, Component) =>
9+
Object.assign(globals, {
10+
[Component]: false,
11+
}),
12+
{
13+
React: false,
14+
},
15+
),
816
rules: {
917
'lines-between-class-members': 0, // See https://github.com/mdx-js/mdx/issues/195
18+
'react/jsx-no-undef': [
19+
2,
20+
{
21+
allowGlobals: true,
22+
},
23+
],
1024
'react/react-in-jsx-scope': 0,
1125
},
1226
}

test/__snapshots__/fixtures.test.ts.snap

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,51 @@ Lorem ipsum dolor sit _amet_, consectetur adipiscing elit. Ut ac lobortis velit.
2727
"
2828
`;
2929

30+
exports[`fixtures should match all snapshots: blank-lines.mdx 1`] = `
31+
"import { Box } from '@rebass/emotion'
32+
33+
# Getting Started
34+
35+
If you have an existing project you want to integrate MDX with, check out
36+
the installation guides.
37+
38+
<Box
39+
p={3}
40+
bg='lightgray'
41+
style={{
42+
textAlign: 'center',
43+
fontWeight: 'bold',
44+
}}
45+
>
46+
47+
[Next.js](/getting-started/next) \\\\|
48+
[Gatsby](/getting-started/gatsby) \\\\|
49+
[Create React App](/getting-started/create-react-app) \\\\|
50+
[React Static](/getting-started/react-static) \\\\|
51+
[Webpack](/getting-started/webpack) \\\\|
52+
[Parcel](/getting-started/parcel) \\\\|
53+
[Zero](/getting-started/zero)
54+
55+
</Box>
56+
57+
# Hello, world!
58+
59+
Here's a Twitter shortcode:
60+
61+
<Tweet tweetId=\\"1116723357410447360\\" />
62+
63+
<TextGradient>
64+
65+
# Here's a text gradient shortcode!
66+
67+
</TextGradient>
68+
69+
Here's a YouTube shortcode:
70+
71+
<YouTube videoId=\\"4fHw4GeW3EU\\" />
72+
"
73+
`;
74+
3075
exports[`fixtures should match all snapshots: no-jsx-html-comments.mdx 1`] = `
3176
"# Title
3277
@@ -53,4 +98,9 @@ Main <main> > </main>
5398
"
5499
`;
55100

56-
exports[`fixtures should match all snapshots: parser.mdx 1`] = `undefined`;
101+
exports[`fixtures should match all snapshots: parser.mdx 1`] = `
102+
"# Title
103+
104+
Header <header>
105+
"
106+
`;

0 commit comments

Comments
 (0)