Skip to content

Commit 8aba8e3

Browse files
docs: update. (#16)
1 parent 5b819d3 commit 8aba8e3

File tree

7 files changed

+110
-34
lines changed

7 files changed

+110
-34
lines changed

.github/workflows/publish.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ jobs:
3434
with:
3535
token: ${{ secrets.NPM_AUTH_TOKEN }}
3636
access: public
37+
tag: ${{ contains(github.ref, '-') && 'next' || 'latest' }}

README.md

Lines changed: 66 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,53 +8,88 @@ A codemod to add `displayName` to React function components.
88

99
- Works with TypeScript or JavaScript source code.
1010
- Quickly fix [`react/display-name`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/display-name.md) lint errors.
11+
- Use `displayName` or a named function expression.
1112
- Pass a path to a file, or a string.
1213

1314
## Example
1415

15-
```ts
16-
import { modify } from '@knighted/display-name'
16+
Given
1717

18-
const codemod = await modify(`
19-
import { memo } from 'react'
18+
```tsx
19+
import React, { memo } from 'react'
2020

21-
const Foo = () => {
22-
return <div>foo</div>
23-
}
21+
const Foo = memo(({ a }) => {
22+
return <>{a}</>
23+
})
24+
const Bar = React.forwardRef((props, ref) => <p ref={ref}>bar</p>)
25+
const Baz = memo(
26+
React.forwardRef((props, ref) => {
27+
return <p ref={ref}>baz</p>
28+
}),
29+
)
30+
```
2431

25-
const Bar = memo(function Bar(props) {
26-
return <span>stuff</span>
27-
})
32+
Then running `modify` on the source code (or `modifyFile` on the file path) results in
2833

29-
const Baz = memo(() => {
30-
return <p>baz</p>
31-
})
32-
`)
34+
```tsx
35+
import React, { memo } from 'react'
3336

34-
console.log(codemod)
37+
const Foo = memo(({ a }) => {
38+
return <>{a}</>
39+
})
40+
Foo.displayName = 'Foo'
41+
const Bar = React.forwardRef((props, ref) => <p ref={ref}>bar</p>)
42+
Bar.displayName = 'Bar'
43+
const Baz = memo(
44+
React.forwardRef((props, ref) => {
45+
return <p ref={ref}>baz</p>
46+
}),
47+
)
48+
```
3549

36-
/*
37-
import { memo } from 'react'
50+
If running the codemod against a codebase that has recently added `eslint-plugin-react` you can write a script.
3851

39-
const Foo = () => {
40-
return <div>foo</div>
41-
}
52+
```js
53+
import { globSync } from 'node:fs'
54+
import { writeFile } from 'node:fs/promises'
55+
import { modifyFile } from '@knighted/display-name'
4256

43-
const Bar = memo(function Bar(props) {
44-
return <span>bar</span>
45-
})
57+
const doCodeMod = async () => {
58+
for (const file of globSync('**/*.tsx', {
59+
exclude: ['**/node_modules/**', '**/dist/**', '**/build/**'],
60+
})) {
61+
await writeFile(file, await modifyFile(file))
62+
}
63+
}
4664

47-
const Baz = memo(() => {
48-
return <p>baz</p>
49-
})
50-
Baz.displayName = 'Baz';
51-
*/
65+
await doCodeMod()
5266
```
5367

54-
You can also pass a filepath instead of a string:
68+
Then optionally run the results through a formatter like `prettier`.
69+
70+
## Options
71+
72+
There are some options, none are required. Most notably you can choose a `style` for adding the display name. The default is `displayName` which adds a displayName property to the function component, or you can choose `namedFuncExpr` to use a named function expression instead.
5573

5674
```ts
57-
import { modifyFile } from '@knighted/display-name'
75+
type Options = {
76+
requirePascal?: boolean
77+
insertSemicolon?: boolean
78+
modifyNestedForwardRef?: boolean
79+
style?: 'displayName' | 'namedFuncExpr'
80+
}
81+
```
5882
59-
await modifyFile('/path/to/file.tsx')
83+
For example, using `namedFuncExpr`
84+
85+
```tsx
86+
const Foo = memo(() => <>foo</>)
87+
```
88+
89+
becomes
90+
91+
```tsx
92+
const Foo = memo(function Foo() {
93+
return <>foo</>
94+
})
6095
```

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@knighted/display-name",
3-
"version": "1.0.0-rc.5",
3+
"version": "1.0.0",
44
"description": "Codemod to add a React displayName to function components.",
55
"type": "module",
66
"exports": {

src/displayName.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,11 @@ const modify = async (source: string, options: Options = defaultOptions) => {
208208
const params = func.params.map(param =>
209209
code.slice(param.start, param.end),
210210
)
211+
/**
212+
* Inside a function expression, the body is always a block statement.
213+
* I think the types for oxc-parser can be improved.
214+
* @see https://github.com/oxc-project/oxc/pull/9128#issuecomment-2870220468
215+
*/
211216
const body = func.body
212217
? code.slice(func.body.start, func.body.end)
213218
: '{}'

test/displayName.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,38 @@ describe('@knighted/displayName', () => {
482482
})
483483
`.replace(/\s+/g, ''),
484484
)
485+
486+
src = `
487+
import React from 'react'
488+
const Hello = React.memo(({ a }) => {
489+
return <>{a}</>
490+
})
491+
`
492+
code = await modify(src, { style: 'namedFuncExpr' })
493+
assert.equal(
494+
code.replace(/\s+/g, ''),
495+
`
496+
import React from 'react'
497+
const Hello = React.memo(function Hello({ a }) {
498+
return <>{a}</>
499+
})
500+
`.replace(/\s+/g, ''),
501+
)
502+
503+
src = `
504+
import {forwardRef} from 'react'
505+
const Fr = forwardRef(({ a }) => <>{a}</>)
506+
`
507+
code = await modify(src, { style: 'namedFuncExpr' })
508+
assert.equal(
509+
code.replace(/\s+/g, ''),
510+
`
511+
import {forwardRef} from 'react'
512+
const Fr = forwardRef(function Fr({ a }) {
513+
return <>{a}</>
514+
})
515+
`.replace(/\s+/g, ''),
516+
)
485517
})
486518

487519
it('the style option works with namedFuncExpr', async t => {

test/fixtures/style.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ const FuncExprForwardRefReact = React.forwardRef<HTMLParagraphElement, Props>(
3939
return <p ref={ref}>{props.foo}</p>
4040
},
4141
)
42+
const Hello = React.memo(({ a }: { a: string }) => {
43+
return <>{a}</>
44+
})
4245

4346
// These already have a display name.
4447
const MemoDisplayName = memo((props: Props) => {

0 commit comments

Comments
 (0)