@nativescript/vite: extensionless shared-workspace module requests return 404

Đang mở
#11,570 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

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
Lĩnh vực
devtools, tooling

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ả

bug

@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

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. 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.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của NativeScript/NativeScript

Tất cả issue của NativeScript/NativeScript

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.