@colrealpro/react-luau-doctor 0.19.1 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/LICENSE +21 -21
- package/README.md +148 -135
- package/THIRD_PARTY_NOTICES.md +25 -18
- package/dist/cli.js +9332 -8043
- package/dist/cli.js.map +60 -49
- package/dist/config.schema.json +548 -0
- package/dist/scan-worker.js +3406 -1956
- package/dist/scan-worker.js.map +45 -36
- package/package.json +13 -3
- package/vendor/tree-sitter-luau.LICENSE +21 -21
- package/vendor/tree-sitter-luau.wasm +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.20.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- VS Code extension with live diagnostics and hover explanations, requiring no CLI or Bun installation
|
|
8
|
+
- Quick fixes to explain findings, add inline disables, or disable rules in project config
|
|
9
|
+
- Optional background scanning of unopened files
|
|
10
|
+
- Autocomplete and validation for `react-luau-doctor.config.json`, with a schema in both packages
|
|
11
|
+
|
|
12
|
+
### New rules
|
|
13
|
+
|
|
14
|
+
- `react-luau/no-mutating-state-updater` catches mutations of previous state in updater callbacks
|
|
15
|
+
- `react-luau/no-call-component-as-function` catches direct calls to component functions
|
|
16
|
+
- `react-luau/no-create-binding-in-render` catches bindings recreated during render
|
|
17
|
+
- `react-luau/no-binding-getvalue-in-render` catches binding snapshots read during render, except for ref initialization
|
|
18
|
+
- `react-luau/usememo-must-return` catches memo callbacks that return no value
|
|
19
|
+
- `react-luau/no-static-name-prop` suggests child table keys instead of static Roblox `Name` props
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Restored per-file CLI progress while parsing effects and sped up worker shutdown
|
|
24
|
+
- `no-set-state-in-render` catches setters in prop expressions and local initializers, including aliases
|
|
25
|
+
- `exhaustive-deps` follows dependency table aliases and handles shadowed module locals correctly
|
|
26
|
+
- `no-prop-mutation` catches prop mutations in nested functions and callbacks
|
|
27
|
+
- `no-array-index-as-key` uses collection shapes and types to distinguish array positions from dictionary keys
|
|
28
|
+
- `rules-of-hooks` accepts loops over provably static module tables
|
|
29
|
+
- `prefer-binding-over-state` skips custom component props proven incompatible with bindings
|
|
30
|
+
|
|
3
31
|
## 0.19.1
|
|
4
32
|
|
|
5
33
|
### Changed
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 ColRealPro
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ColRealPro
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,135 +1,148 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
React-Luau Doctor
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
bun add --global @colrealpro/react-luau-doctor
|
|
27
|
-
react-luau-doctor
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
react-luau-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="editors/vscode/Icon.png" alt="React-Luau Doctor icon" width="128" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">React-Luau Doctor</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
Static analysis tool for React-Luau codebases. It helps identify potential issues, enforce best practices, and improve React code quality.
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<br>
|
|
12
|
+
|
|
13
|
+
React-Luau Doctor scans your codebase and finds mistakes in hooks, effects, state management, and performance. Rules are built specifically around React-Luau patterns, including problems that can't be caught by traditional typechecking or linting. It works as a CLI or CI tool. Editor diagnostics can also be provided through the [LSP](docs/lsp.md) extension
|
|
14
|
+
|
|
15
|
+
## Getting started
|
|
16
|
+
|
|
17
|
+
React-Luau Doctor requires [Bun](https://bun.com/) 1.4.0 or newer. You can run it directly from npm with:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx @colrealpro/react-luau-doctor
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
or install it globally and run it normally:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
bun add --global @colrealpro/react-luau-doctor
|
|
27
|
+
react-luau-doctor
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
This will create a short overview of your project, and report the highest severity issues, you can add `--verbose` to see all the findings
|
|
31
|
+
|
|
32
|
+
## Examples
|
|
33
|
+
|
|
34
|
+
```lua
|
|
35
|
+
local React = require("..path/to/React")
|
|
36
|
+
local RunService = game:GetService("RunService")
|
|
37
|
+
|
|
38
|
+
local function PlayerList(props)
|
|
39
|
+
local playerCount, setPlayerCount = React.useState(0)
|
|
40
|
+
local absolutePosition, setAbsolutePosition = React.useState(
|
|
41
|
+
props.container.AbsolutePosition
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
local labelText = React.useMemo(function()
|
|
45
|
+
return `Players: {playerCount}`
|
|
46
|
+
end, { playerCount })
|
|
47
|
+
|
|
48
|
+
React.useEffect(function()
|
|
49
|
+
setPlayerCount(#props.players)
|
|
50
|
+
end, { props.players })
|
|
51
|
+
|
|
52
|
+
React.useEffect(function()
|
|
53
|
+
props.container:GetPropertyChangedSignal("AbsolutePosition"):Connect(function()
|
|
54
|
+
setAbsolutePosition(props.container.AbsolutePosition)
|
|
55
|
+
end)
|
|
56
|
+
end, { props.container })
|
|
57
|
+
|
|
58
|
+
if props.hidden then
|
|
59
|
+
return nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
React.useEffect(function()
|
|
63
|
+
print(props.title)
|
|
64
|
+
end, { props.title })
|
|
65
|
+
|
|
66
|
+
return React.createElement("TextLabel", {
|
|
67
|
+
Text = labelText,
|
|
68
|
+
Position = UDim2.fromOffset(absolutePosition.X, absolutePosition.Y),
|
|
69
|
+
})
|
|
70
|
+
end
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
React-Luau Doctor would report the following for this component:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
src/PlayerList.lua
|
|
77
|
+
|
|
78
|
+
X error Hook React.useEffect may run after an earlier reachable return,
|
|
79
|
+
so some renders can execute fewer hooks.
|
|
80
|
+
react-luau/rules-of-hooks
|
|
81
|
+
|
|
82
|
+
! warning setPlayerCount() stores a value derived from props inside an effect.
|
|
83
|
+
react-luau/no-derived-state-effect
|
|
84
|
+
|
|
85
|
+
! warning State absolutePosition mirrors AbsolutePosition and only feeds
|
|
86
|
+
presentation updates, so React reconciliation is acting as an
|
|
87
|
+
unnecessary host-property feedback step.
|
|
88
|
+
react-luau/prefer-binding-over-state
|
|
89
|
+
|
|
90
|
+
! warning Effect creates a connection or subscription without matching cleanup.
|
|
91
|
+
react-luau/effect-needs-cleanup
|
|
92
|
+
|
|
93
|
+
! warning useMemo caches a trivial derived value.
|
|
94
|
+
react-luau/rerender-unnecessary-usememo
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Editor support
|
|
98
|
+
|
|
99
|
+
React-Luau Doctor provides a LSP extension for VS Code
|
|
100
|
+
|
|
101
|
+
The LSP uses the same analysis as the CLI, and updates findings in real time as you edit your code
|
|
102
|
+
|
|
103
|
+
See [LSP](docs/lsp.md) for installation and configuration
|
|
104
|
+
|
|
105
|
+
## CI
|
|
106
|
+
|
|
107
|
+
React-Luau Doctor also provides a CI that can be used to run analysis on your codebase and report findings in PRs, or be used to block merging if doctor finds issues (can't promise satisfaction on blocking merging though yet)
|
|
108
|
+
|
|
109
|
+
Install it with:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
react-luau-doctor ci install
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
It will bring you through a couple options, you can skip it and use the defaults by adding `--yes` to the command
|
|
116
|
+
|
|
117
|
+
## Configuring rules
|
|
118
|
+
|
|
119
|
+
Create a `react-luau-doctor.config.json` file in your project:
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"ignore": [
|
|
124
|
+
"**/*.story.lua",
|
|
125
|
+
"**/*.story.luau"
|
|
126
|
+
],
|
|
127
|
+
"rules": {
|
|
128
|
+
"react-luau/no-array-index-as-key": "off",
|
|
129
|
+
"react-luau/exhaustive-deps": "error"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
This will let you enable and disable some rules or change their severity to your liking if you dislike some of the rules.
|
|
135
|
+
|
|
136
|
+
Inline disables can also be used when a finding is intentional:
|
|
137
|
+
```lua
|
|
138
|
+
-- react-luau-doctor-disable-next-line no-array-index-as-key
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Contributing
|
|
142
|
+
|
|
143
|
+
All contributions are welcome! Bug fixes, new rules, improvements to existing rules, and documentation changes are all appreciated!
|
|
144
|
+
|
|
145
|
+
Feel free to open an issue for bugs or feature requests, or submit a pull request
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
MIT licensed. Inspired by [React Doctor](https://github.com/millionco/react-doctor); not affiliated with its authors, Roblox, or the React-Luau maintainers. See [third-party notices](THIRD_PARTY_NOTICES.md) for parser attribution.
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -1,18 +1,25 @@
|
|
|
1
|
-
# Third-party notices
|
|
2
|
-
|
|
3
|
-
## tree-sitter-luau
|
|
4
|
-
|
|
5
|
-
This project redistributes `tree-sitter-luau.wasm` from
|
|
6
|
-
`tree-sitter-grammars/tree-sitter-luau`, version 1.2.0.
|
|
7
|
-
|
|
8
|
-
The grammar is MIT licensed. Its license text is included at
|
|
9
|
-
`vendor/tree-sitter-luau.LICENSE`.
|
|
10
|
-
|
|
11
|
-
Project: https://github.com/tree-sitter-grammars/tree-sitter-luau
|
|
12
|
-
|
|
13
|
-
## web-tree-sitter
|
|
14
|
-
|
|
15
|
-
The runtime parser is provided by `web-tree-sitter`, which is MIT licensed.
|
|
16
|
-
Its license is installed with the npm dependency.
|
|
17
|
-
|
|
18
|
-
Project: https://github.com/tree-sitter/tree-sitter
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
## tree-sitter-luau
|
|
4
|
+
|
|
5
|
+
This project redistributes `tree-sitter-luau.wasm` from
|
|
6
|
+
`tree-sitter-grammars/tree-sitter-luau`, version 1.2.0.
|
|
7
|
+
|
|
8
|
+
The grammar is MIT licensed. Its license text is included at
|
|
9
|
+
`vendor/tree-sitter-luau.LICENSE`.
|
|
10
|
+
|
|
11
|
+
Project: https://github.com/tree-sitter-grammars/tree-sitter-luau
|
|
12
|
+
|
|
13
|
+
## web-tree-sitter
|
|
14
|
+
|
|
15
|
+
The runtime parser is provided by `web-tree-sitter`, which is MIT licensed.
|
|
16
|
+
Its license is installed with the npm dependency.
|
|
17
|
+
|
|
18
|
+
Project: https://github.com/tree-sitter/tree-sitter
|
|
19
|
+
|
|
20
|
+
## jsonc-parser
|
|
21
|
+
|
|
22
|
+
Project config edits use Microsoft's MIT-licensed `jsonc-parser`
|
|
23
|
+
Its license is installed with the npm dependency and included in the VS Code extension at `vendor/jsonc-parser.LICENSE`
|
|
24
|
+
|
|
25
|
+
Project: https://github.com/microsoft/node-jsonc-parser
|