diff --git a/.gitignore b/.gitignore index 22e403f209dd..67b3d8e546a7 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,4 @@ playground/ .cursor .claude AGENTS.md +.specify/ diff --git a/packages/cli/plugin-bff/package.json b/packages/cli/plugin-bff/package.json index bbf4e232a9a2..2d8e230f61d5 100644 --- a/packages/cli/plugin-bff/package.json +++ b/packages/cli/plugin-bff/package.json @@ -32,7 +32,7 @@ "jsnext:source": "./src/cli.ts", "default": "./dist/cjs/cli.js" }, - "./server": { + "./server-plugin": { "types": "./dist/types/server.d.ts", "jsnext:source": "./src/server.ts", "default": "./dist/cjs/server.js" @@ -42,12 +42,12 @@ "jsnext:source": "./src/loader.ts", "default": "./dist/cjs/loader.js" }, - "./hono": { + "./server": { "types": "./dist/types/runtime/hono/index.d.ts", "jsnext:source": "./src/runtime/hono/index.ts", "default": "./dist/cjs/runtime/hono/index.js" }, - "./runtime/create-request": { + "./client": { "types": "./dist/types/create-request/index.d.ts", "jsnext:source": "./src/runtime/create-request/index.ts", "default": "./dist/cjs/runtime/create-request/index.js" @@ -61,13 +61,13 @@ "cli": [ "./dist/types/cli.d.ts" ], - "server": [ + "server-plugin": [ "./dist/types/server.d.ts" ], - "hono": [ + "server": [ "./dist/types/runtime/hono/index.d.ts" ], - "runtime/create-request": [ + "client": [ "./dist/types/runtime/create-request/index.d.ts" ] } diff --git a/packages/cli/plugin-bff/src/cli.ts b/packages/cli/plugin-bff/src/cli.ts index 2f6b9ed09676..b644e321571a 100644 --- a/packages/cli/plugin-bff/src/cli.ts +++ b/packages/cli/plugin-bff/src/cli.ts @@ -19,8 +19,8 @@ import runtimeGenerator from './utils/runtimeGenerator'; const DEFAULT_API_PREFIX = '/api'; const TS_CONFIG_FILENAME = 'tsconfig.json'; -const RUNTIME_CREATE_REQUEST = '@modern-js/plugin-bff/runtime/create-request'; -const RUNTIME_HONO = '@modern-js/plugin-bff/hono'; +const RUNTIME_CREATE_REQUEST = '@modern-js/plugin-bff/client'; +const RUNTIME_HONO = '@modern-js/plugin-bff/server'; export const bffPlugin = (): CliPlugin => ({ name: '@modern-js/plugin-bff', @@ -230,13 +230,6 @@ export const bffPlugin = (): CliPlugin => ({ requestCreator: (bff as any)?.requestCreator, httpMethodDecider, }); - - chain.resolve.alias.set('@api', apiDirectory); - - chain.resolve.alias.set( - '@modern-js/runtime/bff', - RUNTIME_CREATE_REQUEST, - ); }, }, output: { @@ -284,7 +277,7 @@ export const bffPlugin = (): CliPlugin => ({ api._internalServerPlugins(({ plugins }) => { plugins.push({ - name: '@modern-js/plugin-bff/server', + name: '@modern-js/plugin-bff/server-plugin', }); return { plugins }; }); diff --git a/packages/cli/plugin-bff/src/helper.ts b/packages/cli/plugin-bff/src/helper.ts deleted file mode 100644 index b30d31cbf750..000000000000 --- a/packages/cli/plugin-bff/src/helper.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as path from 'path'; -import { registerPaths } from '@modern-js/bff-core'; - -const serverRuntimeAlias = '@modern-js/runtime/server'; -const serverRuntimePath = '.runtime-exports/server'; - -const registerModernRuntimePath = (internalDirectory: string) => { - const paths = { - [serverRuntimeAlias]: path.join(internalDirectory, serverRuntimePath), - }; - const unRegister = registerPaths(paths); - return unRegister; -}; - -export { registerModernRuntimePath }; diff --git a/packages/cli/plugin-bff/src/server.ts b/packages/cli/plugin-bff/src/server.ts index 8d1ec47aaf5c..264d8def4768 100644 --- a/packages/cli/plugin-bff/src/server.ts +++ b/packages/cli/plugin-bff/src/server.ts @@ -142,14 +142,11 @@ export default (): ServerPlugin => ({ prefix, httpMethodDecider, }); - const apiMode = apiRouter.getApiMode(); - const apiHandlerInfos = await apiRouter.getApiHandlers(); api.updateServerContext({ ...appContext, apiRouter, apiHandlerInfos, - apiMode, }); return next(input); }) as any); diff --git a/packages/cli/plugin-bff/src/utils/runtimeGenerator.ts b/packages/cli/plugin-bff/src/utils/runtimeGenerator.ts index 5bc2a7e807f9..b23120fe08e3 100644 --- a/packages/cli/plugin-bff/src/utils/runtimeGenerator.ts +++ b/packages/cli/plugin-bff/src/utils/runtimeGenerator.ts @@ -1,22 +1,50 @@ import path from 'path'; import { fs } from '@modern-js/utils'; +/** + * Get package name from package.json file + * @param appDirectory - Application directory path + * @returns Package name or undefined if not found + */ +const getPackageName = (appDirectory: string): string | undefined => { + try { + const packageJsonPath = path.resolve(appDirectory, './package.json'); + const packageJson = require(packageJsonPath); + return packageJson.name; + } catch (error) { + // If package.json doesn't exist or is invalid, return undefined + return undefined; + } +}; + async function runtimeGenerator({ runtime, appDirectory, relativeDistPath, -}: { runtime: string; appDirectory: string; relativeDistPath: string }) { + packageName, +}: { + runtime: string; + appDirectory: string; + relativeDistPath: string; + packageName?: string; +}) { const pluginDir = path.resolve( appDirectory, `./${relativeDistPath}`, 'runtime', ); + const requestId = + packageName || + getPackageName(appDirectory) || + process.env.npm_package_name || + 'default'; + const source = `import { configure as _configure } from '${runtime}' const configure = (options) => { return _configure({ ...options, - requestId: '${process.env.npm_package_name}', + requestId: '${requestId}', }); } export { configure } diff --git a/packages/cli/plugin-bff/tests/__snapshots__/server.test.ts.snap b/packages/cli/plugin-bff/tests/__snapshots__/server.test.ts.snap index 3718d9423cb0..28adc45c2b3e 100644 --- a/packages/cli/plugin-bff/tests/__snapshots__/server.test.ts.snap +++ b/packages/cli/plugin-bff/tests/__snapshots__/server.test.ts.snap @@ -3,7 +3,7 @@ exports[`bff server plugin prepareApiServer should work well 1`] = ` [ { - "filename": "/fixtures/function/api/hello.ts", + "filename": "/fixtures/function/api/lambda/hello.ts", "handler": [Function], "httpMethod": "GET", "name": "get", @@ -11,7 +11,7 @@ exports[`bff server plugin prepareApiServer should work well 1`] = ` "routePath": "/hello", }, { - "filename": "/fixtures/function/api/upload.ts", + "filename": "/fixtures/function/api/lambda/upload.ts", "handler": [Function], "httpMethod": "GET", "name": "get", @@ -19,7 +19,7 @@ exports[`bff server plugin prepareApiServer should work well 1`] = ` "routePath": "/upload", }, { - "filename": "/fixtures/function/api/user/[id].ts", + "filename": "/fixtures/function/api/lambda/user/[id].ts", "handler": [Function], "httpMethod": "GET", "name": "get", @@ -32,7 +32,7 @@ exports[`bff server plugin prepareApiServer should work well 1`] = ` exports[`bff server plugin prepareApiServer should work well with prefix 1`] = ` [ { - "filename": "/fixtures/function/api/hello.ts", + "filename": "/fixtures/function/api/lambda/hello.ts", "handler": [Function], "httpMethod": "GET", "name": "get", @@ -40,7 +40,7 @@ exports[`bff server plugin prepareApiServer should work well with prefix 1`] = ` "routePath": "/api/hello", }, { - "filename": "/fixtures/function/api/upload.ts", + "filename": "/fixtures/function/api/lambda/upload.ts", "handler": [Function], "httpMethod": "GET", "name": "get", @@ -48,7 +48,7 @@ exports[`bff server plugin prepareApiServer should work well with prefix 1`] = ` "routePath": "/api/upload", }, { - "filename": "/fixtures/function/api/user/[id].ts", + "filename": "/fixtures/function/api/lambda/user/[id].ts", "handler": [Function], "httpMethod": "GET", "name": "get", diff --git a/packages/cli/plugin-bff/tests/fixtures/function/api/hello.ts b/packages/cli/plugin-bff/tests/fixtures/function/api/lambda/hello.ts similarity index 100% rename from packages/cli/plugin-bff/tests/fixtures/function/api/hello.ts rename to packages/cli/plugin-bff/tests/fixtures/function/api/lambda/hello.ts diff --git a/packages/cli/plugin-bff/tests/fixtures/function/api/upload.ts b/packages/cli/plugin-bff/tests/fixtures/function/api/lambda/upload.ts similarity index 100% rename from packages/cli/plugin-bff/tests/fixtures/function/api/upload.ts rename to packages/cli/plugin-bff/tests/fixtures/function/api/lambda/upload.ts diff --git a/packages/cli/plugin-bff/tests/fixtures/function/api/user/[id].ts b/packages/cli/plugin-bff/tests/fixtures/function/api/lambda/user/[id].ts similarity index 100% rename from packages/cli/plugin-bff/tests/fixtures/function/api/user/[id].ts rename to packages/cli/plugin-bff/tests/fixtures/function/api/lambda/user/[id].ts diff --git a/packages/cli/plugin-bff/types.d.ts b/packages/cli/plugin-bff/types.d.ts deleted file mode 100644 index 852e94133552..000000000000 --- a/packages/cli/plugin-bff/types.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module '@modern-js/runtime/bff' { - export * from '@modern-js/create-request'; -} diff --git a/packages/document/main-doc/docs/en/apis/app/runtime/bff/use-hono-context.mdx b/packages/document/main-doc/docs/en/apis/app/runtime/bff/use-hono-context.mdx index d53115301fcf..cea27ed21994 100644 --- a/packages/document/main-doc/docs/en/apis/app/runtime/bff/use-hono-context.mdx +++ b/packages/document/main-doc/docs/en/apis/app/runtime/bff/use-hono-context.mdx @@ -8,7 +8,7 @@ Used to obtain Hono context in an integrated BFF function. ## Usage ```ts -import { useHonoContext } from '@modern-js/plugin-bff/hono'; +import { useHonoContext } from '@modern-js/plugin-bff/server'; ``` ## Function Signature @@ -20,7 +20,7 @@ import { useHonoContext } from '@modern-js/plugin-bff/hono'; Developers can use `context` to obtain more request information, such as setting response headers: ```ts -import { useHonoContext } from '@modern-js/plugin-bff/hono'; +import { useHonoContext } from '@modern-js/plugin-bff/server'; export async function get() { const c = useHonoContext(); diff --git a/packages/document/main-doc/docs/en/configure/app/server/ssr.mdx b/packages/document/main-doc/docs/en/configure/app/server/ssr.mdx index 3054e87ff7a2..f8368c76256d 100644 --- a/packages/document/main-doc/docs/en/configure/app/server/ssr.mdx +++ b/packages/document/main-doc/docs/en/configure/app/server/ssr.mdx @@ -29,7 +29,6 @@ When the value type is `Object`, the following properties can be configured: | ---------------- | ------------------------------------------------------------- | -------------------------------------- | ---------------------------------------------------------------------------- | | mode | `string` | `string` | which defaults to using `renderToString` for rendering. Configure `stream` to enable streaming rendering | | forceCSR | `boolean` | `false` | which is off by default for forcing CSR rendering. Configure `true` to force CSR by adding `?csr=true` or adding `x-modern-ssr-fallback` header when accessing the page | -| disablePrerender | `boolean` | `fasle` | To ensure compatibility with the old data request method (`useLoader`), by default, Modern.js performs pre-rendering of components.However, if developers want to reduce one rendering when there is no use of the useLoader API in your project, you can set the configuration `disablePrerender=true` | | unsafeHeaders | `string[]` | `[]` | For safety reasons, Modern.js does not add excessive content to SSR_DATA. Developers can use this configuration to specify the headers that need to be injected | | loaderFailureMode| `clientRender \| errorBoundary` | `errorBoundary` | The default configuration is `'errorBoundary'`, when an error occurs in [data loader](/en/guides/basic-features/data/data-fetch.html#data-loader-recommended), it will default to rendering the [`Error`](/en/guides/basic-features/routes.html#errorboundary) component of the route. When configured as `'clientRender'`, if a loader throws an error, it switch to client-side rendering,you can use it with [Client Loader](/en/guides/basic-features/data/data-fetch.html#client-loader) | diff --git a/packages/document/main-doc/docs/en/guides/advanced-features/bff/cross-project.mdx b/packages/document/main-doc/docs/en/guides/advanced-features/bff/cross-project.mdx index 6b98a6d024e0..300c6cf32946 100644 --- a/packages/document/main-doc/docs/en/guides/advanced-features/bff/cross-project.mdx +++ b/packages/document/main-doc/docs/en/guides/advanced-features/bff/cross-project.mdx @@ -90,7 +90,7 @@ The `configure` function from `${package_name}/runtime` supports domain configur ```ts title="src/routes/page.tsx" import { configure } from '${package_name}/runtime'; -import { configure as innerConfigure } from '@modern-js/runtime/bff'; +import { configure as innerConfigure } from '@modern-js/plugin-bff/client'; import axios from 'axios'; configure({ diff --git a/packages/document/main-doc/docs/en/guides/advanced-features/bff/frameworks.mdx b/packages/document/main-doc/docs/en/guides/advanced-features/bff/frameworks.mdx index f6a818f9cb0f..da64d6a95236 100644 --- a/packages/document/main-doc/docs/en/guides/advanced-features/bff/frameworks.mdx +++ b/packages/document/main-doc/docs/en/guides/advanced-features/bff/frameworks.mdx @@ -12,7 +12,7 @@ Modern.js uses [Hono.js](https://hono.dev/) as the BFF and Server runtime framew Sometimes in BFF functions, it's necessary to obtain the request context to handle more logic. In such cases, you can use `useHonoContext` to get it: ```ts title="api/lambda/hello.ts" -import { useHonoContext } from '@modern-js/plugin-bff/hono' +import { useHonoContext } from '@modern-js/plugin-bff/server' export const get = async () => { const c = useHonoContext(); console.info(`access url: ${c.req.url}`); diff --git a/packages/document/main-doc/docs/en/guides/advanced-features/bff/function.mdx b/packages/document/main-doc/docs/en/guides/advanced-features/bff/function.mdx index b23cf27fea33..6ec98c9f2940 100644 --- a/packages/document/main-doc/docs/en/guides/advanced-features/bff/function.mdx +++ b/packages/document/main-doc/docs/en/guides/advanced-features/bff/function.mdx @@ -191,7 +191,7 @@ Parameters following the dynamic path are an object called `RequestOption`, whic In a standard function without dynamic routes, `RequestOption` can be obtained from the first parameter, for example: ```ts title="api/lambda/hello.ts" -import type { RequestOption } from '@modern-js/runtime/server'; +import type { RequestOption } from '@modern-js/plugin-bff/server'; export async function post({ query, @@ -204,7 +204,7 @@ export async function post({ Custom types can also be used here: ```ts title="api/lambda/hello.ts" -import type { RequestOption } from '@modern-js/runtime/server'; +import type { RequestOption } from '@modern-js/plugin-bff/server'; type IQuery = { // some types diff --git a/packages/document/main-doc/docs/en/guides/advanced-features/bff/sdk.mdx b/packages/document/main-doc/docs/en/guides/advanced-features/bff/sdk.mdx index b38de058ddba..b9ba13e2fd68 100644 --- a/packages/document/main-doc/docs/en/guides/advanced-features/bff/sdk.mdx +++ b/packages/document/main-doc/docs/en/guides/advanced-features/bff/sdk.mdx @@ -13,7 +13,7 @@ The `configure` function needs to be called before all BFF requests are sent to ::: ```tsx title="routes/page.tsx" -import { configure } from '@modern-js/runtime/bff'; +import { configure } from '@modern-js/plugin-bff/client'; configure({ // ... @@ -90,7 +90,7 @@ There are some conventions when configuring custom request functions: Below is an example of using axios to customize a request function: ```tsx title="App.tsx" -import { configure } from '@modern-js/runtime/bff'; +import { configure } from '@modern-js/plugin-bff/client'; import type { Method, AxiosRequestHeaders as Headers } from 'axios'; configure({ @@ -105,4 +105,4 @@ configure({ return res.data; }, }); -``` \ No newline at end of file +``` diff --git a/packages/document/main-doc/docs/en/guides/advanced-features/web-server.mdx b/packages/document/main-doc/docs/en/guides/advanced-features/web-server.mdx index 409251139c22..10f0696b5ddc 100644 --- a/packages/document/main-doc/docs/en/guides/advanced-features/web-server.mdx +++ b/packages/document/main-doc/docs/en/guides/advanced-features/web-server.mdx @@ -299,7 +299,7 @@ Currently, two types of Hooks are available: `AfterMatch` and `AfterRender`. Dev import type { AfterMatchHook, AfterRenderHook, -} from '@modern-js/runtime/server'; +} from '@modern-js/server-runtime'; export const afterMatch: AfterMatchHook = (ctx, next) => { next(); diff --git a/packages/document/main-doc/docs/en/guides/basic-features/render/ssr-cache.mdx b/packages/document/main-doc/docs/en/guides/basic-features/render/ssr-cache.mdx index defe33f638bd..1a89576370cb 100644 --- a/packages/document/main-doc/docs/en/guides/basic-features/render/ssr-cache.mdx +++ b/packages/document/main-doc/docs/en/guides/basic-features/render/ssr-cache.mdx @@ -13,7 +13,7 @@ Requires version x.43.0+ Create a `server/cache.[t|j]s` file in your application and export the `cacheOption` configuration to enable SSR rendering cache: ```ts title="server/cache.ts" -import type { CacheOption } from '@modern-js/runtime/server; +import type { CacheOption } from '@modern-js/server-runtime; export const cacheOption: CacheOption = { maxAge: 500, // ms @@ -28,7 +28,7 @@ export const cacheOption: CacheOption = { The caching strategy implements [stale-while-revalidate](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control). Within the `maxAge` period, the cache content is directly returned. Exceeding `maxAge` but within `staleWhileRevalidate`, the cache content is still returned directly, but it re-renders asynchronously. - + **Object Type** ```ts @@ -52,7 +52,7 @@ export type CacheOptionProvider = ( Sometimes, developers need to use `req` to customize the cache key, or prevent caching for specific URLs. You can configure this as a function, as shown: ```ts title="server/cache.ts" -import type { CacheOption, CacheOptionProvider } from '@modern-js/runtime/server; +import type { CacheOption, CacheOptionProvider } from '@modern-js/server-runtime; const provider: CacheOptionProvider = (req) => { const { url, headers, ... } = req; @@ -80,7 +80,7 @@ export type CacheOptions = Record; Sometimes, different routes require different caching strategies. We also offer a mapping configuration method, as shown below: ```ts title="server/cache.ts" -import type { CacheOption } from '@modern-js/runtime/server; +import type { CacheOption } from '@modern-js/server-runtime; export const cacheOption: CacheOption = { '/home': { @@ -147,7 +147,7 @@ Developers can implement a Redis cache container as shown below: ```ts import Redis from 'ioredis'; -import type { Container, CacheOption } from '@modern-js/runtime/server; +import type { Container, CacheOption } from '@modern-js/server-runtime; class RedisContainer implements Container { redis = new Redis(); @@ -202,4 +202,4 @@ The `x-render-cache` header can have the following values: | hit | Cache hit, returned cache content | | stale | Cache hit, but data is stale, returned cache content and re-rendered asynchronously | | expired | Cache expired, re-rendered and returned new content | -| miss | Cache missed | \ No newline at end of file +| miss | Cache missed | diff --git a/packages/document/main-doc/docs/zh/apis/app/runtime/bff/use-hono-context.mdx b/packages/document/main-doc/docs/zh/apis/app/runtime/bff/use-hono-context.mdx index d0c45886871d..155cdbf55500 100644 --- a/packages/document/main-doc/docs/zh/apis/app/runtime/bff/use-hono-context.mdx +++ b/packages/document/main-doc/docs/zh/apis/app/runtime/bff/use-hono-context.mdx @@ -9,7 +9,7 @@ title: useHonoContext ## 使用姿势 ```ts -import { useHonoContext } from '@modern-js/plugin-bff/hono'; +import { useHonoContext } from '@modern-js/plugin-bff/server'; ``` ## 函数签名 @@ -21,7 +21,7 @@ import { useHonoContext } from '@modern-js/plugin-bff/hono'; 开发者可以通过 `context` 获取更多的请求信息,例如设置响应头: ```ts -import { useHonoContext } from '@modern-js/plugin-bff/hono'; +import { useHonoContext } from '@modern-js/plugin-bff/server'; export async function get() { const c = useHonoContext(); diff --git a/packages/document/main-doc/docs/zh/configure/app/server/ssr.mdx b/packages/document/main-doc/docs/zh/configure/app/server/ssr.mdx index ece3ad1a39fc..f27952379e56 100644 --- a/packages/document/main-doc/docs/zh/configure/app/server/ssr.mdx +++ b/packages/document/main-doc/docs/zh/configure/app/server/ssr.mdx @@ -29,7 +29,6 @@ export default defineConfig({ | ---------------- | ------------------------------------------------------------- | -------------------------------------- | ---------------------------------------------------------------------------- | | mode | `string` | `string` | 默认为使用 `renderToString` 渲染。配置为 `stream` 开启流式渲染 | | forceCSR | `boolean` | `false` | 默认关闭强制 CSR 渲染。配置为 `true` 后,在页面访问时添加 `?csr=true` 或添加请求头 `x-modern-ssr-fallback` 即可强制 CSR | -| disablePrerender | `boolean` | `fasle` | 为了兼容旧数据请求方式 - `useLoader`, 默认情况下 Modern.js 会对组件进行一次预渲染即有两次渲染 | | unsafeHeaders | `string[]` | `[]` | 为了安全考虑,Modern.js 不会往 SSR_DATA 添加过多的内容。开发者可以通过该配置,对需要注入的 headers 进行配置 | | loaderFailureMode| `clientRender \| errorBoundary` | `errorBoundary` | 当 [data loader](/guides/basic-features/data/data-fetch.html#data-loader推荐) 中出错时,默认会渲染路由 [`Error`](/guides/basic-features/routes.html#错误处理) 组件,配置为 `'clientRender'` 时,有一个 data loader 抛错,就降级到客户端渲染,可以与 [Client Loader](/guides/basic-features/data/data-fetch.html#client-loader) 配合使用 | @@ -40,7 +39,6 @@ export default defineConfig({ ssr: { forceCSR: true, mode: 'stream', - disablePrerender: true, unsafeHeaders: ['User-Agent'], scriptLoading: 'async', }, diff --git a/packages/document/main-doc/docs/zh/guides/advanced-features/bff/cross-project.mdx b/packages/document/main-doc/docs/zh/guides/advanced-features/bff/cross-project.mdx index 623d7f294f6b..5169225dbf74 100644 --- a/packages/document/main-doc/docs/zh/guides/advanced-features/bff/cross-project.mdx +++ b/packages/document/main-doc/docs/zh/guides/advanced-features/bff/cross-project.mdx @@ -92,7 +92,7 @@ configure({ ```ts title="src/routes/page.tsx" import { configure } from '${package_name}/runtime'; -import { configure as innerConfigure } from '@modern-js/runtime/bff'; +import { configure as innerConfigure } from '@modern-js/plugin-bff/client'; import axios from 'axios'; configure({ diff --git a/packages/document/main-doc/docs/zh/guides/advanced-features/bff/frameworks.mdx b/packages/document/main-doc/docs/zh/guides/advanced-features/bff/frameworks.mdx index 2ec00ed868b3..611f6f977fcc 100644 --- a/packages/document/main-doc/docs/zh/guides/advanced-features/bff/frameworks.mdx +++ b/packages/document/main-doc/docs/zh/guides/advanced-features/bff/frameworks.mdx @@ -12,7 +12,7 @@ Modern.js 以 [Hono.js](https://hono.dev/) 作为 BFF 和 Server 运行时框架 在 BFF 函数中,有时需要获取请求上下文,来处理更多逻辑。此时,你可以通过 `useHonoContext` 来获取: ```ts title="api/lambda/hello.ts" -import { useHonoContext } from '@modern-js/plugin-bff/hono' +import { useHonoContext } from '@modern-js/plugin-bff/server' export const get = async () => { const c = useHonoContext(); console.info(`access url: ${c.req.url}`); diff --git a/packages/document/main-doc/docs/zh/guides/advanced-features/bff/function.mdx b/packages/document/main-doc/docs/zh/guides/advanced-features/bff/function.mdx index dedc322cdafc..ce4ff6685e0c 100644 --- a/packages/document/main-doc/docs/zh/guides/advanced-features/bff/function.mdx +++ b/packages/document/main-doc/docs/zh/guides/advanced-features/bff/function.mdx @@ -193,7 +193,7 @@ Dynamic Path 之后的参数是包含 querystring、request body 的对象 `Requ 在不存在动态路由的普通函数中,可以从第一个入参中获取传入的 `data` 和 `query`,例如: ```ts title="api/lambda/hello.ts" -import type { RequestOption } from '@modern-js/runtime/server'; +import type { RequestOption } from '@modern-js/server-runtime'; export async function post({ query, @@ -206,7 +206,7 @@ export async function post({ 这里你也可以使用自定义类型: ```ts title="api/lambda/hello.ts" -import type { RequestOption } from '@modern-js/runtime/server'; +import type { RequestOption } from '@modern-js/server-runtime'; type IQuery = { // some types diff --git a/packages/document/main-doc/docs/zh/guides/advanced-features/bff/sdk.mdx b/packages/document/main-doc/docs/zh/guides/advanced-features/bff/sdk.mdx index 3d9b3699790d..ff3ae1012705 100644 --- a/packages/document/main-doc/docs/zh/guides/advanced-features/bff/sdk.mdx +++ b/packages/document/main-doc/docs/zh/guides/advanced-features/bff/sdk.mdx @@ -15,10 +15,10 @@ BFF 函数的一体化调用在 CSR 和 SSR 是同构的。Modern.js 封装的 ```tsx title="routes/page.tsx" -import { configure } from '@modern-js/runtime/bff'; +import { configure } from '@modern-js/plugin-bff/client'; -configure({ - // ... +configure({ + // ... }) const Index = () =>
Hello world
@@ -92,7 +92,7 @@ configure({ 下面是使用 axios 定制自定义请求函数的示例: ```tsx title="App.tsx" -import { configure } from '@modern-js/runtime/bff'; +import { configure } from '@modern-js/plugin-bff/client'; import type { Method, AxiosRequestHeaders as Headers } from 'axios'; configure({ diff --git a/packages/document/main-doc/docs/zh/guides/advanced-features/web-server.mdx b/packages/document/main-doc/docs/zh/guides/advanced-features/web-server.mdx index 6a2c806916af..b8d9be97d911 100644 --- a/packages/document/main-doc/docs/zh/guides/advanced-features/web-server.mdx +++ b/packages/document/main-doc/docs/zh/guides/advanced-features/web-server.mdx @@ -267,7 +267,7 @@ Modern.js 支持为 Web Server 添加渲染中间件,支持在处理页面路 import { UnstableMiddleware, UnstableMiddlewareContext, -} from '@modern-js/runtime/server'; +} from '@modern-js/server-runtime'; const time: UnstableMiddleware = async (c: UnstableMiddlewareContext, next) => { const start = Date.now(); @@ -292,7 +292,7 @@ Modern.js 提供的 Hook 用于控制 Web Server 中的特定逻辑,所有的 import type { AfterMatchHook, AfterRenderHook, -} from '@modern-js/runtime/server'; +} from '@modern-js/server-runtime'; export const afterMatch: AfterMatchHook = (ctx, next) => { next(); diff --git a/packages/document/main-doc/docs/zh/guides/basic-features/render/ssr-cache.mdx b/packages/document/main-doc/docs/zh/guides/basic-features/render/ssr-cache.mdx index 440de9832560..e3c33407103d 100644 --- a/packages/document/main-doc/docs/zh/guides/basic-features/render/ssr-cache.mdx +++ b/packages/document/main-doc/docs/zh/guides/basic-features/render/ssr-cache.mdx @@ -17,7 +17,7 @@ Modern.js 支持将服务器端渲染(SSR)结果进行缓存,减少服务 在应用中创建 `server/cache.[t|j]s` 文件,并导出 `cacheOption` 配置缓存即可开启 SSR 渲染缓存: ```ts title="server/cache.ts" -import type { CacheOption } from '@modern-js/runtime/server'; +import type { CacheOption } from '@modern-js/server-runtime'; export const cacheOption: CacheOption = { maxAge: 500, // ms @@ -57,7 +57,7 @@ export type CacheOptionProvider = ( ```ts title="server/cache.ts" -import type { CacheOption, CacheOptionProvider } from '@modern-js/runtime/server'; +import type { CacheOption, CacheOptionProvider } from '@modern-js/server-runtime'; const provider: CacheOptionProvider = (req) => { const { url, headers, ... } = req; @@ -85,7 +85,7 @@ export type CacheOptions = Record; 有时开发者面对不同的路由需要应用不同的缓存策略。我们也提供一种映射的方式进行配置, 以下列代码为例: ```ts title="server/cache.ts" -import type { CacheOption } from '@modern-js/runtime/server'; +import type { CacheOption } from '@modern-js/server-runtime'; export const cacheOption: CacheOption = { '/home': { @@ -151,7 +151,7 @@ export interface Container { 以下面代码为例,开发者可实现一个 redis 缓存容器。 ```ts -import type { Container, CacheOption } from '@modern-js/runtime/server'; +import type { Container, CacheOption } from '@modern-js/server-runtime'; class RedisContainer implements Container { redis = new Redis(); @@ -206,4 +206,4 @@ export const cacheOption: CacheOption = { | hit | 缓存命中,返回缓存内容 | | stale | 缓存命中,但数据陈旧,返回缓存内容的同时做重新渲染 | | expired | 缓存命中,重新渲染后返回渲染结果 | -| miss | 缓存未命中 | \ No newline at end of file +| miss | 缓存未命中 | diff --git a/packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/ssr.mdx b/packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/ssr.mdx index f1d07cfe505e..70495ec29f2a 100644 --- a/packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/ssr.mdx +++ b/packages/document/main-doc/docs/zh/guides/topic-detail/module-federation/ssr.mdx @@ -13,8 +13,6 @@ export default defineConfig({ server: { ssr: { mode: 'stream', - // 禁用预渲染,优化 SSR 性能 - disablePrerender: true, }, }, }) diff --git a/packages/runtime/plugin-runtime/package.json b/packages/runtime/plugin-runtime/package.json index ae3664e9faa1..4d1983204a9a 100644 --- a/packages/runtime/plugin-runtime/package.json +++ b/packages/runtime/plugin-runtime/package.json @@ -64,12 +64,6 @@ "jsnext:source": "./src/exports/head.ts", "default": "./dist/esm/exports/head.js" }, - "./server": { - "types": "./dist/types/exports/server.d.ts", - "jsnext:source": "./src/exports/server.ts", - "node": "./dist/cjs/exports/server.js", - "default": "./dist/esm/exports/server.js" - }, "./ssr": { "types": "./dist/types/core/server/index.d.ts", "jsnext:source": "./src/core/server/index.ts", @@ -168,9 +162,6 @@ "head": [ "./dist/types/exports/head.d.ts" ], - "server": [ - "./dist/types/exports/server.d.ts" - ], "document": [ "./dist/types/document/index.d.ts" ], diff --git a/packages/runtime/plugin-runtime/src/exports/server.ts b/packages/runtime/plugin-runtime/src/exports/server.ts deleted file mode 100644 index 43bc786874c6..000000000000 --- a/packages/runtime/plugin-runtime/src/exports/server.ts +++ /dev/null @@ -1,13 +0,0 @@ -export type { - // cache - Container, - CacheControl, - CacheOptionProvider, - CacheOption, - MonitorEvent, - Monitors, - CoreMonitor, - LogEvent, - LogLevel, - TimingEvent, -} from '@modern-js/types'; diff --git a/packages/server/bff-core/src/client/generateClient.ts b/packages/server/bff-core/src/client/generateClient.ts index 9a7dd7aeedc0..70f0514647f3 100644 --- a/packages/server/bff-core/src/client/generateClient.ts +++ b/packages/server/bff-core/src/client/generateClient.ts @@ -3,6 +3,22 @@ import type { HttpMethodDecider } from '@modern-js/types'; import { ApiRouter } from '../router'; import { Err, Ok, type Result } from './result'; +/** + * Get package name from package.json file + * @param appDir - Application directory path + * @returns Package name or undefined if not found + */ +const getPackageName = (appDir: string): string | undefined => { + try { + const packageJsonPath = path.resolve(appDir, './package.json'); + const packageJson = require(packageJsonPath); + return packageJson.name; + } catch (error) { + // If package.json doesn't exist or is invalid, return undefined + return undefined; + } +}; + export type GenClientResult = Result; export type GenClientOptions = { @@ -23,8 +39,7 @@ export type GenClientOptions = { export const DEFAULT_CLIENT_REQUEST_CREATOR = '@modern-js/create-request'; -export const INNER_CLIENT_REQUEST_CREATOR = - '@modern-js/plugin-bff/runtime/create-request'; +export const INNER_CLIENT_REQUEST_CREATOR = '@modern-js/plugin-bff/client'; export const generateClient = async ({ appDir, @@ -66,7 +81,9 @@ export const generateClient = async ({ const routeName = routePath; const requestId = - target === 'bundle' ? process.env.npm_package_name : undefined; + target === 'bundle' + ? getPackageName(appDir) || process.env.npm_package_name + : undefined; if (action === 'upload') { const requestOptions = { diff --git a/packages/server/bff-core/src/router/constants.ts b/packages/server/bff-core/src/router/constants.ts index 7cd1faa9999d..2b5ec8ba619b 100644 --- a/packages/server/bff-core/src/router/constants.ts +++ b/packages/server/bff-core/src/router/constants.ts @@ -2,18 +2,6 @@ import { HttpMethod } from '../types'; export const AllHttpMethods = Object.values(HttpMethod) as string[]; -export enum APIMode { - /** - * 框架模式 - */ - FARMEWORK = 'framework', - - /** - * 函数模式 - */ - FUNCTION = 'function', -} - export const FRAMEWORK_MODE_LAMBDA_DIR = 'lambda'; export const FRAMEWORK_MODE_APP_DIR = 'app'; diff --git a/packages/server/bff-core/src/router/index.ts b/packages/server/bff-core/src/router/index.ts index 180d6fb27f1f..dc304b87527d 100644 --- a/packages/server/bff-core/src/router/index.ts +++ b/packages/server/bff-core/src/router/index.ts @@ -5,7 +5,6 @@ import type { HttpMethodDecider } from '@modern-js/types'; import { HttpMethod, OperatorType, TriggerType, httpMethods } from '../types'; import { INPUT_PARAMS_DECIDER, debug } from '../utils'; import { - APIMode, API_FILE_RULES, FRAMEWORK_MODE_APP_DIR, FRAMEWORK_MODE_LAMBDA_DIR, @@ -22,8 +21,6 @@ export * from './types'; export * from './constants'; export class ApiRouter { - private apiMode: APIMode; - private appDir?: string; private apiDir: string; @@ -64,7 +61,6 @@ export class ApiRouter { this.apiDir = apiDir; this.httpMethodDecider = httpMethodDecider; this.isBuild = isBuild; - this.apiMode = this.getExactApiMode(apiDir, lambdaDir); this.lambdaDir = this.getExactLambdaDir(this.apiDir, lambdaDir); this.existLambdaDir = fs.existsSync(this.lambdaDir); debug(`apiDir:`, this.apiDir, `lambdaDir:`, this.lambdaDir); @@ -74,10 +70,6 @@ export class ApiRouter { return this.existLambdaDir; } - public getApiMode() { - return this.apiMode; - } - public getLambdaDir() { return this.lambdaDir; } @@ -261,32 +253,10 @@ export class ApiRouter { } } - private getExactApiMode = (apiDir: string, lambdaDir?: string): APIMode => { - const exist = this.createExistChecker(apiDir); - const existLambdaDir = - (lambdaDir && fs.pathExistsSync(lambdaDir)) || - exist(FRAMEWORK_MODE_LAMBDA_DIR); - const existAppDir = exist(FRAMEWORK_MODE_APP_DIR); - const existAppFile = exist('app.ts') || exist('app.js'); - - if (existLambdaDir || existAppDir || existAppFile) { - return APIMode.FARMEWORK; - } - - return APIMode.FUNCTION; - }; - - private createExistChecker = (base: string) => (target: string) => - fs.pathExistsSync(path.resolve(base, target)); - private getExactLambdaDir = ( apiDir: string, originLambdaDir?: string, ): string => { - if (this.apiMode === APIMode.FUNCTION) { - return apiDir; - } - return originLambdaDir || path.join(apiDir, FRAMEWORK_MODE_LAMBDA_DIR); }; diff --git a/packages/server/bff-core/tests/client/__snapshots__/generateClient.test.ts.snap b/packages/server/bff-core/tests/client/__snapshots__/generateClient.test.ts.snap index 925592e3a25e..7e0793f703d0 100644 --- a/packages/server/bff-core/tests/client/__snapshots__/generateClient.test.ts.snap +++ b/packages/server/bff-core/tests/client/__snapshots__/generateClient.test.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`client generateClient should support cross croject invocation 1`] = ` -"import { createRequest } from '@modern-js/plugin-bff/runtime/create-request'; +"import { createRequest } from '@modern-js/plugin-bff/client'; export var DELETE = createRequest({path: '/normal/origin',method: 'DELETE',port: 3000,httpMethodDecider: 'functionName', requestId: 'tests'}); export default createRequest({path: '/normal/origin',method: 'GET',port: 3000,httpMethodDecider: 'functionName', requestId: 'tests'}); @@ -10,7 +10,7 @@ export var DELETE = createRequest({path: '/normal/origin',method: 'DELETE',port: `; exports[`client generateClient should support operator 1`] = ` -"import { createRequest } from '@modern-js/plugin-bff/runtime/create-request'; +"import { createRequest } from '@modern-js/plugin-bff/client'; export var DELETE = createRequest({path: '/normal/origin',method: 'DELETE',port: 3000,httpMethodDecider: 'functionName'}); export default createRequest({path: '/normal/origin',method: 'GET',port: 3000,httpMethodDecider: 'functionName'}); @@ -19,7 +19,7 @@ export var DELETE = createRequest({path: '/normal/origin',method: 'DELETE',port: `; exports[`client generateClient should works correctly 1`] = ` -"import { createRequest } from '@modern-js/plugin-bff/runtime/create-request'; +"import { createRequest } from '@modern-js/plugin-bff/client'; export var get = createRequest({path: '/api/:id/origin/foo',method: 'GET',port: 3000,httpMethodDecider: 'functionName'}); export var post = createRequest({path: '/api/:id/origin/foo',method: 'POST',port: 3000,httpMethodDecider: 'functionName'}); diff --git a/packages/server/bff-core/tests/client/generateClient.test.ts b/packages/server/bff-core/tests/client/generateClient.test.ts index ef877548fad3..226cb3f4e532 100644 --- a/packages/server/bff-core/tests/client/generateClient.test.ts +++ b/packages/server/bff-core/tests/client/generateClient.test.ts @@ -21,11 +21,12 @@ describe('client', () => { const port = 3000; const resourcePath = path.resolve( __dirname, - '../fixtures/function/[id]/origin/foo.ts', + '../fixtures/function/lambda/[id]/origin/foo.ts', ); const source = await fs.readFile(resourcePath, 'utf-8'); const result = await generateClient({ + appDir: __dirname, prefix, port, resourcePath, @@ -43,11 +44,12 @@ describe('client', () => { const port = 3000; const resourcePath = path.resolve( __dirname, - '../fixtures/function/normal/origin/index.ts', + '../fixtures/function/lambda/normal/origin/index.ts', ); const source = await fs.readFile(resourcePath, 'utf-8'); const result = await generateClient({ + appDir: __dirname, prefix, port, resourcePath, @@ -65,11 +67,12 @@ describe('client', () => { const port = 3000; const resourcePath = path.resolve( __dirname, - '../fixtures/function/normal/origin/index.ts', + '../fixtures/function/lambda/normal/origin/index.ts', ); const source = await fs.readFile(resourcePath, 'utf-8'); const result = await generateClient({ + appDir: __dirname, prefix, port, resourcePath, diff --git a/packages/server/bff-core/tests/fixtures/function/[id]/origin/bar.ts b/packages/server/bff-core/tests/fixtures/function/lambda/[id]/origin/bar.ts similarity index 100% rename from packages/server/bff-core/tests/fixtures/function/[id]/origin/bar.ts rename to packages/server/bff-core/tests/fixtures/function/lambda/[id]/origin/bar.ts diff --git a/packages/server/bff-core/tests/fixtures/function/[id]/origin/baz.ts b/packages/server/bff-core/tests/fixtures/function/lambda/[id]/origin/baz.ts similarity index 100% rename from packages/server/bff-core/tests/fixtures/function/[id]/origin/baz.ts rename to packages/server/bff-core/tests/fixtures/function/lambda/[id]/origin/baz.ts diff --git a/packages/server/bff-core/tests/fixtures/function/[id]/origin/foo.ts b/packages/server/bff-core/tests/fixtures/function/lambda/[id]/origin/foo.ts similarity index 100% rename from packages/server/bff-core/tests/fixtures/function/[id]/origin/foo.ts rename to packages/server/bff-core/tests/fixtures/function/lambda/[id]/origin/foo.ts diff --git a/packages/server/bff-core/tests/fixtures/function/normal/origin/bar.ts b/packages/server/bff-core/tests/fixtures/function/lambda/normal/origin/bar.ts similarity index 100% rename from packages/server/bff-core/tests/fixtures/function/normal/origin/bar.ts rename to packages/server/bff-core/tests/fixtures/function/lambda/normal/origin/bar.ts diff --git a/packages/server/bff-core/tests/fixtures/function/normal/origin/baz.ts b/packages/server/bff-core/tests/fixtures/function/lambda/normal/origin/baz.ts similarity index 100% rename from packages/server/bff-core/tests/fixtures/function/normal/origin/baz.ts rename to packages/server/bff-core/tests/fixtures/function/lambda/normal/origin/baz.ts diff --git a/packages/server/bff-core/tests/fixtures/function/normal/origin/foo.ts b/packages/server/bff-core/tests/fixtures/function/lambda/normal/origin/foo.ts similarity index 100% rename from packages/server/bff-core/tests/fixtures/function/normal/origin/foo.ts rename to packages/server/bff-core/tests/fixtures/function/lambda/normal/origin/foo.ts diff --git a/packages/server/bff-core/tests/fixtures/function/normal/origin/index.ts b/packages/server/bff-core/tests/fixtures/function/lambda/normal/origin/index.ts similarity index 86% rename from packages/server/bff-core/tests/fixtures/function/normal/origin/index.ts rename to packages/server/bff-core/tests/fixtures/function/lambda/normal/origin/index.ts index a59d0fa79296..5425b00a1c90 100644 --- a/packages/server/bff-core/tests/fixtures/function/normal/origin/index.ts +++ b/packages/server/bff-core/tests/fixtures/function/lambda/normal/origin/index.ts @@ -1,4 +1,4 @@ -import { Api, Put } from '../../../../../src'; +import { Api, Put } from '../../../../../../src'; const getOrigin = ({ query: { id } }: { query: { id: string } }) => ({ id }); diff --git a/packages/server/bff-core/tests/router.test.ts b/packages/server/bff-core/tests/router.test.ts index 03ec715a227f..e5fdf3e4856e 100644 --- a/packages/server/bff-core/tests/router.test.ts +++ b/packages/server/bff-core/tests/router.test.ts @@ -33,17 +33,18 @@ describe('test getPathFromFilename', () => { }); describe('test api router', () => { - const mockApiDir = '/api'; + const mockApiDir = path.join(__dirname, 'fixtures', 'function'); let apiRouter: ApiRouter; beforeAll(() => { apiRouter = new ApiRouter({ apiDir: mockApiDir, + lambdaDir: path.join(mockApiDir, 'lambda'), prefix: '/', }); }); test('support get http method from function name', () => { - const mockFileName = '/api/repo.ts'; + const mockFileName = path.join(mockApiDir, 'lambda', 'repo.ts'); const mockFuncName = 'del'; const del = () => {}; @@ -92,9 +93,10 @@ describe('test api router', () => { test('getSingleModuleHandlers', async () => { const apiDir = path.join(__dirname, 'fixtures', 'function'); - const apiFile = path.join(apiDir, 'normal/origin/index'); + const apiFile = path.join(apiDir, 'lambda/normal/origin/index'); const apiRouter = new ApiRouter({ apiDir, + lambdaDir: path.join(apiDir, 'lambda'), prefix: '/', }); const handlerInfos = await apiRouter.getSingleModuleHandlers(apiFile); @@ -107,6 +109,7 @@ describe('test api router', () => { const apiDir = path.join(__dirname, 'fixtures', 'function'); const apiRouter = new ApiRouter({ apiDir, + lambdaDir: path.join(apiDir, 'lambda'), prefix: '/', }); const filenames = apiRouter.getApiFiles(); @@ -130,10 +133,12 @@ describe('test api router', () => { const get = () => 'Hello Modernjs'; const apiRouter1 = new ApiRouter({ apiDir, + lambdaDir: path.join(apiDir, 'lambda'), prefix: '', }); + const handlerInfo1 = apiRouter1.getHandlerInfo( - path.join(apiDir, 'normal/origin/index.ts'), + path.join(apiDir, 'lambda/normal/origin/index.ts'), 'get', get, ); @@ -141,10 +146,11 @@ describe('test api router', () => { const apiRouter2 = new ApiRouter({ apiDir, + lambdaDir: path.join(apiDir, 'lambda'), prefix: '/', }); const handlerInfo2 = apiRouter2.getHandlerInfo( - path.join(apiDir, 'normal/origin/index.ts'), + path.join(apiDir, 'lambda/normal/origin/index.ts'), 'get', get, ); @@ -155,7 +161,7 @@ describe('test api router', () => { prefix: '', }); const handlerInfo3 = apiRouter3.getHandlerInfo( - path.join(apiDir, 'index.ts'), + path.join(apiDir, 'lambda/index.ts'), 'get', get, ); @@ -163,10 +169,11 @@ describe('test api router', () => { const apiRouter4 = new ApiRouter({ apiDir, + lambdaDir: path.join(apiDir, 'lambda'), prefix: '/', }); const handlerInfo4 = apiRouter4.getHandlerInfo( - path.join(apiDir, 'index.ts'), + path.join(apiDir, 'lambda/index.ts'), 'get', get, ); @@ -176,7 +183,7 @@ describe('test api router', () => { test('getSafeRoutePath should throw error when file is not a api file', () => { const apiRouter = new ApiRouter({ apiDir: PWD, - lambdaDir: PWD, + lambdaDir: path.join(PWD, 'lambda'), prefix: '/', }); const resourcePath = path.resolve( @@ -192,7 +199,7 @@ describe('test api router', () => { const resourcePath = './fixtures/function/_fail.ts'; const apiRouter = new ApiRouter({ apiDir: PWD, - lambdaDir: PWD, + lambdaDir: path.join(PWD, 'lambda'), prefix: '/', }); expect(() => apiRouter.getSafeRoutePath(resourcePath)).toThrow( diff --git a/packages/server/core/src/types/config/server.ts b/packages/server/core/src/types/config/server.ts index 7c0b41e2b3ae..14bd3cc3832b 100644 --- a/packages/server/core/src/types/config/server.ts +++ b/packages/server/core/src/types/config/server.ts @@ -17,7 +17,6 @@ export type SSR = forceCSR?: boolean; mode?: SSRMode; inlineScript?: boolean; - disablePrerender?: boolean; unsafeHeaders?: string[]; loaderFailureMode?: 'clientRender' | 'errorBoundary'; }; diff --git a/packages/server/server-runtime/package.json b/packages/server/server-runtime/package.json index 4530d8b46128..c3f336898ad3 100644 --- a/packages/server/server-runtime/package.json +++ b/packages/server/server-runtime/package.json @@ -59,6 +59,7 @@ "dependencies": { "@modern-js/runtime-utils": "workspace:*", "@modern-js/server-core": "workspace:*", + "@modern-js/types": "workspace:*", "@swc/helpers": "^0.5.17" }, "devDependencies": { diff --git a/packages/server/server-runtime/src/index.ts b/packages/server/server-runtime/src/index.ts index 60b0b16de62f..f704ed4cbf2c 100644 --- a/packages/server/server-runtime/src/index.ts +++ b/packages/server/server-runtime/src/index.ts @@ -10,5 +10,14 @@ export { type ServerConfig, } from '@modern-js/server-core'; +export type { + Container, + CacheControl, + CacheOptionProvider, + CacheOption, + MonitorEvent, + Monitors, +} from '@modern-js/types'; + export const defineServerConfig = (config: ServerConfig): ServerConfig => config; diff --git a/packages/server/utils/tests/ts.test.ts b/packages/server/utils/tests/ts.test.ts index 1f342cde0168..058633c09d1d 100644 --- a/packages/server/utils/tests/ts.test.ts +++ b/packages/server/utils/tests/ts.test.ts @@ -3,7 +3,7 @@ import { fs } from '@modern-js/utils'; import { compile } from '../src'; describe('typescript', () => { - it.skip('compile typescript', async () => { + it('compile typescript', async () => { const example = path.join(__dirname, './fixtures', './ts-example'); const tsconfigPath = path.join(example, './tsconfig.json'); const distDir = path.join(example, './dist'); diff --git a/packages/solutions/app-tools/src/commands/build.ts b/packages/solutions/app-tools/src/commands/build.ts index a0bf35c6fa2e..a4fbd41922f9 100644 --- a/packages/solutions/app-tools/src/commands/build.ts +++ b/packages/solutions/app-tools/src/commands/build.ts @@ -70,7 +70,7 @@ export const build = async ( await registerEsm({ appDir: appContext.appDirectory, distDir: appContext.distDirectory, - alias: combinedAlias, + alias: {}, }); } diff --git a/packages/solutions/app-tools/src/commands/dev.ts b/packages/solutions/app-tools/src/commands/dev.ts index bf9596d667f7..2badf3afeabf 100644 --- a/packages/solutions/app-tools/src/commands/dev.ts +++ b/packages/solutions/app-tools/src/commands/dev.ts @@ -49,7 +49,7 @@ export const dev = async ( await registerEsm({ appDir: appContext.appDirectory, distDir: appContext.distDirectory, - alias: combinedAlias, + alias: {}, }); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 158981cf495d..a168eeaeb0c7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1881,6 +1881,9 @@ importers: '@modern-js/server-core': specifier: workspace:* version: link:../core + '@modern-js/types': + specifier: workspace:* + version: link:../../toolkit/types '@swc/helpers': specifier: ^0.5.17 version: 0.5.17 @@ -4439,6 +4442,9 @@ importers: '@modern-js/runtime': specifier: workspace:* version: link:../../../packages/runtime/plugin-runtime + '@modern-js/server-runtime': + specifier: workspace:* + version: link:../../../packages/server/server-runtime react: specifier: ^19.1.1 version: 19.1.1 @@ -4676,6 +4682,9 @@ importers: '@modern-js/runtime': specifier: workspace:* version: link:../../../../../packages/runtime/plugin-runtime + '@modern-js/server-runtime': + specifier: workspace:* + version: link:../../../../../packages/server/server-runtime react: specifier: ^19.1.1 version: 19.1.1 diff --git a/tests/integration/bff-corss-project/bff-indep-client-app/src/base/App.tsx b/tests/integration/bff-corss-project/bff-indep-client-app/src/base/App.tsx index 693f745a9b70..78017b5fdd8d 100644 --- a/tests/integration/bff-corss-project/bff-indep-client-app/src/base/App.tsx +++ b/tests/integration/bff-corss-project/bff-indep-client-app/src/base/App.tsx @@ -1,5 +1,5 @@ import innerHello from '@api/index'; -import { configure as innerConfigure } from '@modern-js/runtime/bff'; +import { configure as innerConfigure } from '@modern-js/plugin-bff/client'; import type { AxiosRequestHeaders as Headers, Method } from 'axios'; import axios from 'axios'; import context from 'bff-api-app/api/context/index'; diff --git a/tests/integration/bff-hono/api/context/index.ts b/tests/integration/bff-hono/api/lambda/context/index.ts similarity index 72% rename from tests/integration/bff-hono/api/context/index.ts rename to tests/integration/bff-hono/api/lambda/context/index.ts index d67fb6fc00ee..e3c471c9e888 100644 --- a/tests/integration/bff-hono/api/context/index.ts +++ b/tests/integration/bff-hono/api/lambda/context/index.ts @@ -1,4 +1,4 @@ -import { useHonoContext } from '@modern-js/plugin-bff/hono'; +import { useHonoContext } from '@modern-js/plugin-bff/server'; export default async () => { const ctx = useHonoContext(); diff --git a/tests/integration/bff-hono/api/error/index.ts b/tests/integration/bff-hono/api/lambda/error/index.ts similarity index 82% rename from tests/integration/bff-hono/api/error/index.ts rename to tests/integration/bff-hono/api/lambda/error/index.ts index 2fb6752c1eae..52f8fccbf53a 100644 --- a/tests/integration/bff-hono/api/error/index.ts +++ b/tests/integration/bff-hono/api/lambda/error/index.ts @@ -1,4 +1,4 @@ -import { Api, Get } from '@modern-js/plugin-bff/hono'; +import { Api, Get } from '@modern-js/plugin-bff/server'; import { HTTPException } from 'hono/http-exception'; export default async () => { diff --git a/tests/integration/bff-hono/api/error/managed.ts b/tests/integration/bff-hono/api/lambda/error/managed.ts similarity index 83% rename from tests/integration/bff-hono/api/error/managed.ts rename to tests/integration/bff-hono/api/lambda/error/managed.ts index 85ac20163143..69111bfd8743 100644 --- a/tests/integration/bff-hono/api/error/managed.ts +++ b/tests/integration/bff-hono/api/lambda/error/managed.ts @@ -1,4 +1,4 @@ -import { Api, Get } from '@modern-js/plugin-bff/hono'; +import { Api, Get } from '@modern-js/plugin-bff/server'; import { HTTPException } from 'hono/http-exception'; export default async () => { diff --git a/tests/integration/bff-hono/api/index.ts b/tests/integration/bff-hono/api/lambda/index.ts similarity index 98% rename from tests/integration/bff-hono/api/index.ts rename to tests/integration/bff-hono/api/lambda/index.ts index aa2052b52241..07ce93be44a5 100644 --- a/tests/integration/bff-hono/api/index.ts +++ b/tests/integration/bff-hono/api/lambda/index.ts @@ -9,8 +9,9 @@ import { Post, Query, useHonoContext, -} from '@modern-js/plugin-bff/hono'; +} from '@modern-js/plugin-bff/server'; import { z } from 'zod'; + export default async () => { return { message: 'Hello Modern.js', diff --git a/tests/integration/bff-hono/api/upload.ts b/tests/integration/bff-hono/api/lambda/upload.ts similarity index 84% rename from tests/integration/bff-hono/api/upload.ts rename to tests/integration/bff-hono/api/lambda/upload.ts index a963f17a8ced..09d79057af5f 100644 --- a/tests/integration/bff-hono/api/upload.ts +++ b/tests/integration/bff-hono/api/lambda/upload.ts @@ -1,4 +1,4 @@ -import { Api, Upload } from '@modern-js/plugin-bff/hono'; +import { Api, Upload } from '@modern-js/plugin-bff/server'; import { z } from 'zod'; const FileSchema = z.object({ diff --git a/tests/integration/bff-hono/src/routes/base/page.tsx b/tests/integration/bff-hono/src/routes/base/page.tsx index 2ce8c15e016b..67e95ccf84c1 100644 --- a/tests/integration/bff-hono/src/routes/base/page.tsx +++ b/tests/integration/bff-hono/src/routes/base/page.tsx @@ -1,4 +1,4 @@ -import hello, { post, postHello, getHello, getImage } from '@api/index'; +import hello, { post, postHello, getHello, getImage } from '@api/lambda/index'; import { useEffect, useState } from 'react'; const Page = () => { diff --git a/tests/integration/bff-hono/src/routes/custom-sdk/page.tsx b/tests/integration/bff-hono/src/routes/custom-sdk/page.tsx index b687fc13ac34..08fd90035eab 100644 --- a/tests/integration/bff-hono/src/routes/custom-sdk/page.tsx +++ b/tests/integration/bff-hono/src/routes/custom-sdk/page.tsx @@ -1,5 +1,5 @@ -import hello from '@api/index'; -import { configure } from '@modern-js/runtime/bff'; +import hello from '@api/lambda/index'; +import { configure } from '@modern-js/plugin-bff/client'; import { useEffect, useState } from 'react'; configure({ diff --git a/tests/integration/bff-hono/src/routes/error/page.tsx b/tests/integration/bff-hono/src/routes/error/page.tsx index 26d947d8b462..87b50519d2d8 100644 --- a/tests/integration/bff-hono/src/routes/error/page.tsx +++ b/tests/integration/bff-hono/src/routes/error/page.tsx @@ -1,5 +1,5 @@ -import get, { exception } from '@api/error/index'; -import getManaged, { exceptionManaged } from '@api/error/managed'; +import get, { exception } from '@api/lambda/error/index'; +import getManaged, { exceptionManaged } from '@api/lambda/error/managed'; import { useEffect, useState } from 'react'; diff --git a/tests/integration/bff-hono/src/routes/page.loader.ts b/tests/integration/bff-hono/src/routes/page.loader.ts index 059b25c43d84..10f368d8b2a3 100644 --- a/tests/integration/bff-hono/src/routes/page.loader.ts +++ b/tests/integration/bff-hono/src/routes/page.loader.ts @@ -1,4 +1,4 @@ -import { useHonoContext } from '@modern-js/plugin-bff/hono'; +import { useHonoContext } from '@modern-js/plugin-bff/server'; import { defer } from '@modern-js/runtime/router'; interface Ctx { diff --git a/tests/integration/bff-hono/src/routes/ssr/page.data.ts b/tests/integration/bff-hono/src/routes/ssr/page.data.ts index 4eb17c27fc8c..02a35ec3a25f 100644 --- a/tests/integration/bff-hono/src/routes/ssr/page.data.ts +++ b/tests/integration/bff-hono/src/routes/ssr/page.data.ts @@ -1,4 +1,4 @@ -import hello from '@api/index'; +import hello from '@api/lambda/index'; export type ProfileData = { message: string; diff --git a/tests/integration/bff-hono/src/routes/upload/page.tsx b/tests/integration/bff-hono/src/routes/upload/page.tsx index ef49b7e322aa..b921c96464e4 100644 --- a/tests/integration/bff-hono/src/routes/upload/page.tsx +++ b/tests/integration/bff-hono/src/routes/upload/page.tsx @@ -1,4 +1,4 @@ -import { upload } from '@api/upload'; +import { upload } from '@api/lambda/upload'; import React, { useEffect } from 'react'; const getMockImage = () => { diff --git a/tests/integration/deploy-server/api/lambda/context/index.ts b/tests/integration/deploy-server/api/lambda/context/index.ts index 6abbc235fa36..e3c471c9e888 100644 --- a/tests/integration/deploy-server/api/lambda/context/index.ts +++ b/tests/integration/deploy-server/api/lambda/context/index.ts @@ -1,9 +1,9 @@ -import { useContext } from '@modern-js/runtime/server'; +import { useHonoContext } from '@modern-js/plugin-bff/server'; export default async () => { - const ctx = useContext(); + const ctx = useHonoContext(); const { res } = ctx; - res.setHeader('x-id', '1'); + res.headers.set('x-id', '1'); return { message: 'Hello Modern.js', }; diff --git a/tests/integration/deploy-server/api/lambda/index.ts b/tests/integration/deploy-server/api/lambda/index.ts index 23e4fcd5b744..7179fb596b1d 100644 --- a/tests/integration/deploy-server/api/lambda/index.ts +++ b/tests/integration/deploy-server/api/lambda/index.ts @@ -1,51 +1,8 @@ -import { - Api, - Data, - Headers, - Params, - Post, - Query, - useContext, -} from '@modern-js/runtime/server'; -import { z } from 'zod'; - -export default async () => ({ - message: 'Hello Modern.js', -}); - -export const post = async () => ({ - message: 'Hello Modern.js', -}); - -const QuerySchema = z.object({ - user: z.string().email(), -}); - -const DataSchema = z.object({ - message: z.string(), -}); - -const ParamsSchema = z.object({ - id: z.string(), -}); - -const HeadersSchema = z.object({ - 'x-header': z.string(), -}); - -export const postHello = Api( - Post('/hello/:id'), - Params(ParamsSchema), - Query(QuerySchema), - Data(DataSchema), - Headers(HeadersSchema), - async ({ query, data, params, headers }) => { - const ctx = useContext(); - return { - params, - query, - data, - headers, - }; - }, -); +import { useHonoContext } from '@modern-js/plugin-bff/server'; + +export const post = async () => { + const ctx = useHonoContext(); + return { + message: 'Hello Modern.js', + }; +}; diff --git a/tests/integration/pure-esm-project/api/info.js b/tests/integration/pure-esm-project/api/info.js index 2ea884e70b31..fed6486710aa 100644 --- a/tests/integration/pure-esm-project/api/info.js +++ b/tests/integration/pure-esm-project/api/info.js @@ -1,4 +1,4 @@ -import { useHonoContext } from '@modern-js/plugin-bff/hono'; +import { useHonoContext } from '@modern-js/plugin-bff/server'; import { add } from 'lodash-es'; export const get = () => { diff --git a/tests/integration/pure-esm-project/src/routes/page.data.js b/tests/integration/pure-esm-project/src/routes/page.data.js index 29ce67743a67..05efc1480e44 100644 --- a/tests/integration/pure-esm-project/src/routes/page.data.js +++ b/tests/integration/pure-esm-project/src/routes/page.data.js @@ -1,4 +1,4 @@ -import { useHonoContext } from '@modern-js/plugin-bff/hono'; +import { useHonoContext } from '@modern-js/plugin-bff/server'; import { defer } from '@modern-js/runtime/router'; export const loader = () => { diff --git a/tests/integration/routes/modern.config.ts b/tests/integration/routes/modern.config.ts index 3984aa9abae2..7c389a035c17 100644 --- a/tests/integration/routes/modern.config.ts +++ b/tests/integration/routes/modern.config.ts @@ -22,7 +22,6 @@ export default defineConfig({ two: false, three: { mode: 'stream', - disablePrerender: true, loaderFailureMode: 'clientRender', }, four: false, diff --git a/tests/integration/rsc-csr-routes/src/component/routes/layout.tsx b/tests/integration/rsc-csr-routes/src/component/routes/layout.tsx index 973b22a1c895..2904653f2b10 100644 --- a/tests/integration/rsc-csr-routes/src/component/routes/layout.tsx +++ b/tests/integration/rsc-csr-routes/src/component/routes/layout.tsx @@ -1,6 +1,9 @@ import 'server-only'; +import { getRequest } from '@modern-js/runtime'; import { Link, Outlet } from '@modern-js/runtime/router'; + export default function Layout() { + const request = getRequest(); return (
root layout @@ -10,6 +13,7 @@ export default function Layout() { user +
{request.url}
); diff --git a/tests/integration/rsc-csr-routes/tests/index.test.ts b/tests/integration/rsc-csr-routes/tests/index.test.ts index e845bcdc09a5..32efe1ae6f09 100644 --- a/tests/integration/rsc-csr-routes/tests/index.test.ts +++ b/tests/integration/rsc-csr-routes/tests/index.test.ts @@ -238,6 +238,9 @@ async function shouldRenderWithFetchCorrectly({ const message = await page.$eval('.message', el => el.textContent); expect(message).toBe('root page from server'); + const requestUrl = await page.$eval('.request-url', el => el.textContent); + expect(requestUrl?.length).toBeGreaterThan(0); + await page.click('.user-link'); await page.waitForSelector('.user-data', { timeout: 5000 }); const userData = await page.$eval('.user-data', el => el.textContent); diff --git a/tests/integration/rsc-ssr-routes/src/component/routes/layout.tsx b/tests/integration/rsc-ssr-routes/src/component/routes/layout.tsx index 973b22a1c895..2904653f2b10 100644 --- a/tests/integration/rsc-ssr-routes/src/component/routes/layout.tsx +++ b/tests/integration/rsc-ssr-routes/src/component/routes/layout.tsx @@ -1,6 +1,9 @@ import 'server-only'; +import { getRequest } from '@modern-js/runtime'; import { Link, Outlet } from '@modern-js/runtime/router'; + export default function Layout() { + const request = getRequest(); return (
root layout @@ -10,6 +13,7 @@ export default function Layout() { user +
{request.url}
); diff --git a/tests/integration/rsc-ssr-routes/tests/index.test.ts b/tests/integration/rsc-ssr-routes/tests/index.test.ts index 2b705ce5e4ac..57913ee6a12c 100644 --- a/tests/integration/rsc-ssr-routes/tests/index.test.ts +++ b/tests/integration/rsc-ssr-routes/tests/index.test.ts @@ -260,6 +260,9 @@ async function shouldRenderWithFetchCorrectly({ const message = await page.$eval('.message', el => el.textContent); expect(message).toBe('root page from server'); + const requestUrl = await page.$eval('.request-url', el => el.textContent); + expect(requestUrl?.length).toBeGreaterThan(0); + await page.click('.user-link'); await page.waitForSelector('.user-data', { timeout: 5000 }); const userData = await page.$eval('.user-data', el => el.textContent); diff --git a/tests/integration/server-monitors/modern.config.ts b/tests/integration/server-monitors/modern.config.ts index 6b430d7534fa..eba599dbd4f1 100644 --- a/tests/integration/server-monitors/modern.config.ts +++ b/tests/integration/server-monitors/modern.config.ts @@ -2,9 +2,7 @@ import { applyBaseConfig } from '../../utils/applyBaseConfig'; export default applyBaseConfig({ server: { - ssr: { - disablePrerender: true, - }, + ssr: true, }, runtime: { router: true, diff --git a/tests/integration/server-monitors/package.json b/tests/integration/server-monitors/package.json index 9aa4d46ecae0..a743e983c9f6 100644 --- a/tests/integration/server-monitors/package.json +++ b/tests/integration/server-monitors/package.json @@ -13,6 +13,7 @@ }, "dependencies": { "@modern-js/runtime": "workspace:*", + "@modern-js/server-runtime": "workspace:*", "react": "^19.1.1", "react-dom": "^19.1.1" }, diff --git a/tests/integration/server-monitors/server/index.ts b/tests/integration/server-monitors/server/index.ts index ba086bca8ad5..9ac96b660371 100644 --- a/tests/integration/server-monitors/server/index.ts +++ b/tests/integration/server-monitors/server/index.ts @@ -1,29 +1,41 @@ -import type { Middleware } from '@modern-js/runtime/server'; +import { + type MiddlewareHandler, + defineServerConfig, +} from '@modern-js/server-runtime'; -export const middleware: Middleware[] = [ - (ctx, next) => { - const { res } = ctx.source; - res.setHeader('x-index-middleware', 'true'); - next(); - }, +const headerMiddleware: MiddlewareHandler = async (c, next) => { + c.header('x-index-middleware', 'true'); + await next(); +}; - (ctx, next) => { - const { response, request } = ctx; - if (request.url.startsWith('/home')) { - response.set('x-index-name', 'home'); - } +const homeMiddleware: MiddlewareHandler = async (c, next) => { + if (c.req.url.startsWith('/home')) { + c.header('x-index-name', 'home'); + } + await next(); +}; - next(); - }, +const redirectMiddleware: MiddlewareHandler = async (c, next) => { + if (c.req.url.startsWith('/redirect')) { + c.header('Location', '/'); + c.status(302); + } + await next(); +}; - (ctx, next) => { - const { response, request } = ctx; - - if (request.url.startsWith('/redirect')) { - response.set('Location', '/'); - response.status(302); - } - - next(); - }, -]; +export default defineServerConfig({ + middlewares: [ + { + name: 'header-middleware', + handler: headerMiddleware, + }, + { + name: 'home-middleware', + handler: homeMiddleware, + }, + { + name: 'redirect-middleware', + handler: redirectMiddleware, + }, + ], +}); diff --git a/tests/integration/ssr/fixtures/base-async-entry/modern.config.ts b/tests/integration/ssr/fixtures/base-async-entry/modern.config.ts index 3c83f22b14b7..4f3739aa5803 100644 --- a/tests/integration/ssr/fixtures/base-async-entry/modern.config.ts +++ b/tests/integration/ssr/fixtures/base-async-entry/modern.config.ts @@ -5,9 +5,7 @@ export default applyBaseConfig({ router: true, }, server: { - ssr: { - disablePrerender: true, - }, + ssr: true, }, source: { enableAsyncEntry: true, diff --git a/tests/integration/ssr/fixtures/base/modern.config.ts b/tests/integration/ssr/fixtures/base/modern.config.ts index 2c7422eff7cf..4c152353dd63 100644 --- a/tests/integration/ssr/fixtures/base/modern.config.ts +++ b/tests/integration/ssr/fixtures/base/modern.config.ts @@ -6,7 +6,6 @@ export default applyBaseConfig({ }, server: { ssr: { - disablePrerender: true, unsafeHeaders: ['Host'], }, }, diff --git a/tests/integration/ssr/fixtures/base/package.json b/tests/integration/ssr/fixtures/base/package.json index 1bc2d7e9f187..63ae9affa21a 100644 --- a/tests/integration/ssr/fixtures/base/package.json +++ b/tests/integration/ssr/fixtures/base/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@modern-js/runtime": "workspace:*", + "@modern-js/server-runtime": "workspace:*", "react": "^19.1.1", "react-dom": "^19.1.1" }, diff --git a/tests/integration/ssr/fixtures/base/server/cache.ts b/tests/integration/ssr/fixtures/base/server/cache.ts index 8422af2e00a2..2e4d82370a3a 100644 --- a/tests/integration/ssr/fixtures/base/server/cache.ts +++ b/tests/integration/ssr/fixtures/base/server/cache.ts @@ -1,4 +1,4 @@ -import type { CacheOption, Container } from '@modern-js/runtime/server'; +import type { CacheOption, Container } from '@modern-js/server-runtime'; class MyContainer implements Container { map: Map = new Map();