@nativescript/vite: extensionless shared-workspace module requests return 404
Maintainer thường phản hồi trong vòng 3 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 57/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- javascript, node.js, typescript, vite
Hướng nghiên cứu
Start at resolveNsMTransformedModule and resolveFsAnchoredSpec in the NativeScript Vite package’s hmr/server/websocket-ns.js route. Trace how extension and platform candidates are resolved under project and workspace roots, including Vite filesystem access checks. Reproduce with the supplied workspace-fetch.mjs; done means the extensionless shared module request returns 200 and relevant regression checks pass.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
@nativescript/vite 8.0.20 serves a workspace-shared TSX module when its device URL includes .tsx, but returns 404 for the extensionless URL. The HMR client uses extensionless script URLs for reimports, so a successful static import does not establish that the same shared module can be hot-reimported.
Verified with the unpatched production NativeScript HTTP route, Vite 8.3.0 and Node 26.12.0. No Coreframe or Octane plugins, device runtime, or images are involved. This is separate from the graph-identity collision in #11569.
Expected and observed
With a native project at <workspace>/native and a module at <workspace>/shared/src/screen.tsx:
| Request | Actual |
|---|---|
/ns/m/shared/src/screen.tsx |
200 |
/ns/m/shared/src/screen |
404 |
Both should serve the same module. server.fs.allow explicitly includes the workspace. The project and temporary directory use real paths to avoid a symlink/filesystem-allow artifact.
Reproduction
Create these files in an empty directory, run pnpm install, then node workspace-fetch.mjs. The assertion intentionally fails after printing the status pair and writing workspace-fetch-result.json.
package.json:
{
"name": "nativescript-hmr-identity-repro",
"version": "0.0.0",
"private": true,
"type": "module",
"packageManager": "[email protected]",
"scripts": {
"check": "node repro.mjs"
},
"devDependencies": {
"@nativescript/vite": "8.0.20",
"vite": "8.3.0"
}
}
pnpm-workspace.yaml:
packages:
- .
allowBuilds:
esbuild: true
"@parcel/watcher": true
minimumReleaseAgeExclude:
- "@nativescript/[email protected]"
workspace-fetch.mjs:
import assert from 'node:assert/strict'
import { mkdtempSync, realpathSync, mkdirSync, writeFileSync, rmSync } from 'node:fs'
import { createRequire } from 'node:module'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { pathToFileURL } from 'node:url'
import { createServer } from 'vite'
const ns = pathToFileURL(createRequire(import.meta.url).resolve('@nativescript/vite'))
const { registerNsModuleServerRoute } = await import(new URL('./hmr/server/websocket-ns-m.js', ns))
const { setProjectFlavor } = await import(new URL('./helpers/flavor.js', ns))
setProjectFlavor('javascript')
const workspace = realpathSync(mkdtempSync(join(tmpdir(), 'ns-workspace-fetch-')))
const root = join(workspace, 'native')
mkdirSync(join(root, 'src'), { recursive: true })
mkdirSync(join(workspace, 'shared/src'), { recursive: true })
writeFileSync(join(root, 'package.json'), '{"type":"module"}')
writeFileSync(join(workspace, 'pnpm-workspace.yaml'), 'packages:\n - native\n')
writeFileSync(join(workspace, 'shared/src/screen.tsx'), 'export default "baseline";')
const server = await createServer({
root, configFile: false, logLevel: 'silent', optimizeDeps: { noDiscovery: true },
server: { host: '127.0.0.1', port: 0, watch: null, fs: { allow: [workspace] } },
plugins: [{ name: 'native-route-repro', configureServer(server) {
registerNsModuleServerRoute(server, {
verbose: false, appVirtualWithSlash: '/src/', sfcFileMap: new Map(), depFileMap: new Map(),
getGraphVersion: () => 1, getStrategy: () => ({ flavor: 'javascript' }), depsBundle: null,
sharedTransformRequest: (id) => server.transformRequest(id),
ensureInitialGraphPopulationStarted() {}, upsertGraphModule() {},
})
} }],
})
try {
await server.listen()
const origin = `http://127.0.0.1:${server.httpServer.address().port}`
const results = []
for (const url of ['/ns/m/shared/src/screen.tsx', '/ns/m/shared/src/screen']) {
const response = await fetch(origin + url)
results.push({ url, status: response.status })
await response.text()
}
console.log(JSON.stringify(results))
writeFileSync(new URL('./workspace-fetch-result.json', import.meta.url), JSON.stringify(results, null, 2) + '\n')
assert.ok(results.every(({ status }) => status === 200), 'HMR extensionless fetch must serve the same shared module as its static URL')
} finally {
await server.close()
rmSync(workspace, { recursive: true, force: true })
}
Source finding and requested fix
resolveNsMTransformedModule first tries extension/platform candidates as Vite app URLs. Those URLs do not address shared files outside the Vite root. Its later filesystem-root fallback calls resolveFsAnchoredSpec only with the original, extensionless spec; it does not probe the expanded candidates under the workspace root.
Please resolve the same extension/platform candidates under the project/workspace filesystem roots and preserve Vite filesystem access checks. A local exact-version patch doing that passes a real HTTP regression for native-host, shared-workspace and external-source modules, together with graph/hot-context identity checks. This report does not claim device HMR qualification or an upstream-main runtime test.
- Ngôn ngữ chính
- TypeScript
- Star
- 25.7k
- Fork
- 1.7k
- Merge trung bình
- 4 ngày 14 giờ
- Pull request đã merge (30 ngày)
- 53
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của NativeScript/NativeScript
-
bug css
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
NativeScript/NativeScript#11525 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
bug
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 69/100
NativeScript/NativeScript#11591 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
[iOS 26] Inset Frame cannot start native content Back with default navigationCó thể đã có người làm @rafaelaugustos đã nhận 8 ngày trước. Đang mởbug-pending-triage
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 15/100
NativeScript/NativeScript#11589 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
iOS: prebuilt Frame tree with inherited CSS direction triggers UIKit targetNode assertionCó thể đã có người làm @rafaelaugustos đã nhận 9 ngày trước. Đang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 15/100
NativeScript/NativeScript#11586 ·
Maintainer thường phản hồi trong vòng 3 ngày
-
[Android] After exiting with Back, reopening the app in the same process never fires launch again (9.1 regression, Angular apps stay dead and unstyled)Có thể đã có người làm @anjak03 đã nhận 11 ngày trước. Đang mởbug os: android
Độ khó 4/5 1-2 ngày Mức phù hợp với người mới 56/100
NativeScript/NativeScript#11572 ·
Maintainer thường phản hồi trong vòng 3 ngày
Tất cả issue của NativeScript/NativeScript
Issue tương tự
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
-
bug needs triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
DSpace/dspace-angular#6511 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
area: frontend area:byok bug severity:low
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Phone app shows Unknown for a remote machine whose key changedCó thể đã có người làm @janicduplessis đã nhận hôm nay. Đang mởarea: mobile priority: P3 type: bug
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 78/100
appandflow/stim#5006 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Area - Local to Cloud Bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
microsoft/vscode-mssql#23209 ·
Maintainer thường phản hồi trong vòng 1 ngày