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
4 changes: 2 additions & 2 deletions packages/network-debugger/src/core/fork.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ vi.mock('ws', () => {

function MockWebSocket(this: EventEmitter) {
EventEmitter.call(this)
this.send = mockWsSend
this.terminate = mockWsTerminate
(this as any).send = mockWsSend
(this as any).terminate = mockWsTerminate
const originalRemoveAllListeners = this.removeAllListeners.bind(this)
this.removeAllListeners = function () {
mockWsRemoveAllListeners()
Expand Down
58 changes: 57 additions & 1 deletion packages/network-debugger/src/core/fork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import WebSocket from 'ws'
import { ChildProcess, fork } from 'child_process'
import { __dirname } from '../common'
import { resolve as resolvePath } from 'path'
import { IS_DEV_MODE } from '../common'
import { RegisterOptions } from '../common'
import fs from 'fs'
import { sleep, checkMainProcessAlive } from '../utils/process'
Expand All @@ -26,9 +27,39 @@ export class MainProcess {
private ws: Promise<WebSocket>
private options: RegisterOptions
private cp?: ChildProcess
private nativeNetwork?: any

constructor(props: RegisterOptions & { key: string }) {
this.options = props
this.options = { ...props }

try {
const inspector = require('inspector')
// Check if native inspector is active and supports Network
if (inspector.url() && inspector.Network) {
warn(`[Network Debugger] Detected native Node inspector. Hijacking inspector.Network to forward CDP events to native DevTools.`)
this.nativeNetwork = { ...inspector.Network }
// Disable native network tracking to prevent duplicate logs
const methods = [
'requestWillBeSent',
'responseReceived',
'loadingFinished',
'loadingFailed',
'dataSent',
'dataReceived'
]
methods.forEach((method) => {
if (typeof (inspector.Network as any)[method] === 'function') {
;(inspector.Network as any)[method] = () => {}
}
})

// Since the user is already connected to native devtools, don't open a new browser
this.options.autoOpenDevtool = false
}
} catch (e) {
warn(`[Network Debugger] Error during native inspector setup: ${e}`)
}

this.ws = new Promise<WebSocket>(async (resolve, reject) => {
const lockFilePath = resolvePath(__dirname, `./${props.key}`)
if (fs.existsSync(lockFilePath)) {
Expand All @@ -50,15 +81,40 @@ export class MainProcess {
}
fs.writeFileSync(lockFilePath, `${process.pid}`)
const socket = new WebSocket(`ws://localhost:${props.port}`)
const setupSocket = (s: WebSocket) => {
s.on('message', (msg) => {
try {
const data = JSON.parse(msg.toString())
if (data.type === 'cdp' && this.nativeNetwork) {
const { method, params } = data.data
if (method && method.startsWith('Network.')) {
const methodName = method.split('.')[1]
if (typeof this.nativeNetwork[methodName] === 'function') {
try {
this.nativeNetwork[methodName](params)
} catch (err) {
warn(`[Network Debugger] Native network forwarding error for method ${method}: ${err}`)
}
}
}
}
} catch (e) {
// ignore JSON parse errors
}
})
}

socket.on('open', () => {
unlinkSafe(lockFilePath)
setupSocket(socket)
resolve(socket)
})
socket.on('error', () => {
this.openProcess(() => {
unlinkSafe(lockFilePath)
const socket = new WebSocket(`ws://localhost:${props.port}`)
socket.on('open', () => {
setupSocket(socket)
resolve(socket)
})
socket.on('error', reject)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('CDP Protocol Correctness Tests', () => {
const messages: Array<{ method: string; timestamp?: number }> = []

// 模拟 devtool.send 收集消息
const mockSend = vi.fn((msg: { method?: string; params?: { timestamp?: number } }) => {
const mockSend = vi.fn((msg: any) => {
if (msg.method) {
messages.push({
method: msg.method,
Expand Down
9 changes: 8 additions & 1 deletion packages/network-debugger/src/fork/devtool/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface DevtoolServerInitOptions {
autoOpenDevtool?: boolean
onConnect?: () => void
onClose?: () => void
onSend?: (message: DevtoolMessage) => void
}

export interface IDevtoolServer {
Expand All @@ -26,10 +27,13 @@ export class DevtoolServer extends BaseDevtoolServer implements IDevtoolServer {
private browser: ChildProcess | null = null
private socket: Promise<[WebSocket]>

private onSend?: (message: DevtoolMessage) => void

constructor(props: DevtoolServerInitOptions) {
super()
const { port, autoOpenDevtool = true, onConnect, onClose } = props
const { port, autoOpenDevtool = true, onConnect, onClose, onSend } = props
this.port = port
this.onSend = onSend
this.server = new Server({ port })
const { server } = this

Expand Down Expand Up @@ -135,6 +139,9 @@ export class DevtoolServer extends BaseDevtoolServer implements IDevtoolServer {
}

async send(message: DevtoolMessage) {
if (this.onSend) {
this.onSend(message)
}
const [socket] = await this.socket
return socket.send(JSON.stringify(message))
}
Expand Down
56 changes: 28 additions & 28 deletions packages/network-debugger/src/fork/module/common.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,14 @@ describe('fork/module/common.ts', () => {
const plugins = [plugin]

const result = plugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins
})

expect(pluginFn).toHaveBeenCalledWith({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins
})
expect(result).toEqual({ result: 'test' })
Expand All @@ -123,8 +123,8 @@ describe('fork/module/common.ts', () => {
const mockCore = createMockCore()

const result = plugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [plugin]
})

Expand All @@ -142,8 +142,8 @@ describe('fork/module/common.ts', () => {
const mockCore = createMockCore()

const result = plugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [plugin]
})

Expand All @@ -165,8 +165,8 @@ describe('fork/module/common.ts', () => {
const mockCore = createMockCore()

plugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [plugin]
})

Expand Down Expand Up @@ -198,8 +198,8 @@ describe('fork/module/common.ts', () => {
const mockCore = createMockCore()

plugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [plugin]
})

Expand All @@ -222,8 +222,8 @@ describe('fork/module/common.ts', () => {
const mockCore = createMockCore()

plugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [plugin]
})

Expand All @@ -246,8 +246,8 @@ describe('fork/module/common.ts', () => {
const mockCore = createMockCore()

plugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [plugin]
})

Expand Down Expand Up @@ -279,8 +279,8 @@ describe('fork/module/common.ts', () => {
const mockCore = createMockCore()

plugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [plugin]
})

Expand Down Expand Up @@ -313,8 +313,8 @@ describe('fork/module/common.ts', () => {
const mockCore = createMockCore()

plugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [plugin]
})

Expand Down Expand Up @@ -346,14 +346,14 @@ describe('fork/module/common.ts', () => {
const plugins = [plugin1, plugin2]

plugin1({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins
})

plugin2({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins
})

Expand All @@ -378,8 +378,8 @@ describe('fork/module/common.ts', () => {
const mockCore = createMockCore()

plugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [plugin]
})

Expand All @@ -403,8 +403,8 @@ describe('fork/module/common.ts', () => {
const plugins = [plugin]

plugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins
})

Expand Down
20 changes: 10 additions & 10 deletions packages/network-debugger/src/fork/module/health/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ describe('fork/module/health/index.ts', () => {
const mockCore = createMockCore()

healthPlugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [healthPlugin]
})

Expand All @@ -116,8 +116,8 @@ describe('fork/module/health/index.ts', () => {
const mockCore = createMockCore()

healthPlugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [healthPlugin]
})

Expand All @@ -134,8 +134,8 @@ describe('fork/module/health/index.ts', () => {
const mockCore = createMockCore()

healthPlugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [healthPlugin]
})

Expand Down Expand Up @@ -166,8 +166,8 @@ describe('fork/module/health/index.ts', () => {
const mockCore = createMockCore()

healthPlugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [healthPlugin]
})

Expand Down Expand Up @@ -196,8 +196,8 @@ describe('fork/module/health/index.ts', () => {
const mockCore = createMockCore()

healthPlugin({
devtool: mockDevtool,
core: mockCore,
devtool: mockDevtool as any,
core: mockCore as any,
plugins: [healthPlugin]
})

Expand Down
Loading