Skip to content

Commit 891b1ea

Browse files
feat: fix some issues with go to and add better docs (#66)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent 1c23cf8 commit 891b1ea

File tree

5 files changed

+97
-123
lines changed

5 files changed

+97
-123
lines changed

.changeset/mighty-oranges-hear.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@tanstack/devtools-vite': patch
3+
---
4+
5+
fix bugs with go to source not passing in column line properly to config

docs/vite-plugin.md

Lines changed: 77 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ npm install -D @tanstack/devtools-vite
1616

1717
Then add it as the *FIRST* plugin in your Vite config:
1818

19-
```javascript
19+
```ts
2020
import { devtools } from '@tanstack/devtools-vite'
2121

2222
export default {
@@ -33,7 +33,7 @@ And you're done!
3333

3434
You can configure the devtools plugin by passing options to the `devtools` function:
3535

36-
```javascript
36+
```ts
3737
import { devtools } from '@tanstack/devtools-vite'
3838

3939
export default {
@@ -46,63 +46,95 @@ export default {
4646
}
4747
```
4848

49-
- `eventBusConfig` - Configuration for the event bus that the devtools use to communicate with the client
49+
### eventBusConfig
5050

51-
```ts
52-
{
53-
eventBusConfig: {
54-
// port to run the event bus on
55-
port: 1234,
56-
// console log debug logs or not
57-
debug: false
58-
},
59-
}
60-
```
51+
Configuration for the event bus that the devtools use to communicate with the client
6152

62-
- `appDir` - The directory where the react router app is located. Defaults to the "./src" relative to where vite.config is being defined.
53+
```ts
54+
import { devtools } from '@tanstack/devtools-vite'
6355

64-
```javascript
65-
{
66-
appDir: './src',
56+
export default {
57+
plugins: [
58+
devtools({
59+
eventBusConfig: {
60+
// port to run the event bus on
61+
port: 1234,
62+
// console log debug logs or not
63+
debug: false
64+
},
65+
}),
66+
// ... rest of your plugins here
67+
],
6768
}
69+
6870
```
6971

70-
- `editor` - The open in editor configuration which has two fields, `name` and `open`,
71-
`name` is the name of your editor, and `open` is a function that opens the editor with the given file and line number. You can implement your version for your editor as follows:
72+
### editor
7273

73-
> [!IMPORTANT] `editor` is only needed for editors that are NOT VS Code, by default this works OOTB with VS Code.
74+
The open in editor configuration which has two fields, `name` and `open`,
75+
`name` is the name of your editor, and `open` is a function that opens the editor with the given file and line number. You can implement your version for your editor as follows:
7476

75-
```ts
76-
const open = (file: string, line: number) => {
77-
// implement your editor opening logic here
78-
}
77+
```ts
78+
import { devtools } from '@tanstack/devtools-vite'
7979

80-
{
81-
editor: {
82-
name: 'vscode',
83-
open
84-
}
80+
export default {
81+
plugins: [
82+
devtools({
83+
editor: {
84+
name: 'VSCode',
85+
open: async (path, lineNumber, columnNumber) => {
86+
const { exec } = await import('node:child_process')
87+
exec(
88+
// or windsurf/cursor/webstorm
89+
`code -g "${(path).replaceAll('$', '\\$')}${lineNumber ? `:${lineNumber}` : ''}${columnNumber ? `:${columnNumber}` : ''}"`,
90+
)
91+
},
92+
},
93+
}),
94+
// ... rest of your plugins here
95+
],
8596
}
97+
8698
```
99+
100+
> [!IMPORTANT] `editor` is only needed for editors that are NOT VS Code, by default this works OOTB with VS Code.
101+
102+
### enhancedLogs
87103

88-
89-
- `enhancedLogs` - Configuration for enhanced logging. Defaults to enabled.
104+
Configuration for enhanced logging. Defaults to enabled.
90105

91106
```ts
92-
{
93-
enhancedLogs: {
94-
enabled: true
95-
}
107+
import { devtools } from '@tanstack/devtools-vite'
108+
109+
export default {
110+
plugins: [
111+
devtools({
112+
enhancedLogs: {
113+
enabled: true
114+
}
115+
}),
116+
// ... rest of your plugins here
117+
],
96118
}
97119
```
98120

99-
- `injectSource` - Configuration for source injection. Defaults to enabled.
121+
### injectSource
122+
123+
Configuration for source injection. Defaults to enabled.
124+
100125

101126
```ts
102-
{
103-
injectSource: {
104-
enabled: true
105-
}
127+
import { devtools } from '@tanstack/devtools-vite'
128+
129+
export default {
130+
plugins: [
131+
devtools({
132+
injectSource: {
133+
enabled: true
134+
}
135+
}),
136+
// ... rest of your plugins here
137+
],
106138
}
107139
```
108140

@@ -113,4 +145,8 @@ const open = (file: string, line: number) => {
113145
Allows you to open the source location on anything in your browser by clicking on it.
114146

115147
To trigger this behavior you need the Devtools Vite plugin installed and configured and
116-
the Panel available on the page. Simply click on any element while holding down the Shift and Ctrl (or Meta) keys.
148+
the Panel available on the page. Simply click on any element while holding down the Shift and Ctrl (or Meta) keys.
149+
150+
### Advanced console logs
151+
152+
Allows you to go directly to the console log location directly from the browser/terminal
Lines changed: 4 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import { normalizePath } from 'vite'
2-
import { checkPath } from './utils.js'
3-
41
type OpenSourceData = {
52
type: 'open-source'
63
data: {
@@ -31,62 +28,22 @@ export const DEFAULT_EDITOR_CONFIG: EditorConfig = {
3128
open: async (path, lineNumber, columnNumber) => {
3229
const { exec } = await import('node:child_process')
3330
exec(
34-
`code -g "${normalizePath(path).replaceAll('$', '\\$')}${lineNumber ? `:${lineNumber}` : ''}${columnNumber ? `:${columnNumber}` : ''}"`,
31+
`code -g "${path.replaceAll('$', '\\$')}${lineNumber ? `:${lineNumber}` : ''}${columnNumber ? `:${columnNumber}` : ''}"`,
3532
)
3633
},
3734
}
3835

3936
export const handleOpenSource = async ({
4037
data,
4138
openInEditor,
42-
appDir,
4339
}: {
4440
data: OpenSourceData
45-
appDir: string
4641
openInEditor: EditorConfig['open']
4742
}) => {
48-
const { source, line, routeID } = data.data
43+
const { source, line, column } = data.data
4944
const lineNum = line ? `${line}` : undefined
50-
const fs = await import('node:fs')
51-
const path = await import('node:path')
45+
const columnNum = column ? `${column}` : undefined
5246
if (source) {
53-
return openInEditor(source, lineNum)
54-
}
55-
56-
if (routeID) {
57-
const routePath = path.join(appDir, routeID)
58-
const checkedPath = await checkPath(routePath)
59-
60-
if (!checkedPath) return
61-
const { type, validPath } = checkedPath
62-
63-
const reactExtensions = ['tsx', 'jsx']
64-
const allExtensions = ['ts', 'js', ...reactExtensions]
65-
const isRoot = routeID === 'root'
66-
const findFileByExtension = (prefix: string, filePaths: Array<string>) => {
67-
const file = filePaths.find((file) =>
68-
allExtensions.some((ext) => file === `${prefix}.${ext}`),
69-
)
70-
return file
71-
}
72-
73-
if (isRoot) {
74-
if (!fs.existsSync(appDir)) return
75-
const filesInReactRouterPath = fs.readdirSync(appDir)
76-
const rootFile = findFileByExtension('root', filesInReactRouterPath)
77-
rootFile && openInEditor(path.join(appDir, rootFile), lineNum)
78-
return
79-
}
80-
81-
// If its not the root route, then we find the file or folder in the routes folder
82-
// We know that the route ID is in the form of "routes/contact" or "routes/user.profile" when is not root
83-
// so the ID already contains the "routes" segment, so we just need to find the file or folder in the routes folder
84-
if (type === 'directory') {
85-
const filesInFolderRoute = fs.readdirSync(validPath)
86-
const routeFile = findFileByExtension('route', filesInFolderRoute)
87-
routeFile && openInEditor(path.join(appDir, routeID, routeFile), lineNum)
88-
return
89-
}
90-
return openInEditor(validPath, lineNum)
47+
return openInEditor(source, lineNum, columnNum)
9148
}
9249
}

packages/devtools-vite/src/plugin.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import type { ServerEventBusConfig } from '@tanstack/devtools-event-bus/server'
99
import type { Plugin } from 'vite'
1010

1111
export type TanStackDevtoolsViteConfig = {
12-
/** The directory where the react router app is located. Defaults to the "./src" relative to where vite.config is being defined. */
13-
appDir?: string
1412
/**
1513
* Configuration for the editor integration. Defaults to opening in VS code
1614
*/
@@ -46,7 +44,6 @@ export const defineDevtoolsConfig = (config: TanStackDevtoolsViteConfig) =>
4644

4745
export const devtools = (args?: TanStackDevtoolsViteConfig): Array<Plugin> => {
4846
let port = 5173
49-
const appDir = args?.appDir || './src'
5047
const enhancedLogsConfig = args?.enhancedLogs ?? { enabled: true }
5148
const injectSourceConfig = args?.injectSource ?? { enabled: true }
5249
const bus = new ServerEventBus(args?.eventBusConfig)
@@ -94,14 +91,15 @@ export const devtools = (args?: TanStackDevtoolsViteConfig): Array<Plugin> => {
9491
})
9592

9693
const editor = args?.editor ?? DEFAULT_EDITOR_CONFIG
97-
const openInEditor = async (
98-
path: string | undefined,
99-
lineNum: string | undefined,
94+
const openInEditor: EditorConfig['open'] = async (
95+
path,
96+
lineNum,
97+
columnNum,
10098
) => {
10199
if (!path) {
102100
return
103101
}
104-
await editor.open(path, lineNum)
102+
await editor.open(path, lineNum, columnNum)
105103
}
106104
server.middlewares.use((req, res, next) =>
107105
handleDevToolsViteRequest(req, res, next, (parsedData) => {
@@ -110,7 +108,6 @@ export const devtools = (args?: TanStackDevtoolsViteConfig): Array<Plugin> => {
110108
return handleOpenSource({
111109
data: { type: data.type, data },
112110
openInEditor,
113-
appDir,
114111
})
115112
}
116113
return

packages/devtools-vite/src/utils.ts

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@ export const handleDevToolsViteRequest = (
1111
if (req.url?.includes('__tsd/open-source')) {
1212
const searchParams = new URLSearchParams(req.url.split('?')[1])
1313
const source = searchParams.get('source')
14-
const line = searchParams.get('line')
15-
const column = searchParams.get('column')
14+
if (!source) {
15+
return
16+
}
17+
const [file, line, column] = source.split(':')
18+
1619
cb({
1720
type: 'open-source',
1821
routine: 'open-source',
1922
data: {
20-
source: source
21-
? normalizePath(`${process.cwd()}/${source}`)
22-
: undefined,
23+
source: file ? normalizePath(`${process.cwd()}/${file}`) : undefined,
2324
line,
2425
column,
2526
},
@@ -46,25 +47,3 @@ export const handleDevToolsViteRequest = (
4647
res.write('OK')
4748
})
4849
}
49-
50-
export async function checkPath(
51-
routePath: string,
52-
extensions = ['.tsx', '.jsx', '.ts', '.js'],
53-
) {
54-
const fs = await import('node:fs')
55-
// Check if the path exists as a directory
56-
if (fs.existsSync(routePath) && fs.lstatSync(routePath).isDirectory()) {
57-
return { validPath: routePath, type: 'directory' } as const
58-
}
59-
60-
// Check if the path exists as a file with one of the given extensions
61-
for (const ext of extensions) {
62-
const filePath = `${routePath}${ext}`
63-
if (fs.existsSync(filePath) && fs.lstatSync(filePath).isFile()) {
64-
return { validPath: filePath, type: 'file' } as const
65-
}
66-
}
67-
68-
// If neither a file nor a directory is found
69-
return null
70-
}

0 commit comments

Comments
 (0)