Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,4 @@ tmp/
bundle/

# in debugging we frequently dump wasm to wat with `wasm-tools print`
*.wat
*.wat
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ members = [
"packages/hooks",
"packages/html-internal-macro",
"packages/html",
"packages/inspector",
"packages/inspector-macros",
"packages/interpreter",
"packages/lazy-js-bundle",
"packages/liveview",
Expand Down Expand Up @@ -70,6 +72,8 @@ members = [
"packages/asset-resolver",
"packages/depinfo",
"packages/component-manifest",
"packages/inspector",
"packages/inspector-macros",

# CLI harnesses, all included
"packages/cli-harnesses/*",
Expand Down Expand Up @@ -158,6 +162,8 @@ dioxus-history = { path = "packages/history", version = "0.7.1", default-feature
dioxus-html = { path = "packages/html", version = "0.7.1", default-features = false }
dioxus-html-internal-macro = { path = "packages/html-internal-macro", version = "0.7.1" }
dioxus-hooks = { path = "packages/hooks", version = "0.7.1" }
dioxus-inspector = { path = "packages/inspector", version = "0.1.0", default-features = false }
dioxus-inspector-macros = { path = "packages/inspector-macros", version = "0.1.0" }
dioxus-web = { path = "packages/web", version = "0.7.1", default-features = false }
dioxus-ssr = { path = "packages/ssr", version = "0.7.1", default-features = false }
dioxus-desktop = { path = "packages/desktop", version = "0.7.1", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions packages/dioxus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ macro = ["dep:dioxus-core-macro"]
html = ["dep:dioxus-html"]
hooks = ["dep:dioxus-hooks"]
devtools = ["dep:dioxus-devtools", "dioxus-web?/devtools"]
inspector = ["dioxus-web?/inspector"]
mounted = ["dioxus-web?/mounted"]
asset = ["dep:manganis", "dep:dioxus-asset-resolver"]
document = ["dioxus-web?/document", "dep:dioxus-document", "dep:dioxus-history"]
Expand Down
11 changes: 11 additions & 0 deletions packages/inspector-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "dioxus-inspector-macros"
version = "0.1.0"
edition = "2024"
description = "Attribute macros for annotating Dioxus components with inspector metadata"
license = "MIT OR Apache-2.0"

[lib]
proc-macro = true

[dependencies]
9 changes: 9 additions & 0 deletions packages/inspector-macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//! Attribute macro stubs for the inspector runtime.

use proc_macro::TokenStream;

/// Placeholder attribute so existing `#[inspector]` usages continue to compile.
#[proc_macro_attribute]
pub fn inspector(_args: TokenStream, input: TokenStream) -> TokenStream {
input
}
2 changes: 2 additions & 0 deletions packages/inspector/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/target
Cargo.lock
38 changes: 38 additions & 0 deletions packages/inspector/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[package]
name = "dioxus-inspector"
version = "0.1.0"
edition = "2024"
description = "Inspector tooling for Dioxus applications"
license = "MIT OR Apache-2.0"

[features]
default = []
client = ["dep:wasm-bindgen", "dep:wasm-bindgen-futures", "dep:web-sys"]
server = ["dep:reqwest"]

[dependencies]
dioxus-inspector-macros = { path = "../inspector-macros" }
reqwest = { version = "0.12", optional = true, features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
wasm-bindgen = { version = "0.2", optional = true, features = ["serde-serialize"] }
wasm-bindgen-futures = { version = "0.4", optional = true }
web-sys = { version = "0.3", optional = true, features = [
"Document",
"Element",
"HtmlDivElement",
"HtmlElement",
"CssStyleDeclaration",
"Window",
"MouseEvent",
"KeyboardEvent",
"Event",
"EventTarget",
"DomRect",
"Request",
"RequestInit",
"RequestMode",
"Response",
"Headers",
"console",
] }
221 changes: 221 additions & 0 deletions packages/inspector/README.ko.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
# Dioxus Inspector / λ””μ˜₯μ„œμŠ€ μΈμŠ€νŽ™ν„°

> Click a rendered element (Cmd/Ctrl + Shift + Click) and jump straight to the original Rust source line in your IDE.
> λ Œλ”λœ μš”μ†Œλ₯Ό **Cmd/Ctrl + Shift + Click** ν•˜λ©΄ IDEμ—μ„œ 원본 μ†ŒμŠ€ 라인으둜 λ°”λ‘œ μ΄λ™ν•©λ‹ˆλ‹€.

## πŸš€ λΉ λ₯Έ μ‹œμž‘

### 1. μ˜μ‘΄μ„± μΆ”κ°€ (이미 μ™„λ£Œλ¨)

```toml
# Cargo.toml
[dependencies]
dioxus-inspector = { path = "../../crates/dioxus/packages/inspector", features = ["client"] }

[features]
inspector = ["dioxus-inspector"]
```

### 2. μ»΄ν¬λ„ŒνŠΈ μ„€μ •

```rust
use dioxus::prelude::*;
use dioxus_inspector::InspectorClient;

#[component]
pub fn App() -> Element {
#[cfg(feature = "inspector")]
{
use_effect(|| {
if let Err(err) = InspectorClient::new("http://127.0.0.1:41235").install() {
tracing::warn!(?err, "Inspector client failed to initialize");
}
|| {}
});
}

rsx! {
div {
class: "app",
"Hello World"
}
}
}
```

### 3. Server μ‹€ν–‰

```bash
# Terminal 1: Inspector Server
npm run dev:inspector

# Terminal 2: Dioxus App (Web)
cd apps/metacity-server
dx serve --features inspector

# (선택) Desktop/Tauri
cargo tauri dev --features inspector
```

### 4. μ‚¬μš©ν•˜κΈ°

1. λΈŒλΌμš°μ €μ—μ„œ μ•± μ—΄κΈ°
2. **Cmd+Shift+Click** (λ˜λŠ” Ctrl+Shift+Click)
3. μ»΄ν¬λ„ŒνŠΈ 클릭
4. IDEκ°€ μžλ™μœΌλ‘œ μ—΄λ¦Ό! (VSCode, Cursor, Windsurf, JetBrains λ“± λŒ€λΆ€λΆ„ CLI 지원 IDE)

## πŸ“ 상세 μ‚¬μš©λ²•

### DOM λ©”νƒ€λ°μ΄ν„°λŠ” μžλ™ μ‚½μž…

`dx serve --features inspector` 처럼 **Debug λΉŒλ“œ**λ₯Ό μ‹€ν–‰ν•˜λ©΄ Dioxus λ§€ν¬λ‘œκ°€ λͺ¨λ“  DOM μš”μ†Œμ— `data-inspector` 속성을 μžλ™μœΌλ‘œ μΆ”κ°€ν•©λ‹ˆλ‹€. (파일 경둜, 쀄, μ—΄ 정보 포함)
λ”°λΌμ„œ 더 이상 `data_inspector` 속성을 직접 μž‘μ„±ν•  ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.

### 쑰건뢀 컴파일

- **Debug λΉŒλ“œ**: Inspector ν™œμ„±ν™”
- **Release λΉŒλ“œ**: μžλ™μœΌλ‘œ 제거 (μ„±λŠ₯ 영ν–₯ 0)

```bash
# Debug (inspector 포함)
dx serve --features inspector

# Release (inspector μ œμ™Έ)
dx build --release
```

## 🎯 IDE 지원 / Supported IDEs

- VSCode / Code Insiders
- Cursor
- Windsurf
- WebStorm / IntelliJ / Fleet (JetBrains)
- 기타 `--goto file:line[:column]` ν˜•νƒœμ˜ CLIλ₯Ό μ œκ³΅ν•˜λŠ” IDE (μ»€μŠ€ν…€ λͺ…λ Ή μΆ”κ°€ κ°€λŠ₯)

Inspector serverλŠ” ν™˜κ²½λ³€μˆ˜(`EDITOR`, `TERM_PROGRAM`), μ‹€ν–‰ 쀑인 ν”„λ‘œμ„ΈμŠ€, CLI 쑴재 μ—¬λΆ€(`which`, `where`)λ₯Ό ν™œμš©ν•΄ IDEλ₯Ό κ°μ§€ν•©λ‹ˆλ‹€. ν•„μš”ν•˜λ©΄ `scripts/inspector-server.js`μ—μ„œ 감지 μˆœμ„œλ₯Ό μ»€μŠ€ν„°λ§ˆμ΄μ§•ν•˜μ„Έμš”.

## πŸ”§ μ„€μ • / μ»€μŠ€ν„°λ§ˆμ΄μ§•

### λ‹€λ₯Έ 포트 μ‚¬μš©

```rust
const INSPECTOR_ENDPOINT: &str = "http://127.0.0.1:8888";

InspectorClient::new(INSPECTOR_ENDPOINT).install()
```

Server도 λ™μΌν•œ 포트둜:
```javascript
// scripts/inspector-server.js
const PORT = 8888;
```

### μ»€μŠ€ν…€ 단좕킀

```rust
use dioxus_inspector::client::ClickModifier;

let client = InspectorClient::new(endpoint)
.with_modifier(ClickModifier {
meta: false, // Cmd/Ctrl λΆˆν•„μš”
shift: true, // Shift만 ν•„μš”
});
```

## πŸ› 문제 ν•΄κ²°

### 클릭해도 λ°˜μ‘ μ—†μŒ
```bash
# 1. Inspector server μ‹€ν–‰ 쀑인지 확인
npm run dev:inspector

# 2. λΈŒλΌμš°μ € μ½˜μ†” 확인
# "Inspector client installed" λ©”μ‹œμ§€ μžˆμ–΄μ•Ό 함
```

### IDEκ°€ μ•ˆ μ—΄λ¦Ό
```bash
# 1. Server 둜그 확인
[Inspector] Opening: code --goto /path/to/file.rs:42:1

# 2. IDE CLI μ„€μΉ˜ 확인
which windsurf # λ˜λŠ” code, cursor

# 3. μˆ˜λ™μœΌλ‘œ ν…ŒμŠ€νŠΈ
windsurf --goto /path/to/file.rs:42:1
```

### CORS μ—λŸ¬
β†’ `inspector-server.js`에 이미 CORS 섀정됨. 포트 확인.

## πŸ“š μ•„ν‚€ν…μ²˜ / Architecture

```
Browser (WASM) Dev Server (Node.js) IDE
β”‚ β”‚ β”‚
β”‚ Cmd/Ctrl+Shift+Click β”‚ β”‚
│──────────────────────────────>β”‚ β”‚
β”‚ β”‚ β”‚
β”‚ POST /api/inspector/open β”‚ spawn('code'/'cursor') β”‚
β”‚ { file, line, column } │─────────────────────────>β”‚
β”‚ β”‚ β”‚
β”‚ ← 200 OK β”‚ β”‚
β”‚ β”‚ File opens!
```

## 🎨 예제 / Example

`apps/metacity-server/src/components/app.rs`μ—μ„œ μ‹€μ „ μ˜ˆμ‹œλ₯Ό λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€. μ•„λž˜μ™€ 같이 InspectorClient만 μ΄ˆκΈ°ν™”ν•˜λ©΄ DOM λ…Έλ“œμ—λŠ” μžλ™μœΌλ‘œ 메타데이터가 μ£Όμž…λ©λ‹ˆλ‹€.

```rust
#[cfg(feature = "inspector")]
use dioxus_inspector::InspectorClient;

#[component]
pub fn App() -> Element {
#[cfg(feature = "inspector")]
use_effect(|| {
InspectorClient::new("http://127.0.0.1:41235/api/inspector/open")
.install()
.ok();
|| {}
});

rsx! { div { class: "app", "Hello" } }
}
```

Debug λͺ¨λ“œμ—μ„œ RSX λ§€ν¬λ‘œκ°€ λͺ¨λ“  λ…Έλ“œμ— `data-inspector` 속성을 μžλ™μœΌλ‘œ λΆ€μ—¬ν•©λ‹ˆλ‹€.

## βœ… CI / 검증 방법

Inspectorκ°€ Dioxus fork 내뢀에 ν¬ν•¨λ˜μ–΄ μžˆμœΌλ―€λ‘œ, CIμ—μ„œ λ‹€μŒ λͺ…령듀을 톡해 νšŒκ·€λ₯Ό 막을 수 μžˆμŠ΅λ‹ˆλ‹€.

1. **FMT & Clippy**
```bash
cargo fmt --workspace -- packages/rsx/src/element.rs packages/inspector packages/inspector-macros
cargo clippy -p dioxus-inspector -p dioxus-inspector-macros --all-features -- -D warnings
```

2. **WASM λΉŒλ“œ 검사** (λΈŒλΌμš°μ € ν΄λΌμ΄μ–ΈνŠΈ 확인)
```bash
cargo check -p dioxus-inspector --features client --target wasm32-unknown-unknown
```

3. **Downstream Smoke Test** (예: POS-agent)
```bash
cd apps/metacity-server
cargo check --features inspector
# or run dx serve in CI with xvfb if 톡합 ν…ŒμŠ€νŠΈκ°€ ν•„μš”
```

4. **Inspector Server Lint (선택)**
```bash
npm run lint -- scripts/inspector-server.js
```

이 검증 절차λ₯Ό CI νŒŒμ΄ν”„λΌμΈμ— λ„£μœΌλ©΄ Inspector κ΄€λ ¨ 변경이 듀어와도 μ•ˆμ •μ μœΌλ‘œ λ™μž‘ν•˜λŠ”μ§€ λΉ λ₯΄κ²Œ 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

## πŸ“„ λΌμ΄μ„ μŠ€

MIT OR Apache-2.0
Loading