one 1.25.12 → 1.25.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/cli/build.cjs +37 -186
- package/dist/cjs/cli/build.native.js +270 -423
- package/dist/cjs/cli/build.native.js.map +1 -1
- package/dist/cjs/cli/buildPage.cjs +7 -7
- package/dist/cjs/cli/buildPage.native.js +7 -7
- package/dist/cjs/cli/buildPage.native.js.map +1 -1
- package/dist/cjs/cli/buildPageWorker.cjs +1 -1
- package/dist/cjs/cli/buildPageWorker.native.js +1 -1
- package/dist/cjs/cli/buildPageWorker.native.js.map +1 -1
- package/dist/cjs/cli/serverRouteModules.cjs +47 -0
- package/dist/cjs/cli/serverRouteModules.native.js +52 -0
- package/dist/cjs/cli/serverRouteModules.native.js.map +1 -0
- package/dist/cjs/cli/workerPool.native.js.map +1 -1
- package/dist/cjs/createApp.cjs +3 -0
- package/dist/cjs/createDevHandleRequest.cjs +151 -0
- package/dist/cjs/createDevHandleRequest.native.js +194 -0
- package/dist/cjs/createDevHandleRequest.native.js.map +1 -0
- package/dist/cjs/createHandleRequest.cjs +1 -123
- package/dist/cjs/createHandleRequest.native.js +1 -163
- package/dist/cjs/createHandleRequest.native.js.map +1 -1
- package/dist/cjs/createHandleRequest.test.cjs +25 -25
- package/dist/cjs/createHandleRequest.test.native.js +25 -25
- package/dist/cjs/createHandleRequest.test.native.js.map +1 -1
- package/dist/cjs/headless-server.native.js.map +1 -1
- package/dist/cjs/headless.cjs +4 -0
- package/dist/cjs/headless.native.js +4 -0
- package/dist/cjs/headless.native.js.map +1 -1
- package/dist/cjs/layouts/Drawer.cjs +0 -2
- package/dist/cjs/layouts/Drawer.native.js.map +1 -1
- package/dist/cjs/layouts/Tabs.cjs +0 -2
- package/dist/cjs/layouts/Tabs.native.js.map +1 -1
- package/dist/cjs/router/diagnoseRouteLoadFailure.native.js.map +1 -1
- package/dist/cjs/router/useViteRoutes.cjs +9 -1
- package/dist/cjs/router/useViteRoutes.native.js +9 -1
- package/dist/cjs/router/useViteRoutes.native.js.map +1 -1
- package/dist/cjs/router/web/WebStackView.cjs +0 -2
- package/dist/cjs/router/web/WebStackView.native.js +0 -2
- package/dist/cjs/router/web/WebStackView.native.js.map +1 -1
- package/dist/cjs/serve-worker.cjs +3 -2
- package/dist/cjs/serve-worker.native.js +3 -2
- package/dist/cjs/serve-worker.native.js.map +1 -1
- package/dist/cjs/server/oneServe.cjs +23 -4
- package/dist/cjs/server/oneServe.native.js +25 -6
- package/dist/cjs/server/oneServe.native.js.map +1 -1
- package/dist/cjs/server/routeExportsFromEntry.cjs +47 -0
- package/dist/cjs/server/routeExportsFromEntry.native.js +52 -0
- package/dist/cjs/server/routeExportsFromEntry.native.js.map +1 -0
- package/dist/cjs/server/workerHandler.cjs +30 -12
- package/dist/cjs/server/workerHandler.native.js +32 -13
- package/dist/cjs/server/workerHandler.native.js.map +1 -1
- package/dist/cjs/server/workerHandler.test.cjs +43 -10
- package/dist/cjs/server/workerHandler.test.native.js +46 -10
- package/dist/cjs/server/workerHandler.test.native.js.map +1 -1
- package/dist/cjs/views/ScrollBehavior.native.js.map +1 -1
- package/dist/cjs/vite/cloudflareWranglerConfig.cjs +247 -0
- package/dist/cjs/vite/cloudflareWranglerConfig.native.js +392 -0
- package/dist/cjs/vite/cloudflareWranglerConfig.native.js.map +1 -0
- package/dist/cjs/vite/cloudflareWranglerConfig.test.cjs +116 -0
- package/dist/cjs/vite/cloudflareWranglerConfig.test.native.js +120 -0
- package/dist/cjs/vite/cloudflareWranglerConfig.test.native.js.map +1 -0
- package/dist/cjs/vite/one.cjs +4 -2
- package/dist/cjs/vite/one.native.js +8 -6
- package/dist/cjs/vite/one.native.js.map +1 -1
- package/dist/cjs/vite/plugins/SSRCSSPlugin.cjs +10 -1
- package/dist/cjs/vite/plugins/SSRCSSPlugin.native.js +52 -3
- package/dist/cjs/vite/plugins/SSRCSSPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/environmentGuardPlugin.cjs +1 -1
- package/dist/cjs/vite/plugins/environmentGuardPlugin.native.js +1 -1
- package/dist/cjs/vite/plugins/environmentGuardPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/environmentGuardPlugin.test.cjs +4 -0
- package/dist/cjs/vite/plugins/environmentGuardPlugin.test.native.js +4 -0
- package/dist/cjs/vite/plugins/environmentGuardPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.cjs +14 -5
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js +15 -5
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.test.cjs +47 -0
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.test.native.js +47 -0
- package/dist/cjs/vite/plugins/fileSystemRouterPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/virtualEntryPlugin.cjs +9 -7
- package/dist/cjs/vite/plugins/virtualEntryPlugin.native.js +11 -7
- package/dist/cjs/vite/plugins/virtualEntryPlugin.native.js.map +1 -1
- package/dist/cjs/vite/plugins/virtualEntryPlugin.test.cjs +12 -0
- package/dist/cjs/vite/plugins/virtualEntryPlugin.test.native.js +12 -0
- package/dist/cjs/vite/plugins/virtualEntryPlugin.test.native.js.map +1 -1
- package/dist/cjs/vite/plugins/workerdDevPlugin.cjs +364 -0
- package/dist/cjs/vite/plugins/workerdDevPlugin.native.js +461 -0
- package/dist/cjs/vite/plugins/workerdDevPlugin.native.js.map +1 -0
- package/dist/cjs/vite/plugins/workerdDevPlugin.test.cjs +42 -0
- package/dist/cjs/vite/plugins/workerdDevPlugin.test.native.js +45 -0
- package/dist/cjs/vite/plugins/workerdDevPlugin.test.native.js.map +1 -0
- package/dist/cjs/vite/replaceLoader.cjs +6 -3
- package/dist/cjs/vite/replaceLoader.native.js +8 -3
- package/dist/cjs/vite/replaceLoader.native.js.map +1 -1
- package/dist/esm/cli/build.mjs +31 -180
- package/dist/esm/cli/build.mjs.map +1 -1
- package/dist/esm/cli/build.native.js +264 -417
- package/dist/esm/cli/build.native.js.map +1 -1
- package/dist/esm/cli/buildPage.mjs +7 -7
- package/dist/esm/cli/buildPage.mjs.map +1 -1
- package/dist/esm/cli/buildPage.native.js +7 -7
- package/dist/esm/cli/buildPage.native.js.map +1 -1
- package/dist/esm/cli/buildPageWorker.mjs +1 -1
- package/dist/esm/cli/buildPageWorker.mjs.map +1 -1
- package/dist/esm/cli/buildPageWorker.native.js +1 -1
- package/dist/esm/cli/buildPageWorker.native.js.map +1 -1
- package/dist/esm/cli/serverRouteModules.mjs +22 -0
- package/dist/esm/cli/serverRouteModules.mjs.map +1 -0
- package/dist/esm/cli/serverRouteModules.native.js +24 -0
- package/dist/esm/cli/serverRouteModules.native.js.map +1 -0
- package/dist/esm/cli/workerPool.mjs.map +1 -1
- package/dist/esm/cli/workerPool.native.js.map +1 -1
- package/dist/esm/createApp.mjs +4 -1
- package/dist/esm/createApp.mjs.map +1 -1
- package/dist/esm/createDevHandleRequest.mjs +126 -0
- package/dist/esm/createDevHandleRequest.mjs.map +1 -0
- package/dist/esm/createDevHandleRequest.native.js +166 -0
- package/dist/esm/createDevHandleRequest.native.js.map +1 -0
- package/dist/esm/createHandleRequest.mjs +1 -123
- package/dist/esm/createHandleRequest.mjs.map +1 -1
- package/dist/esm/createHandleRequest.native.js +1 -163
- package/dist/esm/createHandleRequest.native.js.map +1 -1
- package/dist/esm/createHandleRequest.test.mjs +1 -1
- package/dist/esm/createHandleRequest.test.native.js +1 -1
- package/dist/esm/headless-server.mjs.map +1 -1
- package/dist/esm/headless-server.native.js.map +1 -1
- package/dist/esm/headless.mjs +4 -0
- package/dist/esm/headless.mjs.map +1 -1
- package/dist/esm/headless.native.js +4 -0
- package/dist/esm/headless.native.js.map +1 -1
- package/dist/esm/layouts/Drawer.mjs +0 -2
- package/dist/esm/layouts/Drawer.mjs.map +1 -1
- package/dist/esm/layouts/Drawer.native.js.map +1 -1
- package/dist/esm/layouts/Tabs.mjs +0 -2
- package/dist/esm/layouts/Tabs.mjs.map +1 -1
- package/dist/esm/layouts/Tabs.native.js.map +1 -1
- package/dist/esm/router/diagnoseRouteLoadFailure.mjs.map +1 -1
- package/dist/esm/router/diagnoseRouteLoadFailure.native.js.map +1 -1
- package/dist/esm/router/useViteRoutes.mjs +9 -1
- package/dist/esm/router/useViteRoutes.mjs.map +1 -1
- package/dist/esm/router/useViteRoutes.native.js +9 -1
- package/dist/esm/router/useViteRoutes.native.js.map +1 -1
- package/dist/esm/router/web/WebStackView.mjs +0 -2
- package/dist/esm/router/web/WebStackView.mjs.map +1 -1
- package/dist/esm/router/web/WebStackView.native.js +0 -2
- package/dist/esm/router/web/WebStackView.native.js.map +1 -1
- package/dist/esm/serve-worker.mjs +3 -2
- package/dist/esm/serve-worker.mjs.map +1 -1
- package/dist/esm/serve-worker.native.js +3 -2
- package/dist/esm/serve-worker.native.js.map +1 -1
- package/dist/esm/server/oneServe.mjs +23 -4
- package/dist/esm/server/oneServe.mjs.map +1 -1
- package/dist/esm/server/oneServe.native.js +25 -6
- package/dist/esm/server/oneServe.native.js.map +1 -1
- package/dist/esm/server/routeExportsFromEntry.mjs +21 -0
- package/dist/esm/server/routeExportsFromEntry.mjs.map +1 -0
- package/dist/esm/server/routeExportsFromEntry.native.js +23 -0
- package/dist/esm/server/routeExportsFromEntry.native.js.map +1 -0
- package/dist/esm/server/workerHandler.mjs +30 -12
- package/dist/esm/server/workerHandler.mjs.map +1 -1
- package/dist/esm/server/workerHandler.native.js +32 -13
- package/dist/esm/server/workerHandler.native.js.map +1 -1
- package/dist/esm/server/workerHandler.test.mjs +43 -10
- package/dist/esm/server/workerHandler.test.mjs.map +1 -1
- package/dist/esm/server/workerHandler.test.native.js +46 -10
- package/dist/esm/server/workerHandler.test.native.js.map +1 -1
- package/dist/esm/views/ScrollBehavior.mjs.map +1 -1
- package/dist/esm/views/ScrollBehavior.native.js.map +1 -1
- package/dist/esm/vite/cloudflareWranglerConfig.mjs +202 -0
- package/dist/esm/vite/cloudflareWranglerConfig.mjs.map +1 -0
- package/dist/esm/vite/cloudflareWranglerConfig.native.js +344 -0
- package/dist/esm/vite/cloudflareWranglerConfig.native.js.map +1 -0
- package/dist/esm/vite/cloudflareWranglerConfig.test.mjs +117 -0
- package/dist/esm/vite/cloudflareWranglerConfig.test.mjs.map +1 -0
- package/dist/esm/vite/cloudflareWranglerConfig.test.native.js +118 -0
- package/dist/esm/vite/cloudflareWranglerConfig.test.native.js.map +1 -0
- package/dist/esm/vite/one.mjs +4 -2
- package/dist/esm/vite/one.mjs.map +1 -1
- package/dist/esm/vite/one.native.js +8 -6
- package/dist/esm/vite/one.native.js.map +1 -1
- package/dist/esm/vite/plugins/SSRCSSPlugin.mjs +10 -1
- package/dist/esm/vite/plugins/SSRCSSPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/SSRCSSPlugin.native.js +52 -3
- package/dist/esm/vite/plugins/SSRCSSPlugin.native.js.map +1 -1
- package/dist/esm/vite/plugins/environmentGuardPlugin.mjs +1 -1
- package/dist/esm/vite/plugins/environmentGuardPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/environmentGuardPlugin.native.js +1 -1
- package/dist/esm/vite/plugins/environmentGuardPlugin.native.js.map +1 -1
- package/dist/esm/vite/plugins/environmentGuardPlugin.test.mjs +4 -0
- package/dist/esm/vite/plugins/environmentGuardPlugin.test.mjs.map +1 -1
- package/dist/esm/vite/plugins/environmentGuardPlugin.test.native.js +4 -0
- package/dist/esm/vite/plugins/environmentGuardPlugin.test.native.js.map +1 -1
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.mjs +13 -4
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.native.js +14 -4
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.native.js.map +1 -1
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.mjs +47 -0
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.mjs.map +1 -1
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.native.js +47 -0
- package/dist/esm/vite/plugins/fileSystemRouterPlugin.test.native.js.map +1 -1
- package/dist/esm/vite/plugins/virtualEntryPlugin.mjs +9 -7
- package/dist/esm/vite/plugins/virtualEntryPlugin.mjs.map +1 -1
- package/dist/esm/vite/plugins/virtualEntryPlugin.native.js +11 -7
- package/dist/esm/vite/plugins/virtualEntryPlugin.native.js.map +1 -1
- package/dist/esm/vite/plugins/virtualEntryPlugin.test.mjs +12 -0
- package/dist/esm/vite/plugins/virtualEntryPlugin.test.mjs.map +1 -1
- package/dist/esm/vite/plugins/virtualEntryPlugin.test.native.js +12 -0
- package/dist/esm/vite/plugins/virtualEntryPlugin.test.native.js.map +1 -1
- package/dist/esm/vite/plugins/workerdDevPlugin.mjs +336 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.mjs.map +1 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.native.js +430 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.native.js.map +1 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.test.mjs +43 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.test.mjs.map +1 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.test.native.js +43 -0
- package/dist/esm/vite/plugins/workerdDevPlugin.test.native.js.map +1 -0
- package/dist/esm/vite/replaceLoader.mjs +6 -3
- package/dist/esm/vite/replaceLoader.mjs.map +1 -1
- package/dist/esm/vite/replaceLoader.native.js +8 -3
- package/dist/esm/vite/replaceLoader.native.js.map +1 -1
- package/package.json +9 -9
- package/src/cli/build.ts +48 -224
- package/src/cli/buildPage.ts +9 -7
- package/src/cli/buildPageWorker.ts +1 -0
- package/src/cli/serverRouteModules.ts +33 -0
- package/src/cli/workerPool.ts +1 -0
- package/src/createApp.tsx +5 -1
- package/src/createDevHandleRequest.ts +186 -0
- package/src/createHandleRequest.test.ts +1 -1
- package/src/createHandleRequest.ts +2 -172
- package/src/headless-server.ts +0 -1
- package/src/headless.tsx +5 -0
- package/src/layouts/Drawer.web.tsx +0 -3
- package/src/layouts/Tabs.web.tsx +0 -2
- package/src/router/diagnoseRouteLoadFailure.ts +3 -1
- package/src/router/useViteRoutes.tsx +9 -1
- package/src/router/web/WebStackView.tsx +0 -3
- package/src/serve-worker.ts +6 -1
- package/src/server/oneServe.ts +40 -16
- package/src/server/routeExportsFromEntry.ts +59 -0
- package/src/server/workerHandler.test.ts +37 -9
- package/src/server/workerHandler.ts +39 -13
- package/src/views/ScrollBehavior.tsx +5 -1
- package/src/vite/cloudflareWranglerConfig.test.ts +101 -0
- package/src/vite/cloudflareWranglerConfig.ts +252 -0
- package/src/vite/one.ts +14 -1
- package/src/vite/plugins/SSRCSSPlugin.ts +17 -2
- package/src/vite/plugins/environmentGuardPlugin.test.ts +5 -0
- package/src/vite/plugins/environmentGuardPlugin.ts +2 -2
- package/src/vite/plugins/fileSystemRouterPlugin.test.ts +44 -0
- package/src/vite/plugins/fileSystemRouterPlugin.tsx +20 -8
- package/src/vite/plugins/virtualEntryPlugin.test.ts +13 -0
- package/src/vite/plugins/virtualEntryPlugin.ts +13 -9
- package/src/vite/plugins/workerdDevPlugin.test.ts +44 -0
- package/src/vite/plugins/workerdDevPlugin.ts +398 -0
- package/src/vite/replaceLoader.ts +10 -2
- package/types/cli/build.d.ts.map +1 -1
- package/types/cli/buildPage.d.ts +1 -1
- package/types/cli/buildPage.d.ts.map +1 -1
- package/types/cli/serverRouteModules.d.ts +2 -0
- package/types/cli/serverRouteModules.d.ts.map +1 -0
- package/types/cli/workerPool.d.ts +1 -0
- package/types/cli/workerPool.d.ts.map +1 -1
- package/types/createApp.d.ts.map +1 -1
- package/types/createDevHandleRequest.d.ts +10 -0
- package/types/createDevHandleRequest.d.ts.map +1 -0
- package/types/createHandleRequest.d.ts +2 -9
- package/types/createHandleRequest.d.ts.map +1 -1
- package/types/headless-server.d.ts +0 -1
- package/types/headless-server.d.ts.map +1 -1
- package/types/headless.d.ts.map +1 -1
- package/types/layouts/Drawer.web.d.ts.map +1 -1
- package/types/layouts/Tabs.web.d.ts.map +1 -1
- package/types/router/diagnoseRouteLoadFailure.d.ts.map +1 -1
- package/types/router/useViteRoutes.d.ts.map +1 -1
- package/types/router/web/WebStackView.d.ts.map +1 -1
- package/types/serve-worker.d.ts +3 -1
- package/types/serve-worker.d.ts.map +1 -1
- package/types/server/oneServe.d.ts +1 -1
- package/types/server/oneServe.d.ts.map +1 -1
- package/types/server/routeExportsFromEntry.d.ts +29 -0
- package/types/server/routeExportsFromEntry.d.ts.map +1 -0
- package/types/server/workerHandler.d.ts +2 -1
- package/types/server/workerHandler.d.ts.map +1 -1
- package/types/views/ScrollBehavior.d.ts.map +1 -1
- package/types/vite/cloudflareWranglerConfig.d.ts +21 -0
- package/types/vite/cloudflareWranglerConfig.d.ts.map +1 -0
- package/types/vite/cloudflareWranglerConfig.test.d.ts +2 -0
- package/types/vite/cloudflareWranglerConfig.test.d.ts.map +1 -0
- package/types/vite/one.d.ts.map +1 -1
- package/types/vite/plugins/SSRCSSPlugin.d.ts.map +1 -1
- package/types/vite/plugins/fileSystemRouterPlugin.d.ts.map +1 -1
- package/types/vite/plugins/virtualEntryPlugin.d.ts.map +1 -1
- package/types/vite/plugins/workerdDevPlugin.d.ts +15 -0
- package/types/vite/plugins/workerdDevPlugin.d.ts.map +1 -0
- package/types/vite/plugins/workerdDevPlugin.test.d.ts +2 -0
- package/types/vite/plugins/workerdDevPlugin.test.d.ts.map +1 -0
- package/types/vite/replaceLoader.d.ts +2 -1
- package/types/vite/replaceLoader.d.ts.map +1 -1
- package/dist/cjs/headless/devHeadlessNote.cjs +0 -34
- package/dist/cjs/headless/devHeadlessNote.native.js +0 -37
- package/dist/cjs/headless/devHeadlessNote.native.js.map +0 -1
- package/dist/esm/headless/devHeadlessNote.mjs +0 -9
- package/dist/esm/headless/devHeadlessNote.mjs.map +0 -1
- package/dist/esm/headless/devHeadlessNote.native.js +0 -9
- package/dist/esm/headless/devHeadlessNote.native.js.map +0 -1
- package/src/headless/devHeadlessNote.ts +0 -13
- package/types/headless/devHeadlessNote.d.ts +0 -2
- package/types/headless/devHeadlessNote.d.ts.map +0 -1
package/src/cli/build.ts
CHANGED
|
@@ -29,6 +29,13 @@ import { getRouterRootFromOneOptions } from '../utils/getRouterRootFromOneOption
|
|
|
29
29
|
import { isRolldown } from '../utils/isRolldown'
|
|
30
30
|
import { toAbsolute, toAbsoluteUrl } from '../utils/toAbsolute'
|
|
31
31
|
import { buildVercelOutputDirectory } from '../vercel/build/buildVercelOutputDirectory'
|
|
32
|
+
import {
|
|
33
|
+
createCloudflareWranglerConfig,
|
|
34
|
+
getCloudflareProjectName,
|
|
35
|
+
isPlainObject,
|
|
36
|
+
loadUserWranglerConfig,
|
|
37
|
+
type JsonValue,
|
|
38
|
+
} from '../vite/cloudflareWranglerConfig'
|
|
32
39
|
import { getManifest } from '../vite/getManifest'
|
|
33
40
|
import { loadUserOneOptions } from '../vite/loadConfig'
|
|
34
41
|
import { runWithAsyncLocalContext } from '../vite/one-server-only'
|
|
@@ -38,6 +45,7 @@ import { checkNodeVersion } from './checkNodeVersion'
|
|
|
38
45
|
import { getWorkerPool, terminateWorkerPool } from './workerPool'
|
|
39
46
|
import { generateSitemap, type RouteSitemapData } from './generateSitemap'
|
|
40
47
|
import { labelProcess } from './label-process'
|
|
48
|
+
import { getRouteExports } from './serverRouteModules'
|
|
41
49
|
import { pLimit } from '../utils/pLimit'
|
|
42
50
|
import { getCriticalCSSOutputPaths } from '../vite/plugins/criticalCSSPlugin'
|
|
43
51
|
|
|
@@ -51,191 +59,10 @@ function normalizeDeploy(
|
|
|
51
59
|
return deploy
|
|
52
60
|
}
|
|
53
61
|
|
|
54
|
-
type JsonPrimitive = string | number | boolean | null
|
|
55
|
-
type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue }
|
|
56
|
-
|
|
57
|
-
const GENERATED_CLOUDFLARE_WRANGLER_RULES = [
|
|
58
|
-
{ type: 'ESModule', globs: ['./server/**/*.js'], fallthrough: true },
|
|
59
|
-
{ type: 'ESModule', globs: ['./api/**/*.js'], fallthrough: true },
|
|
60
|
-
{ type: 'ESModule', globs: ['./middlewares/**/*.js'], fallthrough: true },
|
|
61
|
-
{ type: 'ESModule', globs: ['./assets/**/*.js'], fallthrough: true },
|
|
62
|
-
]
|
|
63
|
-
|
|
64
62
|
const CLOUDFLARE_DEPLOY_WRANGLER_RULES = [
|
|
65
63
|
{ type: 'ESModule', globs: ['assets/**/*.js', 'assets/**/*.mjs'] },
|
|
66
64
|
]
|
|
67
65
|
|
|
68
|
-
function isPlainObject(value: unknown): value is Record<string, JsonValue> {
|
|
69
|
-
return !!value && typeof value === 'object' && !Array.isArray(value)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function mergeJsonObjects(
|
|
73
|
-
base: Record<string, JsonValue>,
|
|
74
|
-
overrides: Record<string, JsonValue>
|
|
75
|
-
): Record<string, JsonValue> {
|
|
76
|
-
const merged: Record<string, JsonValue> = { ...base }
|
|
77
|
-
|
|
78
|
-
for (const [key, value] of Object.entries(overrides)) {
|
|
79
|
-
const baseValue = merged[key]
|
|
80
|
-
if (isPlainObject(baseValue) && isPlainObject(value)) {
|
|
81
|
-
merged[key] = mergeJsonObjects(baseValue, value)
|
|
82
|
-
} else {
|
|
83
|
-
merged[key] = value
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return merged
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function dedupeJsonValues<T extends JsonValue>(values: T[]): T[] {
|
|
91
|
-
const seen = new Set<string>()
|
|
92
|
-
return values.filter((value) => {
|
|
93
|
-
const key = JSON.stringify(value)
|
|
94
|
-
if (seen.has(key)) return false
|
|
95
|
-
seen.add(key)
|
|
96
|
-
return true
|
|
97
|
-
})
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function mergeCloudflareCompatibilityFlags(flags: unknown): string[] {
|
|
101
|
-
const userFlags = Array.isArray(flags)
|
|
102
|
-
? flags.filter((flag): flag is string => typeof flag === 'string')
|
|
103
|
-
: []
|
|
104
|
-
|
|
105
|
-
return dedupeJsonValues<string>(['nodejs_compat', ...userFlags])
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function mergeCloudflareRules(rules: unknown): JsonValue[] {
|
|
109
|
-
const userRules = Array.isArray(rules)
|
|
110
|
-
? rules.filter((rule): rule is JsonValue => isPlainObject(rule))
|
|
111
|
-
: []
|
|
112
|
-
|
|
113
|
-
return dedupeJsonValues<JsonValue>([
|
|
114
|
-
...GENERATED_CLOUDFLARE_WRANGLER_RULES,
|
|
115
|
-
...userRules,
|
|
116
|
-
])
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// minimal JSONC parser: strips line/block comments (string-aware) and trailing
|
|
120
|
-
// commas, then runs JSON.parse. sufficient for small hand-written config files.
|
|
121
|
-
function parseJsonc(text: string): unknown {
|
|
122
|
-
let out = ''
|
|
123
|
-
let i = 0
|
|
124
|
-
let inString = false
|
|
125
|
-
let quote = ''
|
|
126
|
-
while (i < text.length) {
|
|
127
|
-
const ch = text[i]
|
|
128
|
-
const next = text[i + 1]
|
|
129
|
-
if (inString) {
|
|
130
|
-
if (ch === '\\') {
|
|
131
|
-
out += ch + (next ?? '')
|
|
132
|
-
i += 2
|
|
133
|
-
continue
|
|
134
|
-
}
|
|
135
|
-
if (ch === quote) inString = false
|
|
136
|
-
out += ch
|
|
137
|
-
i++
|
|
138
|
-
continue
|
|
139
|
-
}
|
|
140
|
-
if (ch === '"' || ch === "'") {
|
|
141
|
-
inString = true
|
|
142
|
-
quote = ch
|
|
143
|
-
out += ch
|
|
144
|
-
i++
|
|
145
|
-
continue
|
|
146
|
-
}
|
|
147
|
-
if (ch === '/' && next === '/') {
|
|
148
|
-
while (i < text.length && text[i] !== '\n') i++
|
|
149
|
-
continue
|
|
150
|
-
}
|
|
151
|
-
if (ch === '/' && next === '*') {
|
|
152
|
-
i += 2
|
|
153
|
-
while (i < text.length - 1 && !(text[i] === '*' && text[i + 1] === '/')) i++
|
|
154
|
-
i += 2
|
|
155
|
-
continue
|
|
156
|
-
}
|
|
157
|
-
out += ch
|
|
158
|
-
i++
|
|
159
|
-
}
|
|
160
|
-
return JSON.parse(out.replace(/,(\s*[}\]])/g, '$1'))
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
async function loadUserWranglerConfig(
|
|
164
|
-
root: string
|
|
165
|
-
): Promise<{ path: string; config: Record<string, JsonValue> } | null> {
|
|
166
|
-
const candidateRoots = [...new Set([root, process.cwd()])]
|
|
167
|
-
|
|
168
|
-
for (const candidateRoot of candidateRoots) {
|
|
169
|
-
for (const fileName of ['wrangler.jsonc', 'wrangler.json']) {
|
|
170
|
-
const configPath = join(candidateRoot, fileName)
|
|
171
|
-
if (!(await FSExtra.pathExists(configPath))) {
|
|
172
|
-
continue
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const contents = await FSExtra.readFile(configPath, 'utf-8')
|
|
176
|
-
let parsed: unknown
|
|
177
|
-
try {
|
|
178
|
-
parsed = parseJsonc(contents)
|
|
179
|
-
} catch (err) {
|
|
180
|
-
throw new Error(
|
|
181
|
-
`Failed to parse ${relative(process.cwd(), configPath)}: ${(err as Error).message}`
|
|
182
|
-
)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (!isPlainObject(parsed)) {
|
|
186
|
-
throw new Error(
|
|
187
|
-
`Expected ${relative(process.cwd(), configPath)} to contain a top-level JSON object`
|
|
188
|
-
)
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return {
|
|
192
|
-
path: configPath,
|
|
193
|
-
config: parsed,
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return null
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
function createCloudflareWranglerConfig(
|
|
202
|
-
projectName: string,
|
|
203
|
-
userConfig?: Record<string, JsonValue>
|
|
204
|
-
): Record<string, JsonValue> {
|
|
205
|
-
const generatedConfig: Record<string, JsonValue> = {
|
|
206
|
-
name: projectName,
|
|
207
|
-
main: 'worker.js',
|
|
208
|
-
compatibility_date: '2024-12-05',
|
|
209
|
-
compatibility_flags: ['nodejs_compat'],
|
|
210
|
-
find_additional_modules: true,
|
|
211
|
-
rules: GENERATED_CLOUDFLARE_WRANGLER_RULES,
|
|
212
|
-
assets: {
|
|
213
|
-
directory: 'client',
|
|
214
|
-
binding: 'ASSETS',
|
|
215
|
-
run_worker_first: true,
|
|
216
|
-
},
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const mergedConfig = userConfig
|
|
220
|
-
? mergeJsonObjects(generatedConfig, userConfig)
|
|
221
|
-
: generatedConfig
|
|
222
|
-
|
|
223
|
-
mergedConfig.main = 'worker.js'
|
|
224
|
-
mergedConfig.find_additional_modules = true
|
|
225
|
-
mergedConfig.compatibility_flags = mergeCloudflareCompatibilityFlags(
|
|
226
|
-
mergedConfig.compatibility_flags
|
|
227
|
-
)
|
|
228
|
-
mergedConfig.rules = mergeCloudflareRules(mergedConfig.rules)
|
|
229
|
-
mergedConfig.assets = {
|
|
230
|
-
...(isPlainObject(mergedConfig.assets) ? mergedConfig.assets : {}),
|
|
231
|
-
directory: 'client',
|
|
232
|
-
binding: 'ASSETS',
|
|
233
|
-
run_worker_first: true,
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
return mergedConfig
|
|
237
|
-
}
|
|
238
|
-
|
|
239
66
|
function omitEmptyJsonValues(value: JsonValue): JsonValue | undefined {
|
|
240
67
|
if (Array.isArray(value)) {
|
|
241
68
|
const items = value
|
|
@@ -276,17 +103,6 @@ async function finalizeCloudflareWranglerDeployConfig(configPath: string) {
|
|
|
276
103
|
await FSExtra.writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`)
|
|
277
104
|
}
|
|
278
105
|
|
|
279
|
-
// reads package.json name, strips npm scope prefix for use as cloudflare worker name
|
|
280
|
-
async function getCloudflareProjectName(root: string): Promise<string> {
|
|
281
|
-
try {
|
|
282
|
-
const pkg = JSON.parse(await FSExtra.readFile(join(root, 'package.json'), 'utf-8'))
|
|
283
|
-
if (pkg.name) {
|
|
284
|
-
return pkg.name.replace(/^@[^/]+\//, '')
|
|
285
|
-
}
|
|
286
|
-
} catch {}
|
|
287
|
-
return 'one-app'
|
|
288
|
-
}
|
|
289
|
-
|
|
290
106
|
// ensure worker threads inherit the same CACHE_KEY as the main process
|
|
291
107
|
process.env.ONE_CACHE_KEY = constants.CACHE_KEY
|
|
292
108
|
|
|
@@ -722,17 +538,36 @@ export async function build(args: {
|
|
|
722
538
|
}
|
|
723
539
|
|
|
724
540
|
// build a direct mapping from source file path to client chunk info
|
|
725
|
-
// this is more reliable than manifest.json which can have ambiguous keys
|
|
541
|
+
// this is more reliable than manifest.json which can have ambiguous keys.
|
|
542
|
+
// index every module a chunk contains, not just its facade: a route that
|
|
543
|
+
// another route re-exports from stops being a dynamic entry and lands in a
|
|
544
|
+
// plain shared chunk, which has no facade and so gets no source-path key in
|
|
545
|
+
// the manifest either. the facade pass runs second so it wins where both hit.
|
|
726
546
|
const clientChunksBySource = new Map<string, { fileName: string; imports: string[] }>()
|
|
727
547
|
if (vxrnOutput.clientOutput) {
|
|
728
548
|
for (const chunk of vxrnOutput.clientOutput) {
|
|
729
|
-
if (chunk.type
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
})
|
|
549
|
+
if (chunk.type !== 'chunk') continue
|
|
550
|
+
const info = { fileName: chunk.fileName, imports: chunk.imports || [] }
|
|
551
|
+
for (const moduleId of chunk.moduleIds ?? []) {
|
|
552
|
+
clientChunksBySource.set(moduleId, info)
|
|
734
553
|
}
|
|
735
554
|
}
|
|
555
|
+
for (const chunk of vxrnOutput.clientOutput) {
|
|
556
|
+
if (chunk.type !== 'chunk' || !chunk.facadeModuleId) continue
|
|
557
|
+
clientChunksBySource.set(chunk.facadeModuleId, {
|
|
558
|
+
fileName: chunk.fileName,
|
|
559
|
+
imports: chunk.imports || [],
|
|
560
|
+
})
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// the manifest keys chunks by source path only when they have a facade, so
|
|
565
|
+
// reach the rest through the chunk file name that clientChunksBySource gives us
|
|
566
|
+
const clientManifestByFile = new Map<string, ClientManifestEntry>()
|
|
567
|
+
for (const entry of Object.values(vxrnOutput.clientManifest) as ClientManifestEntry[]) {
|
|
568
|
+
if (entry.file) {
|
|
569
|
+
clientManifestByFile.set(entry.file, entry)
|
|
570
|
+
}
|
|
736
571
|
}
|
|
737
572
|
|
|
738
573
|
const outputEntries = [...vxrnOutput.serverOutput.entries()]
|
|
@@ -828,7 +663,9 @@ export async function build(args: {
|
|
|
828
663
|
|
|
829
664
|
// also look up in manifest for additional info (css, nested imports, etc)
|
|
830
665
|
const manifestKey = `${routerRoot}${foundRoute.file.slice(1)}`
|
|
831
|
-
const clientManifestEntry =
|
|
666
|
+
const clientManifestEntry: ClientManifestEntry | undefined =
|
|
667
|
+
vxrnOutput.clientManifest[manifestKey] ??
|
|
668
|
+
(clientChunk ? clientManifestByFile.get(clientChunk.fileName) : undefined)
|
|
832
669
|
|
|
833
670
|
// SPA and SSG routes may not have client chunks - that's expected
|
|
834
671
|
if (!clientChunk && foundRoute.type !== 'spa' && foundRoute.type !== 'ssg') {
|
|
@@ -853,7 +690,7 @@ export async function build(args: {
|
|
|
853
690
|
}
|
|
854
691
|
|
|
855
692
|
function collectImports(
|
|
856
|
-
entry: ClientManifestEntry
|
|
693
|
+
entry: Partial<ClientManifestEntry>,
|
|
857
694
|
{ type = 'js' }: { type?: 'js' | 'css' } = {}
|
|
858
695
|
): string[] {
|
|
859
696
|
const { imports = [], css } = entry
|
|
@@ -924,13 +761,9 @@ export async function build(args: {
|
|
|
924
761
|
}
|
|
925
762
|
|
|
926
763
|
// add the page itself using the direct chunk lookup (more reliable than manifest)
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
routePreloads[
|
|
930
|
-
} else if (clientManifestEntry) {
|
|
931
|
-
// fallback to manifest if no chunk (shouldn't happen normally)
|
|
932
|
-
const routeKey = `/${routerRoot}${foundRoute.file.slice(1)}`
|
|
933
|
-
routePreloads[routeKey] = `/${clientManifestEntry.file}`
|
|
764
|
+
const routeChunkFile = clientChunk?.fileName ?? clientManifestEntry?.file
|
|
765
|
+
if (routeChunkFile) {
|
|
766
|
+
routePreloads[`/${routerRoot}${foundRoute.file.slice(1)}`] = `/${routeChunkFile}`
|
|
934
767
|
}
|
|
935
768
|
|
|
936
769
|
const preloadSetupFilePreloads = (() => {
|
|
@@ -1106,11 +939,15 @@ export async function build(args: {
|
|
|
1106
939
|
|
|
1107
940
|
let exported
|
|
1108
941
|
try {
|
|
1109
|
-
exported = await
|
|
942
|
+
exported = await getRouteExports(
|
|
943
|
+
vxrnOutput.serverEntry,
|
|
944
|
+
routerRoot,
|
|
945
|
+
foundRoute.file
|
|
946
|
+
)
|
|
1110
947
|
} catch (err) {
|
|
1111
948
|
console.error(`Error importing page (original error)`, err)
|
|
1112
949
|
// err cause not showing in vite or something
|
|
1113
|
-
throw new Error(`Error importing page: ${
|
|
950
|
+
throw new Error(`Error importing page: ${foundRoute.file}`, {
|
|
1114
951
|
cause: err,
|
|
1115
952
|
})
|
|
1116
953
|
}
|
|
@@ -1180,6 +1017,7 @@ export async function build(args: {
|
|
|
1180
1017
|
return workerPool
|
|
1181
1018
|
.buildPage({
|
|
1182
1019
|
serverEntry: vxrnOutput.serverEntry,
|
|
1020
|
+
routerRoot,
|
|
1183
1021
|
path,
|
|
1184
1022
|
relativeId,
|
|
1185
1023
|
params,
|
|
@@ -1209,6 +1047,7 @@ export async function build(args: {
|
|
|
1209
1047
|
const built = await runWithAsyncLocalContext(async () => {
|
|
1210
1048
|
return await buildPage(
|
|
1211
1049
|
vxrnOutput.serverEntry,
|
|
1050
|
+
routerRoot,
|
|
1212
1051
|
path,
|
|
1213
1052
|
relativeId,
|
|
1214
1053
|
params,
|
|
@@ -1435,21 +1274,9 @@ export async function build(args: {
|
|
|
1435
1274
|
)
|
|
1436
1275
|
return importPath.startsWith('.') ? importPath : `./${importPath}`
|
|
1437
1276
|
}
|
|
1438
|
-
const pageRouteMap: string[] = []
|
|
1439
1277
|
const apiRouteMap: string[] = []
|
|
1440
1278
|
const middlewareRouteMap: string[] = []
|
|
1441
1279
|
|
|
1442
|
-
// Generate lazy imports for SSR/SSG page server bundles
|
|
1443
|
-
for (const [routeFile, info] of Object.entries(
|
|
1444
|
-
buildInfoForWriting.routeToBuildInfo
|
|
1445
|
-
)) {
|
|
1446
|
-
if (info.serverJsPath) {
|
|
1447
|
-
const importPath =
|
|
1448
|
-
'./' + info.serverJsPath.replace(new RegExp(`^${outDir}/`), '')
|
|
1449
|
-
pageRouteMap.push(` '${routeFile}': () => import('${importPath}')`)
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
1280
|
// Generate lazy imports for API routes
|
|
1454
1281
|
for (const route of buildInfoForWriting.manifest.apiRoutes) {
|
|
1455
1282
|
if (route.file) {
|
|
@@ -1484,9 +1311,6 @@ import { serve, setFetchStaticHtml } from 'one/serve-worker'
|
|
|
1484
1311
|
// Lazy import map - modules load on-demand when route is matched
|
|
1485
1312
|
const lazyRoutes = {
|
|
1486
1313
|
serverEntry: () => import('./server/_virtual_one-entry.js'),
|
|
1487
|
-
pages: {
|
|
1488
|
-
${pageRouteMap.join(',\n')}
|
|
1489
|
-
},
|
|
1490
1314
|
api: {
|
|
1491
1315
|
${apiRouteMap.join(',\n')}
|
|
1492
1316
|
},
|
package/src/cli/buildPage.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { isResponse } from '../utils/isResponse'
|
|
|
14
14
|
import { toAbsolute, toAbsoluteUrl } from '../utils/toAbsolute'
|
|
15
15
|
import { replaceLoader } from '../vite/replaceLoader'
|
|
16
16
|
import type { One, RouteInfo } from '../vite/types'
|
|
17
|
+
import { getRouteExports } from './serverRouteModules'
|
|
17
18
|
|
|
18
19
|
const { readFile, outputFile } = FSExtra
|
|
19
20
|
|
|
@@ -45,6 +46,7 @@ export function printBuildTimings() {
|
|
|
45
46
|
|
|
46
47
|
export async function buildPage(
|
|
47
48
|
serverEntry: string,
|
|
49
|
+
routerRoot: string,
|
|
48
50
|
path: string,
|
|
49
51
|
relativeId: string,
|
|
50
52
|
params: any,
|
|
@@ -186,7 +188,7 @@ prefetchCSS()
|
|
|
186
188
|
recordTiming('writeCSSPreload', performance.now() - t0)
|
|
187
189
|
|
|
188
190
|
t0 = performance.now()
|
|
189
|
-
const exported = await
|
|
191
|
+
const exported = await getRouteExports(serverEntry, routerRoot, foundRoute.file)
|
|
190
192
|
recordTiming('importServerModule', performance.now() - t0)
|
|
191
193
|
|
|
192
194
|
const loaderProps: LoaderProps = { path, params }
|
|
@@ -200,14 +202,13 @@ prefetchCSS()
|
|
|
200
202
|
const layoutResults = await Promise.all(
|
|
201
203
|
foundRoute.layouts.map(async (layout) => {
|
|
202
204
|
try {
|
|
203
|
-
|
|
204
|
-
if (!layoutServerPath) {
|
|
205
|
+
if (!layout.loaderServerPath) {
|
|
205
206
|
return { contextKey: layout.contextKey, loaderData: undefined }
|
|
206
207
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
208
|
+
const layoutExported = await getRouteExports(
|
|
209
|
+
serverEntry,
|
|
210
|
+
routerRoot,
|
|
211
|
+
layout.contextKey
|
|
211
212
|
)
|
|
212
213
|
const layoutLoaderData = await layoutExported?.loader?.(loaderProps)
|
|
213
214
|
return { contextKey: layout.contextKey, loaderData: layoutLoaderData }
|
|
@@ -301,6 +302,7 @@ if (typeof document === 'undefined') globalThis.document = {}
|
|
|
301
302
|
replaceLoader({
|
|
302
303
|
code,
|
|
303
304
|
loaderData,
|
|
305
|
+
routeId: foundRoute.file,
|
|
304
306
|
})
|
|
305
307
|
await outputFile(loaderPartialPath, withLoader)
|
|
306
308
|
// native-friendly CJS version with just the data (no ESM imports)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { getRouteExportsFromEntry } from '../server/routeExportsFromEntry'
|
|
2
|
+
import { toAbsoluteUrl } from '../utils/toAbsolute'
|
|
3
|
+
|
|
4
|
+
// entry evaluation is expensive and every page in a build shares it
|
|
5
|
+
const serverEntries = new Map<string, Promise<any>>()
|
|
6
|
+
|
|
7
|
+
function loadServerEntry(serverEntry: string) {
|
|
8
|
+
let loading = serverEntries.get(serverEntry)
|
|
9
|
+
if (!loading) {
|
|
10
|
+
loading = import(toAbsoluteUrl(serverEntry))
|
|
11
|
+
serverEntries.set(serverEntry, loading)
|
|
12
|
+
}
|
|
13
|
+
return loading
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function getRouteExports(
|
|
17
|
+
serverEntry: string,
|
|
18
|
+
routerRoot: string,
|
|
19
|
+
routeFile: string
|
|
20
|
+
): Promise<Record<string, any>> {
|
|
21
|
+
const entry = await loadServerEntry(serverEntry)
|
|
22
|
+
const exported = await getRouteExportsFromEntry(entry, routerRoot, routeFile)
|
|
23
|
+
|
|
24
|
+
if (!exported) {
|
|
25
|
+
const routes =
|
|
26
|
+
entry?.default?.options?.routes ?? entry?.default?.default?.options?.routes
|
|
27
|
+
throw new Error(
|
|
28
|
+
`[one] route ${routeFile} is missing from the built server entry route map (looked in: ${Object.keys(routes ?? {}).join(', ')})`
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return exported
|
|
33
|
+
}
|
package/src/cli/workerPool.ts
CHANGED
package/src/createApp.tsx
CHANGED
|
@@ -7,7 +7,7 @@ import { render } from './render'
|
|
|
7
7
|
import { initClientMatches } from './router/router'
|
|
8
8
|
import { registerPreloadedRoute } from './router/useViteRoutes'
|
|
9
9
|
import { setupSkewProtection } from './skewProtection'
|
|
10
|
-
import { handleSkewError } from './utils/dynamicImport'
|
|
10
|
+
import { handleSkewError, isChunkLoadError } from './utils/dynamicImport'
|
|
11
11
|
import { findRootLayout } from './utils/findRootLayout'
|
|
12
12
|
import type { RenderAppProps } from './types'
|
|
13
13
|
import type { OneLinkingConfig } from './link/getLinking'
|
|
@@ -293,5 +293,9 @@ export function createApp(options: CreateAppProps) {
|
|
|
293
293
|
})
|
|
294
294
|
.catch((err) => {
|
|
295
295
|
console.error(`Error during client initialization:`, err)
|
|
296
|
+
if (isChunkLoadError(err)) {
|
|
297
|
+
handleSkewError()
|
|
298
|
+
}
|
|
296
299
|
})
|
|
297
300
|
}
|
|
301
|
+
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { LOADER_JS_POSTFIX_UNCACHED } from './constants'
|
|
2
|
+
import {
|
|
3
|
+
compileManifest,
|
|
4
|
+
getURLfromRequestURL,
|
|
5
|
+
isPageRequestMethod,
|
|
6
|
+
isStaticAssetRequestPath,
|
|
7
|
+
resolveAPIRoute,
|
|
8
|
+
resolveLoaderRoute,
|
|
9
|
+
resolvePageRoute,
|
|
10
|
+
runMiddlewares,
|
|
11
|
+
type RequestHandlerResponse,
|
|
12
|
+
type RequestHandlers,
|
|
13
|
+
} from './createHandleRequest'
|
|
14
|
+
import { getPathFromLoaderPath } from './utils/cleanUrl'
|
|
15
|
+
import { getManifest } from './vite/getManifest'
|
|
16
|
+
|
|
17
|
+
const debugRouter = process.env.ONE_DEBUG_ROUTER
|
|
18
|
+
|
|
19
|
+
// node-dev request handler. kept out of createHandleRequest.ts so the worker
|
|
20
|
+
// graph (one/serve-worker) does not pull getManifest -> micromatch/fast-glob.
|
|
21
|
+
export function createHandleRequest(
|
|
22
|
+
handlers: RequestHandlers,
|
|
23
|
+
{
|
|
24
|
+
routerRoot,
|
|
25
|
+
ignoredRouteFiles,
|
|
26
|
+
routePaths,
|
|
27
|
+
}: { routerRoot: string; ignoredRouteFiles?: string[]; routePaths?: string[] }
|
|
28
|
+
) {
|
|
29
|
+
const manifest = getManifest({ routerRoot, ignoredRouteFiles, routePaths })
|
|
30
|
+
if (!manifest) {
|
|
31
|
+
throw new Error(`No routes manifest`)
|
|
32
|
+
}
|
|
33
|
+
const compiledManifest = compileManifest(manifest)
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
manifest,
|
|
37
|
+
handler: async function handleRequest(
|
|
38
|
+
request: Request
|
|
39
|
+
): Promise<RequestHandlerResponse> {
|
|
40
|
+
const url = getURLfromRequestURL(request)
|
|
41
|
+
const { pathname } = url
|
|
42
|
+
|
|
43
|
+
// skip paths handled by vite internals or react native dev middleware
|
|
44
|
+
if (
|
|
45
|
+
pathname === '/__vxrnhmr' ||
|
|
46
|
+
pathname.startsWith('/@vite/') ||
|
|
47
|
+
pathname.startsWith('/@fs/') ||
|
|
48
|
+
pathname.startsWith('/@id/') ||
|
|
49
|
+
pathname.startsWith('/node_modules/') ||
|
|
50
|
+
pathname.startsWith('/debugger-frontend') ||
|
|
51
|
+
pathname.startsWith('/inspector')
|
|
52
|
+
) {
|
|
53
|
+
return null
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const looksLikeStaticFile = isStaticAssetRequestPath(pathname)
|
|
57
|
+
|
|
58
|
+
if (handlers.handleAPI) {
|
|
59
|
+
const apiRoute = compiledManifest.apiRoutes.find((route) => {
|
|
60
|
+
return route.compiledRegex.test(pathname)
|
|
61
|
+
})
|
|
62
|
+
if (apiRoute) {
|
|
63
|
+
if (debugRouter) {
|
|
64
|
+
console.info(`[one] ⚡ ${pathname} → matched API route: ${apiRoute.page}`)
|
|
65
|
+
}
|
|
66
|
+
return await resolveAPIRoute(handlers, request, url, apiRoute)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!isPageRequestMethod(request.method)) {
|
|
71
|
+
return null
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (handlers.handleLoader) {
|
|
75
|
+
const isClientRequestingNewRoute = pathname.endsWith(LOADER_JS_POSTFIX_UNCACHED)
|
|
76
|
+
|
|
77
|
+
if (isClientRequestingNewRoute) {
|
|
78
|
+
const platformParam = url.searchParams.get('platform')
|
|
79
|
+
const isNativePlatform =
|
|
80
|
+
platformParam === 'ios' ||
|
|
81
|
+
platformParam === 'android' ||
|
|
82
|
+
platformParam === 'native'
|
|
83
|
+
|
|
84
|
+
// for native requests, try serving the pre-built .native.js static file first
|
|
85
|
+
// (SSG/SPA routes generate standalone CJS loaders at build time)
|
|
86
|
+
if (isNativePlatform && handlers.handleStaticFile) {
|
|
87
|
+
const nativeLoaderPath = pathname.replace(/\.js$/, '.native.js')
|
|
88
|
+
const staticResponse = await handlers.handleStaticFile(nativeLoaderPath)
|
|
89
|
+
if (staticResponse) {
|
|
90
|
+
return staticResponse
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const originalUrl = getPathFromLoaderPath(pathname)
|
|
95
|
+
|
|
96
|
+
for (const route of compiledManifest.pageRoutes) {
|
|
97
|
+
if (route.file === '') {
|
|
98
|
+
// ignore not found route
|
|
99
|
+
continue
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const finalUrl = new URL(originalUrl, url.origin)
|
|
103
|
+
finalUrl.search = url.search
|
|
104
|
+
|
|
105
|
+
if (!route.compiledRegex.test(finalUrl.pathname)) {
|
|
106
|
+
continue
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// route is known to export no loader → return empty module without
|
|
110
|
+
// importing the page bundle. on workerd/cloudflare, evaluating a
|
|
111
|
+
// no-loader SSG page's server bundle can crash when it pulls in
|
|
112
|
+
// RN/Tamagui modules that aren't compatible with the workers runtime.
|
|
113
|
+
if (route.hasLoader === false) {
|
|
114
|
+
const emptyBody = isNativePlatform
|
|
115
|
+
? 'exports.loader=function(){return undefined}'
|
|
116
|
+
: 'export function loader() { return undefined }'
|
|
117
|
+
return new Response(emptyBody, {
|
|
118
|
+
headers: { 'Content-Type': 'text/javascript' },
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const cleanedRequest = new Request(finalUrl, request)
|
|
123
|
+
return resolveLoaderRoute(handlers, cleanedRequest, finalUrl, route)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// no matching route - return empty module so client handles gracefully
|
|
127
|
+
const emptyBody = isNativePlatform
|
|
128
|
+
? 'exports.loader=function(){return{}}'
|
|
129
|
+
: 'export {}'
|
|
130
|
+
return new Response(emptyBody, {
|
|
131
|
+
headers: { 'Content-Type': 'text/javascript' },
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (handlers.handlePage) {
|
|
137
|
+
for (const route of compiledManifest.pageRoutes) {
|
|
138
|
+
if (!route.compiledRegex.test(pathname)) {
|
|
139
|
+
continue
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// static asset requests (sourcemaps, favicons, fonts, …) should not
|
|
143
|
+
// SSR the user's +not-found page or hijack a dynamic route. for
|
|
144
|
+
// +not-found we still run middleware so it can intercept, then
|
|
145
|
+
// short-circuit to a bare 404 instead of rendering the page tree.
|
|
146
|
+
const isDynamicRoute = Object.keys(route.routeKeys).length > 0
|
|
147
|
+
const isNotFoundRoute = route.page.endsWith('/+not-found')
|
|
148
|
+
if (looksLikeStaticFile && isNotFoundRoute) {
|
|
149
|
+
if (debugRouter) {
|
|
150
|
+
console.info(
|
|
151
|
+
`[one] ⚡ ${pathname} → bare 404 for static probe on ${route.page}`
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
if (!route.middlewares?.length) {
|
|
155
|
+
return null
|
|
156
|
+
}
|
|
157
|
+
return await runMiddlewares(handlers, request, route, async () => {
|
|
158
|
+
return new Response(null, {
|
|
159
|
+
status: 404,
|
|
160
|
+
headers: { 'Content-Type': 'text/plain' },
|
|
161
|
+
})
|
|
162
|
+
})
|
|
163
|
+
}
|
|
164
|
+
if (looksLikeStaticFile && isDynamicRoute) {
|
|
165
|
+
if (debugRouter) {
|
|
166
|
+
console.info(
|
|
167
|
+
`[one] ⚡ ${pathname} → skipping dynamic route ${route.page} for static asset`
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
continue
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (debugRouter) {
|
|
174
|
+
console.info(
|
|
175
|
+
`[one] ⚡ ${pathname} → matched page route: ${route.page} (${route.type})`
|
|
176
|
+
)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return resolvePageRoute(handlers, request, url, route)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return null
|
|
184
|
+
},
|
|
185
|
+
}
|
|
186
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it, vi, beforeEach } from 'vitest'
|
|
2
|
-
import { createHandleRequest } from './
|
|
2
|
+
import { createHandleRequest } from './createDevHandleRequest'
|
|
3
3
|
|
|
4
4
|
// Mock the manifest. Specific routes come before dynamic ones, matching how
|
|
5
5
|
// the real manifest is ordered after matchers.sortRoutes().
|