Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
bit-pm
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
燕伟桐
bit-pm
Commits
79b7f865
Unverified
提交
79b7f865
authored
5月 02, 2025
作者:
Will Chen
提交者:
GitHub
5月 02, 2025
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Emit clean stack traces from iframe (#63)
上级
1bbfedc6
显示空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
505 行增加
和
327 行删除
+505
-327
dyad-shim.js
scaffold/dyad-shim.js
+185
-0
package.json
scaffold/package.json
+4
-2
pnpm-lock.yaml
scaffold/pnpm-lock.yaml
+238
-132
vite.config.ts
scaffold/vite.config.ts
+59
-174
PreviewIframe.tsx
src/components/preview_panel/PreviewIframe.tsx
+19
-19
没有找到文件。
scaffold/dyad-shim.js
0 → 100644
浏览文件 @
79b7f865
(
function
()
{
const
isInsideIframe
=
window
.
parent
!==
window
;
if
(
!
isInsideIframe
)
return
;
let
previousUrl
=
window
.
location
.
href
;
const
PARENT_TARGET_ORIGIN
=
"*"
;
// --- History API Overrides ---
const
originalPushState
=
history
.
pushState
;
const
originalReplaceState
=
history
.
replaceState
;
const
handleStateChangeAndNotify
=
(
originalMethod
,
state
,
title
,
url
)
=>
{
const
oldUrlForMessage
=
previousUrl
;
let
newUrl
;
try
{
newUrl
=
url
?
new
URL
(
url
,
window
.
location
.
href
).
href
:
window
.
location
.
href
;
}
catch
(
e
)
{
newUrl
=
window
.
location
.
href
;
}
const
navigationType
=
originalMethod
===
originalPushState
?
"pushState"
:
"replaceState"
;
try
{
// Pass the original state directly
originalMethod
.
call
(
history
,
state
,
title
,
url
);
previousUrl
=
window
.
location
.
href
;
window
.
parent
.
postMessage
(
{
type
:
navigationType
,
payload
:
{
oldUrl
:
oldUrlForMessage
,
newUrl
:
newUrl
},
},
PARENT_TARGET_ORIGIN
);
}
catch
(
e
)
{
console
.
error
(
`[vite-dev-plugin] Error calling original
${
navigationType
}
: `
,
e
);
window
.
parent
.
postMessage
(
{
type
:
"navigation-error"
,
payload
:
{
operation
:
navigationType
,
message
:
e
.
message
,
error
:
e
.
toString
(),
stateAttempted
:
state
,
urlAttempted
:
url
,
},
},
PARENT_TARGET_ORIGIN
);
}
};
history
.
pushState
=
function
(
state
,
title
,
url
)
{
handleStateChangeAndNotify
(
originalPushState
,
state
,
title
,
url
);
};
history
.
replaceState
=
function
(
state
,
title
,
url
)
{
handleStateChangeAndNotify
(
originalReplaceState
,
state
,
title
,
url
);
};
// --- Listener for Back/Forward Navigation (popstate event) ---
window
.
addEventListener
(
"popstate"
,
(
event
)
=>
{
const
currentUrl
=
window
.
location
.
href
;
previousUrl
=
currentUrl
;
});
// --- Listener for Commands from Parent ---
window
.
addEventListener
(
"message"
,
(
event
)
=>
{
if
(
event
.
source
!==
window
.
parent
||
!
event
.
data
||
typeof
event
.
data
!==
"object"
)
return
;
if
(
event
.
data
.
type
===
"navigate"
)
{
const
direction
=
event
.
data
.
payload
?.
direction
;
if
(
direction
===
"forward"
)
history
.
forward
();
else
if
(
direction
===
"backward"
)
history
.
back
();
}
});
// --- Sourcemapped Error Handling ---
function
sendSourcemappedErrorToParent
(
error
,
sourceType
)
{
if
(
typeof
window
.
StackTrace
===
"undefined"
)
{
console
.
error
(
"[vite-dev-plugin] StackTrace object not found."
);
// Send simplified raw data if StackTrace isn't available
window
.
parent
.
postMessage
(
{
type
:
sourceType
,
payload
:
{
message
:
error
?.
message
||
String
(
error
),
stack
:
error
?.
stack
||
"<no stack available - StackTrace.js missing>"
,
},
},
PARENT_TARGET_ORIGIN
);
return
;
}
window
.
StackTrace
.
fromError
(
error
)
.
then
((
stackFrames
)
=>
{
const
sourcemappedStack
=
stackFrames
.
map
((
sf
)
=>
sf
.
toString
())
.
join
(
"
\
n"
);
const
payload
=
{
message
:
error
?.
message
||
String
(
error
),
stack
:
sourcemappedStack
,
};
window
.
parent
.
postMessage
(
{
type
:
"iframe-sourcemapped-error"
,
payload
:
{
...
payload
,
originalSourceType
:
sourceType
},
},
PARENT_TARGET_ORIGIN
);
})
.
catch
((
mappingError
)
=>
{
console
.
error
(
"[vite-dev-plugin] Error during stacktrace sourcemapping:"
,
mappingError
);
const
payload
=
{
message
:
error
?.
message
||
String
(
error
),
// Provide the raw stack or an indication of mapping failure
stack
:
error
?.
stack
?
`Sourcemapping failed:
${
mappingError
.
message
}
\n--- Raw Stack ---\n
${
error
.
stack
}
`
:
`Sourcemapping failed:
${
mappingError
.
message
}
\n<no raw stack available>`
,
};
window
.
parent
.
postMessage
(
{
type
:
"iframe-sourcemapped-error"
,
payload
:
{
...
payload
,
originalSourceType
:
sourceType
},
},
PARENT_TARGET_ORIGIN
);
});
}
window
.
addEventListener
(
"error"
,
(
event
)
=>
{
let
error
=
event
.
error
;
if
(
!
(
error
instanceof
Error
))
{
window
.
parent
.
postMessage
(
{
type
:
"window-error"
,
payload
:
{
message
:
error
.
toString
(),
stack
:
"<no stack available - an improper error was thrown>"
,
},
},
PARENT_TARGET_ORIGIN
);
return
;
}
sendSourcemappedErrorToParent
(
error
,
"window-error"
);
});
window
.
addEventListener
(
"unhandledrejection"
,
(
event
)
=>
{
let
error
=
event
.
reason
;
if
(
!
(
error
instanceof
Error
))
{
window
.
parent
.
postMessage
(
{
type
:
"unhandled-rejection"
,
payload
:
{
message
:
event
.
reason
.
toString
(),
stack
:
"<no stack available - an improper error was thrown (promise)>"
,
},
},
PARENT_TARGET_ORIGIN
);
return
;
}
sendSourcemappedErrorToParent
(
error
,
"unhandled-rejection"
);
});
})();
scaffold/package.json
浏览文件 @
79b7f865
...
...
@@ -56,6 +56,7 @@
"react-router-dom"
:
"^6.26.2"
,
"recharts"
:
"^2.12.7"
,
"sonner"
:
"^1.5.0"
,
"stacktrace-js"
:
"^2.0.2"
,
"tailwind-merge"
:
"^2.5.2"
,
"tailwindcss-animate"
:
"^1.0.7"
,
"vaul"
:
"^0.9.3"
,
...
...
@@ -67,7 +68,7 @@
"@types/node"
:
"^22.5.5"
,
"@types/react"
:
"^18.3.3"
,
"@types/react-dom"
:
"^18.3.0"
,
"@vitejs/plugin-react-swc"
:
"^3.
5
.0"
,
"@vitejs/plugin-react-swc"
:
"^3.
9
.0"
,
"autoprefixer"
:
"^10.4.20"
,
"eslint"
:
"^9.9.0"
,
"eslint-plugin-react-hooks"
:
"^5.1.0-rc.0"
,
...
...
@@ -77,6 +78,6 @@
"tailwindcss"
:
"^3.4.11"
,
"typescript"
:
"^5.5.3"
,
"typescript-eslint"
:
"^8.0.1"
,
"vite"
:
"^
5.4.1
"
"vite"
:
"^
6.3.4
"
}
}
\ No newline at end of file
scaffold/pnpm-lock.yaml
浏览文件 @
79b7f865
...
...
@@ -143,6 +143,9 @@ importers:
sonner
:
specifier
:
^1.5.0
version
:
1.7.4(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
stacktrace-js
:
specifier
:
^2.0.2
version
:
2.0.2
tailwind-merge
:
specifier
:
^2.5.2
version
:
2.6.0
...
...
@@ -172,8 +175,8 @@ importers:
specifier
:
^18.3.0
version
:
18.3.6(@types/react@18.3.20)
'
@vitejs/plugin-react-swc'
:
specifier
:
^3.
5
.0
version
:
3.9.0(vite@
5.4.18(@types/node@22.14
.1))
specifier
:
^3.
9
.0
version
:
3.9.0(vite@
6.3.4(@types/node@22.14.1)(jiti@1.21.7)(yaml@2.7
.1))
autoprefixer
:
specifier
:
^10.4.20
version
:
10.4.21(postcss@8.5.3)
...
...
@@ -202,8 +205,8 @@ importers:
specifier
:
^8.0.1
version
:
8.30.1(eslint@9.24.0(jiti@1.21.7))(typescript@5.8.3)
vite
:
specifier
:
^
5.4.1
version
:
5.4.18(@types/node@22.14
.1)
specifier
:
^
6.3.4
version
:
6.3.4(@types/node@22.14.1)(jiti@1.21.7)(yaml@2.7
.1)
packages
:
...
...
@@ -215,141 +218,153 @@ packages:
resolution
:
{
integrity
:
sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==
}
engines
:
{
node
:
'
>=6.9.0'
}
'
@esbuild/aix-ppc64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZed
Q==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/aix-ppc64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqB
Q==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
ppc64
]
os
:
[
aix
]
'
@esbuild/android-arm64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/android-arm64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
XelR6MzjlZuBM4f5z2IQHK6LkK34Cvv6Rj2EntER3lwCBFdg6h2lKbtRjpTTsdEjD/WSe1q8UyPBXP1x3i/wYQ
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
arm64
]
os
:
[
android
]
'
@esbuild/android-arm@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/android-arm@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
PuwVXbnP87Tcff5I9ngV0lmiSu40xw1At6i3GsU77U7cjDDB4s0X2cyFuBiDa1SBk9DnvWwnGvVaGBqoFWPb7A
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
arm
]
os
:
[
android
]
'
@esbuild/android-x64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/android-x64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
ogtTpYHT/g1GWS/zKM0cc/tIebFjm1F9Aw1boQ2Y0eUQ+J89d0jFY//s9ei9jVIlkYi8AfOjiixcLJSGNSOAdQ
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
x64
]
os
:
[
android
]
'
@esbuild/darwin-arm64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/darwin-arm64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
eESK5yfPNTqpAmDfFWNsOhmIOaQA59tAcF/EfYvo5/QWQCzXn5iUSOnqt3ra3UdzBv073ykTtmeLJZGt3HhA+w
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
arm64
]
os
:
[
darwin
]
'
@esbuild/darwin-x64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/darwin-x64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
Kd8glo7sIZtwOLcPbW0yLpKmBNWMANZhrC1r6K++uDR2zyzb6AeOYtI6udbtabmQpFaxJ8uduXMAo1gs5ozz8A
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
x64
]
os
:
[
darwin
]
'
@esbuild/freebsd-arm64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/freebsd-arm64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
EJiyS70BYybOBpJth3M0KLOus0n+RRMKTYzhYhFeMwp7e/RaajXvP+BWlmEXNk6uk+KAu46j/kaQzr6au+JcIw
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
arm64
]
os
:
[
freebsd
]
'
@esbuild/freebsd-x64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZC
Q==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/freebsd-x64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
Q+wSjaLpGxYf7zC0kL0nDlhsfuFkoN+EXrx2KSB33RhinWzejOd6AvgmP5JbkgXKmjhmpfgKZq24pneodYqE8
Q==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
x64
]
os
:
[
freebsd
]
'
@esbuild/linux-arm64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/linux-arm64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
xCUgnNYhRD5bb1C1nqrDV1PfkwgbswTTBRbAd8aH5PhYzikdf/ddtsYyMXFfGSsb/6t6QaPSzxtbfAZr9uox4A
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
arm64
]
os
:
[
linux
]
'
@esbuild/linux-arm@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/linux-arm@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
dUOVmAUzuHy2ZOKIHIKHCm58HKzFqd+puLaS424h6I85GlSDRZIA5ycBixb3mFgM0Jdh+ZOSB6KptX30DD8YOQ
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
arm
]
os
:
[
linux
]
'
@esbuild/linux-ia32@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/linux-ia32@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
yplPOpczHOO4jTYKmuYuANI3WhvIPSVANGcNUeMlxH4twz/TeXuzEP41tGKNGWJjuMhotpGabeFYGAOU2ummBw
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
ia32
]
os
:
[
linux
]
'
@esbuild/linux-loong64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQS
g==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/linux-loong64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
P4BLP5/fjyihmXCELRGrLd793q/lBtKMQl8ARGpDxgzgIKJDRJ/u4r1A/HgpBpKpKZelGct2PGI4T+axcedf6
g==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
loong64
]
os
:
[
linux
]
'
@esbuild/linux-mips64el@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jb
g==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/linux-mips64el@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
eRAOV2ODpu6P5divMEMa26RRqb2yUoYsuQQOuFUexUoQndm4MdpXXDBbUoKIc0iPa4aCO7gIhtnYomkn2x+ba
g==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
mips64el
]
os
:
[
linux
]
'
@esbuild/linux-ppc64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/linux-ppc64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
ZC4jV2p7VbzTlnl8nZKLcBkfzIf4Yad1SJM4ZMKYnJqZFD4rTI+pBG65u8ev4jk3/MPwY9DvGn50wi3uhdaghg
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
ppc64
]
os
:
[
linux
]
'
@esbuild/linux-riscv64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDD
A==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/linux-riscv64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
LDDODcFzNtECTrUUbVCs6j9/bDVqy7DDRsuIXJg6so+mFksgwG7ZVnTruYi5V+z3eE5y+BJZw7VvUadkbfg7Q
A==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
riscv64
]
os
:
[
linux
]
'
@esbuild/linux-s390x@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/linux-s390x@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
s+w/NOY2k0yC2p9SLen+ymflgcpRkvwwa02fqmAwhBRI3SC12uiS10edHHXlVWwfAagYSY5UpmT/zISXPMW3tQ
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
s390x
]
os
:
[
linux
]
'
@esbuild/linux-x64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/linux-x64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
nQHDz4pXjSDC6UfOE1Fw9Q8d6GCAd9KdvMZpfVGWSJztYCarRgSDfOVBY5xwhQXseiyxapkiSJi/5/ja8mRFFA
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
x64
]
os
:
[
linux
]
'
@esbuild/netbsd-x64@0.21.5'
:
resolution
:
{
integrity
:
sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==
}
engines
:
{
node
:
'
>=12'
}
'
@esbuild/netbsd-arm64@0.25.3'
:
resolution
:
{
integrity
:
sha512-1QaLtOWq0mzK6tzzp0jRN3eccmN3hezey7mhLnzC6oNlJoUJz4nym5ZD7mDnS/LZQgkrhEbEiTn515lPeLpgWA==
}
engines
:
{
node
:
'
>=18'
}
cpu
:
[
arm64
]
os
:
[
netbsd
]
'
@esbuild/netbsd-x64@0.25.3'
:
resolution
:
{
integrity
:
sha512-i5Hm68HXHdgv8wkrt+10Bc50zM0/eonPb/a/OFVfB6Qvpiirco5gBA5bz7S2SHuU+Y4LWn/zehzNX14Sp4r27g==
}
engines
:
{
node
:
'
>=18'
}
cpu
:
[
x64
]
os
:
[
netbsd
]
'
@esbuild/openbsd-x64@0.21.5'
:
resolution
:
{
integrity
:
sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==
}
engines
:
{
node
:
'
>=12'
}
'
@esbuild/openbsd-arm64@0.25.3'
:
resolution
:
{
integrity
:
sha512-zGAVApJEYTbOC6H/3QBr2mq3upG/LBEXr85/pTtKiv2IXcgKV0RT0QA/hSXZqSvLEpXeIxah7LczB4lkiYhTAQ==
}
engines
:
{
node
:
'
>=18'
}
cpu
:
[
arm64
]
os
:
[
openbsd
]
'
@esbuild/openbsd-x64@0.25.3'
:
resolution
:
{
integrity
:
sha512-fpqctI45NnCIDKBH5AXQBsD0NDPbEFczK98hk/aa6HJxbl+UtLkJV2+Bvy5hLSLk3LHmqt0NTkKNso1A9y1a4w==
}
engines
:
{
node
:
'
>=18'
}
cpu
:
[
x64
]
os
:
[
openbsd
]
'
@esbuild/sunos-x64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/sunos-x64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
ROJhm7d8bk9dMCUZjkS8fgzsPAZEjtRJqCAmVgB0gMrvG7hfmPmz9k1rwO4jSiblFjYmNvbECL9uhaPzONMfgA
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
x64
]
os
:
[
sunos
]
'
@esbuild/win32-arm64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/win32-arm64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
YWcow8peiHpNBiIXHwaswPnAXLsLVygFwCB3A7Bh5jRkIBFWHGmNQ48AlX4xDvQNoMZlPYzjVOQDYEzWCqufMQ
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
arm64
]
os
:
[
win32
]
'
@esbuild/win32-ia32@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/win32-ia32@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
qspTZOIGoXVS4DpNqUYUs9UxVb04khS1Degaw/MnfMe7goQ3lTfQ13Vw4qY/Nj0979BGvMRpAYbs/BAxEvU8ew
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
ia32
]
os
:
[
win32
]
'
@esbuild/win32-x64@0.2
1.5
'
:
resolution
:
{
integrity
:
sha512-
tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw
==
}
engines
:
{
node
:
'
>=1
2
'
}
'
@esbuild/win32-x64@0.2
5.3
'
:
resolution
:
{
integrity
:
sha512-
ICgUR+kPimx0vvRzf+N/7L7tVSQeE3BYY+NhHRHXS1kBuPO7z2+7ea2HbhDyZdTephgvNvKrlDDKUexuCVBVvg
==
}
engines
:
{
node
:
'
>=1
8
'
}
cpu
:
[
x64
]
os
:
[
win32
]
...
...
@@ -1603,9 +1618,12 @@ packages:
emoji-regex@9.2.2
:
resolution
:
{
integrity
:
sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
}
esbuild@0.21.5
:
resolution
:
{
integrity
:
sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==
}
engines
:
{
node
:
'
>=12'
}
error-stack-parser@2.1.4
:
resolution
:
{
integrity
:
sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==
}
esbuild@0.25.3
:
resolution
:
{
integrity
:
sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==
}
engines
:
{
node
:
'
>=18'
}
hasBin
:
true
escalade@3.2.0
:
...
...
@@ -1692,6 +1710,14 @@ packages:
fastq@1.19.1
:
resolution
:
{
integrity
:
sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==
}
fdir@6.4.4
:
resolution
:
{
integrity
:
sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==
}
peerDependencies
:
picomatch
:
^3 || ^4
peerDependenciesMeta
:
picomatch
:
optional
:
true
file-entry-cache@8.0.0
:
resolution
:
{
integrity
:
sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==
}
engines
:
{
node
:
'
>=16.0.0'
}
...
...
@@ -1974,6 +2000,10 @@ packages:
resolution
:
{
integrity
:
sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
}
engines
:
{
node
:
'
>=8.6'
}
picomatch@4.0.2
:
resolution
:
{
integrity
:
sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
}
engines
:
{
node
:
'
>=12'
}
pify@2.3.0
:
resolution
:
{
integrity
:
sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==
}
engines
:
{
node
:
'
>=0.10.0'
}
...
...
@@ -2200,6 +2230,22 @@ packages:
resolution
:
{
integrity
:
sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
}
engines
:
{
node
:
'
>=0.10.0'
}
source-map@0.5.6
:
resolution
:
{
integrity
:
sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==
}
engines
:
{
node
:
'
>=0.10.0'
}
stack-generator@2.0.10
:
resolution
:
{
integrity
:
sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==
}
stackframe@1.3.4
:
resolution
:
{
integrity
:
sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==
}
stacktrace-gps@3.1.2
:
resolution
:
{
integrity
:
sha512-GcUgbO4Jsqqg6RxfyTHFiPxdPqF+3LFmQhm7MgCuYQOYuWyqxo5pwRPz5d/u6/WYJdEnWfK4r+jGbyD8TSggXQ==
}
stacktrace-js@2.0.2
:
resolution
:
{
integrity
:
sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==
}
string-width@4.2.3
:
resolution
:
{
integrity
:
sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
}
engines
:
{
node
:
'
>=8'
}
...
...
@@ -2256,6 +2302,10 @@ packages:
tiny-invariant@1.3.3
:
resolution
:
{
integrity
:
sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==
}
tinyglobby@0.2.13
:
resolution
:
{
integrity
:
sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==
}
engines
:
{
node
:
'
>=12.0.0'
}
to-regex-range@5.0.1
:
resolution
:
{
integrity
:
sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
}
engines
:
{
node
:
'
>=8.0'
}
...
...
@@ -2332,22 +2382,27 @@ packages:
victory-vendor@36.9.2
:
resolution
:
{
integrity
:
sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==
}
vite@
5.4.18
:
resolution
:
{
integrity
:
sha512-
1oDcnEp3lVyHCuQ2YFelM4Alm2o91xNoMncRm1U7S+JdYfYOvbiGZ3/CxGttrOu2M/KcGz7cRC2DoNUA6urmMA
==
}
engines
:
{
node
:
^18.0.0 ||
>=20
.0.0
}
vite@
6.3.4
:
resolution
:
{
integrity
:
sha512-
BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw
==
}
engines
:
{
node
:
^18.0.0 ||
^20.0.0 || >=22
.0.0
}
hasBin
:
true
peerDependencies
:
'
@types/node'
:
^18.0.0 || >=20.0.0
'
@types/node'
:
^18.0.0 || ^20.0.0 || >=22.0.0
jiti
:
'
>=1.21.0'
less
:
'
*'
lightningcss
:
^1.21.0
sass
:
'
*'
sass-embedded
:
'
*'
stylus
:
'
*'
sugarss
:
'
*'
terser
:
^5.4.0
terser
:
^5.16.0
tsx
:
^4.8.1
yaml
:
^2.4.2
peerDependenciesMeta
:
'
@types/node'
:
optional
:
true
jiti
:
optional
:
true
less
:
optional
:
true
lightningcss
:
...
...
@@ -2362,6 +2417,10 @@ packages:
optional
:
true
terser
:
optional
:
true
tsx
:
optional
:
true
yaml
:
optional
:
true
which@2.0.2
:
resolution
:
{
integrity
:
sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
}
...
...
@@ -2400,73 +2459,79 @@ snapshots:
dependencies
:
regenerator-runtime
:
0.14.1
'
@esbuild/aix-ppc64@0.21.5'
:
'
@esbuild/aix-ppc64@0.25.3'
:
optional
:
true
'
@esbuild/android-arm64@0.25.3'
:
optional
:
true
'
@esbuild/android-arm@0.25.3'
:
optional
:
true
'
@esbuild/android-
arm64@0.21.5
'
:
'
@esbuild/android-
x64@0.25.3
'
:
optional
:
true
'
@esbuild/
android-arm@0.21.5
'
:
'
@esbuild/
darwin-arm64@0.25.3
'
:
optional
:
true
'
@esbuild/
android-x64@0.21.5
'
:
'
@esbuild/
darwin-x64@0.25.3
'
:
optional
:
true
'
@esbuild/
darwin-arm64@0.21.5
'
:
'
@esbuild/
freebsd-arm64@0.25.3
'
:
optional
:
true
'
@esbuild/
darwin-x64@0.21.5
'
:
'
@esbuild/
freebsd-x64@0.25.3
'
:
optional
:
true
'
@esbuild/
freebsd-arm64@0.21.5
'
:
'
@esbuild/
linux-arm64@0.25.3
'
:
optional
:
true
'
@esbuild/
freebsd-x64@0.21.5
'
:
'
@esbuild/
linux-arm@0.25.3
'
:
optional
:
true
'
@esbuild/linux-
arm64@0.21.5
'
:
'
@esbuild/linux-
ia32@0.25.3
'
:
optional
:
true
'
@esbuild/linux-
arm@0.21.5
'
:
'
@esbuild/linux-
loong64@0.25.3
'
:
optional
:
true
'
@esbuild/linux-
ia32@0.21.5
'
:
'
@esbuild/linux-
mips64el@0.25.3
'
:
optional
:
true
'
@esbuild/linux-
loong64@0.21.5
'
:
'
@esbuild/linux-
ppc64@0.25.3
'
:
optional
:
true
'
@esbuild/linux-
mips64el@0.21.5
'
:
'
@esbuild/linux-
riscv64@0.25.3
'
:
optional
:
true
'
@esbuild/linux-
ppc64@0.21.5
'
:
'
@esbuild/linux-
s390x@0.25.3
'
:
optional
:
true
'
@esbuild/linux-
riscv64@0.21.5
'
:
'
@esbuild/linux-
x64@0.25.3
'
:
optional
:
true
'
@esbuild/
linux-s390x@0.21.5
'
:
'
@esbuild/
netbsd-arm64@0.25.3
'
:
optional
:
true
'
@esbuild/
linux-x64@0.21.5
'
:
'
@esbuild/
netbsd-x64@0.25.3
'
:
optional
:
true
'
@esbuild/
netbsd-x64@0.21.5
'
:
'
@esbuild/
openbsd-arm64@0.25.3
'
:
optional
:
true
'
@esbuild/openbsd-x64@0.2
1.5
'
:
'
@esbuild/openbsd-x64@0.2
5.3
'
:
optional
:
true
'
@esbuild/sunos-x64@0.2
1.5
'
:
'
@esbuild/sunos-x64@0.2
5.3
'
:
optional
:
true
'
@esbuild/win32-arm64@0.2
1.5
'
:
'
@esbuild/win32-arm64@0.2
5.3
'
:
optional
:
true
'
@esbuild/win32-ia32@0.2
1.5
'
:
'
@esbuild/win32-ia32@0.2
5.3
'
:
optional
:
true
'
@esbuild/win32-x64@0.2
1.5
'
:
'
@esbuild/win32-x64@0.2
5.3
'
:
optional
:
true
'
@eslint-community/eslint-utils@4.6.1(eslint@9.24.0(jiti@1.21.7))'
:
...
...
@@ -3498,10 +3563,10 @@ snapshots:
'
@typescript-eslint/types'
:
8.30.1
eslint-visitor-keys
:
4.2.0
'
@vitejs/plugin-react-swc@3.9.0(vite@
5.4.18(@types/node@22.14
.1))'
:
'
@vitejs/plugin-react-swc@3.9.0(vite@
6.3.4(@types/node@22.14.1)(jiti@1.21.7)(yaml@2.7
.1))'
:
dependencies
:
'
@swc/core'
:
1.11.21
vite
:
5.4.18(@types/node@22.14
.1)
vite
:
6.3.4(@types/node@22.14.1)(jiti@1.21.7)(yaml@2.7
.1)
transitivePeerDependencies
:
-
'
@swc/helpers'
...
...
@@ -3717,31 +3782,37 @@ snapshots:
emoji-regex@9.2.2
:
{}
esbuild@0.21.5
:
error-stack-parser@2.1.4
:
dependencies
:
stackframe
:
1.3.4
esbuild@0.25.3
:
optionalDependencies
:
'
@esbuild/aix-ppc64'
:
0.21.5
'
@esbuild/android-arm'
:
0.21.5
'
@esbuild/android-arm64'
:
0.21.5
'
@esbuild/android-x64'
:
0.21.5
'
@esbuild/darwin-arm64'
:
0.21.5
'
@esbuild/darwin-x64'
:
0.21.5
'
@esbuild/freebsd-arm64'
:
0.21.5
'
@esbuild/freebsd-x64'
:
0.21.5
'
@esbuild/linux-arm'
:
0.21.5
'
@esbuild/linux-arm64'
:
0.21.5
'
@esbuild/linux-ia32'
:
0.21.5
'
@esbuild/linux-loong64'
:
0.21.5
'
@esbuild/linux-mips64el'
:
0.21.5
'
@esbuild/linux-ppc64'
:
0.21.5
'
@esbuild/linux-riscv64'
:
0.21.5
'
@esbuild/linux-s390x'
:
0.21.5
'
@esbuild/linux-x64'
:
0.21.5
'
@esbuild/netbsd-x64'
:
0.21.5
'
@esbuild/openbsd-x64'
:
0.21.5
'
@esbuild/sunos-x64'
:
0.21.5
'
@esbuild/win32-arm64'
:
0.21.5
'
@esbuild/win32-ia32'
:
0.21.5
'
@esbuild/win32-x64'
:
0.21.5
'
@esbuild/aix-ppc64'
:
0.25.3
'
@esbuild/android-arm'
:
0.25.3
'
@esbuild/android-arm64'
:
0.25.3
'
@esbuild/android-x64'
:
0.25.3
'
@esbuild/darwin-arm64'
:
0.25.3
'
@esbuild/darwin-x64'
:
0.25.3
'
@esbuild/freebsd-arm64'
:
0.25.3
'
@esbuild/freebsd-x64'
:
0.25.3
'
@esbuild/linux-arm'
:
0.25.3
'
@esbuild/linux-arm64'
:
0.25.3
'
@esbuild/linux-ia32'
:
0.25.3
'
@esbuild/linux-loong64'
:
0.25.3
'
@esbuild/linux-mips64el'
:
0.25.3
'
@esbuild/linux-ppc64'
:
0.25.3
'
@esbuild/linux-riscv64'
:
0.25.3
'
@esbuild/linux-s390x'
:
0.25.3
'
@esbuild/linux-x64'
:
0.25.3
'
@esbuild/netbsd-arm64'
:
0.25.3
'
@esbuild/netbsd-x64'
:
0.25.3
'
@esbuild/openbsd-arm64'
:
0.25.3
'
@esbuild/openbsd-x64'
:
0.25.3
'
@esbuild/sunos-x64'
:
0.25.3
'
@esbuild/win32-arm64'
:
0.25.3
'
@esbuild/win32-ia32'
:
0.25.3
'
@esbuild/win32-x64'
:
0.25.3
escalade@3.2.0
:
{}
...
...
@@ -3846,6 +3917,10 @@ snapshots:
dependencies
:
reusify
:
1.1.0
fdir@6.4.4(picomatch@4.0.2)
:
optionalDependencies
:
picomatch
:
4.0.2
file-entry-cache@8.0.0
:
dependencies
:
flat-cache
:
4.0.1
...
...
@@ -4082,6 +4157,8 @@ snapshots:
picomatch@2.3.1
:
{}
picomatch@4.0.2
:
{}
pify@2.3.0
:
{}
pirates@4.0.7
:
{}
...
...
@@ -4312,6 +4389,25 @@ snapshots:
source-map-js@1.2.1
:
{}
source-map@0.5.6
:
{}
stack-generator@2.0.10
:
dependencies
:
stackframe
:
1.3.4
stackframe@1.3.4
:
{}
stacktrace-gps@3.1.2
:
dependencies
:
source-map
:
0.5.6
stackframe
:
1.3.4
stacktrace-js@2.0.2
:
dependencies
:
error-stack-parser
:
2.1.4
stack-generator
:
2.0.10
stacktrace-gps
:
3.1.2
string-width@4.2.3
:
dependencies
:
emoji-regex
:
8.0.0
...
...
@@ -4393,6 +4489,11 @@ snapshots:
tiny-invariant@1.3.3
:
{}
tinyglobby@0.2.13
:
dependencies
:
fdir
:
6.4.4(picomatch@4.0.2)
picomatch
:
4.0.2
to-regex-range@5.0.1
:
dependencies
:
is-number
:
7.0.0
...
...
@@ -4476,14 +4577,19 @@ snapshots:
d3-time
:
3.1.0
d3-timer
:
3.0.1
vite@
5.4.18(@types/node@22.14
.1)
:
vite@
6.3.4(@types/node@22.14.1)(jiti@1.21.7)(yaml@2.7
.1)
:
dependencies
:
esbuild
:
0.21.5
esbuild
:
0.25.3
fdir
:
6.4.4(picomatch@4.0.2)
picomatch
:
4.0.2
postcss
:
8.5.3
rollup
:
4.40.0
tinyglobby
:
0.2.13
optionalDependencies
:
'
@types/node'
:
22.14.1
fsevents
:
2.3.3
jiti
:
1.21.7
yaml
:
2.7.1
which@2.0.2
:
dependencies
:
...
...
scaffold/vite.config.ts
浏览文件 @
79b7f865
import
{
defineConfig
,
Plugin
}
from
"vite"
;
import
{
defineConfig
,
Plugin
,
HtmlTagDescriptor
}
from
"vite"
;
import
react
from
"@vitejs/plugin-react-swc"
;
import
path
from
"path"
;
import
fs
from
"fs"
;
export
function
devErrorAndNavigationPlugin
():
Plugin
{
let
stacktraceJsContent
:
string
|
null
=
null
;
let
dyadShimContent
:
string
|
null
=
null
;
return
{
name
:
"dev-error-and-navigation-handler"
,
apply
:
"serve"
,
transformIndexHtml
(
html
)
{
return
{
html
,
tags
:
[
{
tag
:
"script"
,
injectTo
:
"head"
,
children
:
`
(function() {
// Check if running inside an iframe immediately
const isInsideIframe = window.parent !== window;
if (!isInsideIframe) {
// If not in an iframe, no need for the rest of the script
// console.log('[vite-dev-navigation] Not inside an iframe. Skipping setup.');
return;
}
// Use a unique key for our timestamp to avoid conflicts (optional, but kept for state consistency)
const NAV_TIMESTAMP_KEY = '__viteDevNavTimestamp';
let previousUrl = window.location.href;
let lastNavigationTimestamp = Date.now(); // Initialize with current time
// --- Initial State Timestamp Setup (Optional but helps consistency) ---
configResolved
()
{
const
stackTraceLibPath
=
path
.
join
(
"node_modules"
,
"stacktrace-js"
,
"dist"
,
"stacktrace.min.js"
);
if
(
stackTraceLibPath
)
{
try
{
const initialState = history.state || {};
if (!initialState[NAV_TIMESTAMP_KEY]) {
initialState[NAV_TIMESTAMP_KEY] = lastNavigationTimestamp;
// Use try-catch for replaceState as well, in case state is not serializable initially
try {
history.replaceState(initialState, '', window.location.href);
// console.log('[vite-dev-navigation] Initial navigation timestamp set:', lastNavigationTimestamp);
} catch(replaceError) {
console.warn('[vite-dev-navigation] Could not set initial navigation timestamp via replaceState:', replaceError);
stacktraceJsContent
=
fs
.
readFileSync
(
stackTraceLibPath
,
"utf-8"
);
}
catch
(
error
)
{
console
.
error
(
`[dyad-shim] Failed to read stacktrace.js from
${
stackTraceLibPath
}
:`
,
error
);
stacktraceJsContent
=
null
;
}
}
else
{
lastNavigationTimestamp = initialState[NAV_TIMESTAMP_KEY];
// console.log('[vite-dev-navigation] Using existing initial navigation timestamp:', lastNavigationTimestamp);
}
} catch (e) {
console.warn('[vite-dev-navigation] Could not access or modify initial history state:', e);
}
// --- History API Overrides ---
const originalPushState = history.pushState;
const originalReplaceState = history.replaceState;
const handleStateChangeAndNotify = (originalMethod, state, title, url) => {
const newTimestamp = Date.now();
const oldUrlForMessage = previousUrl; // Capture previous URL before potential change
// Prepare new state with timestamp
let newState = state || {};
if (typeof newState !== 'object' || newState === null) {
newState = {};
} else if (Object.isFrozen(newState)) { // Handle frozen state objects
newState = { ...newState };
console
.
error
(
`[dyad-shim] stacktrace.js not found.`
);
}
newState[NAV_TIMESTAMP_KEY] = newTimestamp;
// Determine the intended new URL *before* calling the original method
let newUrl;
const
dyadShimPath
=
path
.
join
(
"dyad-shim.js"
);
if
(
dyadShimPath
)
{
try
{
// Resolve the potentially relative URL against the current location
newUrl = url ? new URL(url, window.location.href).href : window.location.href;
} catch (e) {
console.warn('[vite-dev-navigation] Error constructing URL:', url, e);
newUrl = window.location.href; // Fallback
dyadShimContent
=
fs
.
readFileSync
(
dyadShimPath
,
"utf-8"
);
}
catch
(
error
)
{
console
.
error
(
`[dyad-shim] Failed to read dyad-shim from
${
dyadShimPath
}
:`
,
error
);
dyadShimContent
=
null
;
}
// Determine the type of operation
const navigationType = (originalMethod === originalPushState ? 'pushState' : 'replaceState');
// Call the original history method
try {
originalMethod.call(history, newState, title, url);
// Update internal state *after* successful call
lastNavigationTimestamp = newTimestamp;
previousUrl = window.location.href; // Use the actual URL after the call
// Post message to parent *after* successful state change
// Use the 'newUrl' we calculated earlier as the intended target
// Use 'oldUrlForMessage' as the URL before this operation started
// console.log(\`[vite-dev-navigation] Emitting message: { type: '\${navigationType}', payload: { oldUrl: '\${oldUrlForMessage}', newUrl: '\${newUrl}' } }\`);
window.parent.postMessage({
type: navigationType, // 'pushState' or 'replaceState'
payload: {
oldUrl: oldUrlForMessage,
newUrl: newUrl // The URL passed to pushState/replaceState, resolved
}
}, '*'); // Consider a specific targetOrigin
} catch (e) {
console.error(\`[vite-dev-navigation] Error calling original \${navigationType}: \`, e);
// Optionally notify parent about the error during navigation attempt
window.parent.postMessage({
type: 'navigation-error',
payload: {
operation: navigationType,
message: e.message,
error: e.toString(),
stateAttempted: state, // Be careful sending state, might be large or sensitive
urlAttempted: url
}
}, '*');
}
else
{
console
.
error
(
`[dyad-shim] stacktrace.js not found.`
);
}
};
history.pushState = function(state, title, url) {
handleStateChangeAndNotify(originalPushState, state, title, url);
};
history.replaceState = function(state, title, url) {
handleStateChangeAndNotify(originalReplaceState, state, title, url);
};
},
// --- Listener for Back/Forward Navigation (popstate event) ---
// We keep this listener primarily to update our internal 'previousUrl'
// and 'lastNavigationTimestamp' state so that subsequent push/replace
// messages report the correct 'oldUrl'. We no longer send messages from here.
window.addEventListener('popstate', (event) => {
const currentUrl = window.location.href;
// console.log('[vite-dev-navigation] Popstate event detected. Previous URL was:', previousUrl, 'New URL is:', currentUrl);
transformIndexHtml
(
html
)
{
const
tags
:
HtmlTagDescriptor
[]
=
[];
const newStateTimestamp = event.state?.[NAV_TIMESTAMP_KEY];
if (typeof newStateTimestamp === 'number') {
lastNavigationTimestamp = newStateTimestamp; // Update timestamp from popped state
// console.log('[vite-dev-navigation] Updated lastNavigationTimestamp from popstate:', lastNavigationTimestamp);
// 1. Inject stacktrace.js
if
(
stacktraceJsContent
)
{
tags
.
push
({
tag
:
"script"
,
injectTo
:
"head-prepend"
,
children
:
stacktraceJsContent
,
});
}
else
{
// console.warn('[vite-dev-navigation] Popstate event state missing navigation timestamp.');
// If timestamp is missing, we might lose track, but there's not much we can do reliably.
// Keep the last known timestamp.
}
// Update previousUrl to reflect the new reality AFTER the popstate event
previousUrl = currentUrl;
tags
.
push
({
tag
:
"script"
,
injectTo
:
"head-prepend"
,
children
:
"console.warn('[dyad-shim] stacktrace.js library was not injected.');"
,
});
// --- Listener for Commands from Parent ---
window.addEventListener('message', (event) => {
// Security check: Ensure message is from parent
if (event.source !== window.parent || !event.data || typeof event.data !== 'object') {
return;
}
if (event.data.type === 'navigate') {
const direction = event.data.payload?.direction;
// console.log(\`[vite-dev-navigation] Received command: \${direction}\`);
if (direction === 'forward') {
history.forward();
} else if (direction === 'backward') {
history.back();
} else {
console.warn('[vite-dev-navigation] Received navigate command with invalid direction:', direction);
}
}
// 2. Inject dyad shim
if
(
dyadShimContent
)
{
tags
.
push
({
tag
:
"script"
,
injectTo
:
"head-prepend"
,
children
:
dyadShimContent
,
});
// --- Existing Error Handling ---
window.addEventListener('error', (event) => {
// console.log('[vite-dev-navigation] Forwarding error event to parent.');
window.parent.postMessage({
type: 'window-error',
payload: {
message: event.message,
filename: event.filename,
lineno: event.lineno,
colno: event.colno,
error: event.error?.toString() // Include stack trace if available
}
}, '*');
}
else
{
tags
.
push
({
tag
:
"script"
,
injectTo
:
"head-prepend"
,
children
:
"console.warn('[dyad-shim] dyad shim was not injected.');"
,
});
window.addEventListener('unhandledrejection', (event) => {
// console.log('[vite-dev-navigation] Forwarding unhandledrejection event to parent.');
window.parent.postMessage({
type: 'unhandled-rejection',
payload: {
reason: event.reason instanceof Error ? event.reason.toString() : JSON.stringify(event.reason) // Attempt to serialize reason
}
}, '*');
});
// console.log('[vite-dev-navigation] Navigation/error script initialized inside iframe. Initial URL:', previousUrl, 'Initial Timestamp:', lastNavigationTimestamp);
})(); // End of IIFE
`
,
},
],
};
return
{
html
,
tags
};
},
};
}
// https://vitejs.dev/config/
export
default
defineConfig
(({
mode
})
=>
({
server
:
{
host
:
"::"
,
...
...
src/components/preview_panel/PreviewIframe.tsx
浏览文件 @
79b7f865
...
...
@@ -45,7 +45,9 @@ const ErrorBanner = ({ error, onDismiss, onAIFix }: ErrorBannerProps) => {
{
/* Error message in the middle */
}
<
div
className=
"px-6 py-1 text-sm"
>
<
div
className=
"text-red-700 dark:text-red-300 text-wrap"
>
{
error
}
</
div
>
<
div
className=
"text-red-700 dark:text-red-300 text-wrap font-mono whitespace-pre-wrap break-words text-xs"
>
{
error
}
</
div
>
</
div
>
{
/* Tip message */
}
...
...
@@ -159,8 +161,16 @@ export const PreviewIframe = ({
const
{
type
,
payload
}
=
event
.
data
;
if
(
type
===
"window-error"
)
{
const
errorMessage
=
`Error in
${
payload
.
filename
}
(line
${
payload
.
lineno
}
, col
${
payload
.
colno
}
):
${
payload
.
message
}
`
;
if
(
type
===
"window-error"
||
type
===
"unhandled-rejection"
||
type
===
"iframe-sourcemapped-error"
)
{
const
stack
=
type
===
"iframe-sourcemapped-error"
?
payload
.
stack
.
split
(
"
\
n"
).
slice
(
0
,
1
).
join
(
"
\
n"
)
:
payload
.
stack
;
const
errorMessage
=
`Error
${
payload
.
message
}
\nStack trace:
${
stack
}
`
;
console
.
error
(
"Iframe error:"
,
errorMessage
);
setErrorMessage
(
errorMessage
);
setAppOutput
((
prev
)
=>
[
...
...
@@ -171,18 +181,6 @@ export const PreviewIframe = ({
appId
:
selectedAppId
!
,
},
]);
}
else
if
(
type
===
"unhandled-rejection"
)
{
const
errorMessage
=
`Unhandled Promise Rejection:
${
payload
.
reason
}
`
;
console
.
error
(
"Iframe unhandled rejection:"
,
errorMessage
);
setErrorMessage
(
errorMessage
);
setAppOutput
((
prev
)
=>
[
...
prev
,
{
message
:
`Iframe unhandled rejection:
${
errorMessage
}
`
,
type
:
"client-error"
,
appId
:
selectedAppId
!
,
},
]);
}
else
if
(
type
===
"pushState"
||
type
===
"replaceState"
)
{
console
.
debug
(
`Navigation event:
${
type
}
`
,
payload
);
...
...
@@ -201,10 +199,6 @@ export const PreviewIframe = ({
newHistory
[
currentHistoryPosition
]
=
payload
.
newUrl
;
setNavigationHistory
(
newHistory
);
}
// Update navigation buttons state
setCanGoBack
(
currentHistoryPosition
>
0
);
setCanGoForward
(
currentHistoryPosition
<
navigationHistory
.
length
-
1
);
}
};
...
...
@@ -212,6 +206,12 @@ export const PreviewIframe = ({
return
()
=>
window
.
removeEventListener
(
"message"
,
handleMessage
);
},
[
navigationHistory
,
currentHistoryPosition
,
selectedAppId
]);
useEffect
(()
=>
{
// Update navigation buttons state
setCanGoBack
(
currentHistoryPosition
>
0
);
setCanGoForward
(
currentHistoryPosition
<
navigationHistory
.
length
-
1
);
},
[
navigationHistory
,
currentHistoryPosition
]);
// Initialize navigation history when iframe loads
useEffect
(()
=>
{
if
(
appUrl
)
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论