@bleedingdev/modern-js-app-tools 3.9.0-ultramodern.2 → 3.9.0-ultramodern.20
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/builder/generator/createCopyPattern.js +2 -1
- package/dist/cjs/builder/generator/index.js +0 -1
- package/dist/cjs/builder/shared/builderPlugins/adapterHtml.js +2 -1
- package/dist/cjs/builder/shared/builderPlugins/index.js +4 -11
- package/dist/cjs/builder/shared/lazyCompilation.js +26 -0
- package/dist/cjs/commands/index.js +6 -2
- package/dist/cjs/compat/hooks.js +1 -1
- package/dist/cjs/config/index.js +4 -11
- package/dist/cjs/index.js +70 -87
- package/dist/cjs/plugins/analyze/getFileSystemEntry.js +1 -1
- package/dist/cjs/plugins/analyze/getServerRoutes.js +1 -1
- package/dist/cjs/plugins/analyze/utils.js +2 -2
- package/dist/cjs/plugins/deploy/index.js +7 -28
- package/dist/cjs/plugins/deploy/platforms/netlify.js +2 -1
- package/dist/cjs/plugins/deploy/platforms/node.js +12 -16
- package/dist/cjs/plugins/deploy/platforms/vercel.js +2 -1
- package/dist/cjs/plugins/deploy/utils/generator.js +1 -1
- package/dist/cjs/plugins/deploy/utils/index.js +15 -12
- package/dist/cjs/plugins/initialize/index.js +3 -1
- package/dist/cjs/plugins/serverBuild.js +2 -3
- package/dist/cjs/{plugins/backendFederationBuild.js → server-plugin.js} +4 -7
- package/dist/cjs/utils/loadPlugins.js +1 -6
- package/dist/esm/builder/generator/createCopyPattern.mjs +2 -1
- package/dist/esm/builder/generator/index.mjs +1 -2
- package/dist/esm/builder/shared/builderPlugins/adapterHtml.mjs +2 -1
- package/dist/esm/builder/shared/builderPlugins/index.mjs +0 -1
- package/dist/esm/builder/shared/lazyCompilation.mjs +14 -1
- package/dist/esm/commands/index.mjs +6 -2
- package/dist/esm/compat/hooks.mjs +1 -1
- package/dist/esm/config/index.mjs +0 -1
- package/dist/esm/index.mjs +9 -6
- package/dist/esm/plugins/analyze/getFileSystemEntry.mjs +1 -1
- package/dist/esm/plugins/analyze/getServerRoutes.mjs +1 -1
- package/dist/esm/plugins/analyze/utils.mjs +2 -2
- package/dist/esm/plugins/deploy/index.mjs +5 -21
- package/dist/esm/plugins/deploy/platforms/netlify.mjs +2 -1
- package/dist/esm/plugins/deploy/platforms/node.mjs +12 -16
- package/dist/esm/plugins/deploy/platforms/vercel.mjs +2 -1
- package/dist/esm/plugins/deploy/utils/generator.mjs +1 -1
- package/dist/esm/plugins/deploy/utils/index.mjs +17 -14
- package/dist/esm/plugins/initialize/index.mjs +3 -1
- package/dist/esm/plugins/serverBuild.mjs +2 -3
- package/dist/esm/server-plugin.mjs +1 -0
- package/dist/esm/utils/loadPlugins.mjs +2 -7
- package/dist/esm-node/builder/generator/createCopyPattern.mjs +2 -1
- package/dist/esm-node/builder/generator/index.mjs +1 -2
- package/dist/esm-node/builder/shared/builderPlugins/adapterHtml.mjs +2 -1
- package/dist/esm-node/builder/shared/builderPlugins/index.mjs +0 -1
- package/dist/esm-node/builder/shared/lazyCompilation.mjs +14 -1
- package/dist/esm-node/commands/index.mjs +6 -2
- package/dist/esm-node/compat/hooks.mjs +1 -1
- package/dist/esm-node/config/index.mjs +0 -1
- package/dist/esm-node/index.mjs +9 -6
- package/dist/esm-node/plugins/analyze/getFileSystemEntry.mjs +1 -1
- package/dist/esm-node/plugins/analyze/getServerRoutes.mjs +1 -1
- package/dist/esm-node/plugins/analyze/utils.mjs +2 -2
- package/dist/esm-node/plugins/deploy/index.mjs +5 -21
- package/dist/esm-node/plugins/deploy/platforms/netlify.mjs +2 -1
- package/dist/esm-node/plugins/deploy/platforms/node.mjs +12 -16
- package/dist/esm-node/plugins/deploy/platforms/vercel.mjs +2 -1
- package/dist/esm-node/plugins/deploy/utils/generator.mjs +1 -1
- package/dist/esm-node/plugins/deploy/utils/index.mjs +17 -15
- package/dist/esm-node/plugins/initialize/index.mjs +3 -1
- package/dist/esm-node/plugins/serverBuild.mjs +2 -3
- package/dist/esm-node/server-plugin.mjs +2 -0
- package/dist/esm-node/utils/loadPlugins.mjs +2 -7
- package/dist/types/builder/shared/builderPlugins/index.d.ts +0 -1
- package/dist/types/builder/shared/lazyCompilation.d.ts +15 -0
- package/dist/types/config/index.d.ts +0 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/plugins/deploy/index.d.ts +1 -4
- package/dist/types/plugins/deploy/utils/generator.d.ts +1 -1
- package/dist/types/plugins/deploy/utils/index.d.ts +1 -1
- package/dist/types/server-plugin.d.ts +10 -0
- package/dist/types/types/config/output.d.ts +0 -9
- package/dist/types/types/index.d.ts +1 -1
- package/dist/types/types/plugin.d.ts +58 -2
- package/dist/types/utils/initAppContext.d.ts +3 -2
- package/docs/apis/app/commands.md +1 -0
- package/docs/configure/app/bff/effect.md +34 -36
- package/docs/configure/app/source/react-compiler.md +2 -0
- package/docs/guides/advanced-features/bff/data-platform.md +2 -2
- package/docs/guides/advanced-features/bff/frameworks.md +36 -24
- package/docs/guides/advanced-features/bff/function.md +2 -2
- package/docs/guides/advanced-features/bff/operators.md +17 -17
- package/docs/guides/basic-features/render/ssr-cache.md +14 -1
- package/docs/guides/get-started/quick-start.md +2 -6
- package/docs/guides/get-started/ultramodern.md +14 -97
- package/docs/llms.txt +3 -3
- package/docs/plugin/server-plugins/api.md +1 -0
- package/package.json +38 -36
- package/dist/cjs/builder/shared/builderPlugins/adapterPrecompress.js +0 -125
- package/dist/cjs/config/build-environment.js +0 -268
- package/dist/cjs/config/public.js +0 -46
- package/dist/cjs/plugins/backend-federation/codegen.js +0 -256
- package/dist/cjs/plugins/backend-federation/config.js +0 -204
- package/dist/cjs/plugins/backend-federation/emit.js +0 -150
- package/dist/cjs/plugins/deploy/platforms/cloudflare-output-verifier/index.js +0 -62
- package/dist/cjs/plugins/deploy/utils/npmAliases.js +0 -226
- package/dist/cjs/plugins/ultramodernReleaseEnvelope.js +0 -44
- package/dist/cjs/presetUltramodern.js +0 -168
- package/dist/cjs/types/config/precompress.js +0 -18
- package/dist/esm/builder/shared/builderPlugins/adapterPrecompress.mjs +0 -77
- package/dist/esm/config/build-environment.mjs +0 -224
- package/dist/esm/config/public.mjs +0 -1
- package/dist/esm/plugins/backend-federation/codegen.mjs +0 -205
- package/dist/esm/plugins/backend-federation/config.mjs +0 -128
- package/dist/esm/plugins/backend-federation/emit.mjs +0 -99
- package/dist/esm/plugins/backendFederationBuild.mjs +0 -1
- package/dist/esm/plugins/deploy/platforms/cloudflare-output-verifier/index.mjs +0 -1
- package/dist/esm/plugins/deploy/utils/npmAliases.mjs +0 -174
- package/dist/esm/plugins/ultramodernReleaseEnvelope.mjs +0 -6
- package/dist/esm/presetUltramodern.mjs +0 -112
- package/dist/esm/types/config/precompress.mjs +0 -0
- package/dist/esm-node/builder/shared/builderPlugins/adapterPrecompress.mjs +0 -78
- package/dist/esm-node/config/build-environment.mjs +0 -225
- package/dist/esm-node/config/public.mjs +0 -2
- package/dist/esm-node/plugins/backend-federation/codegen.mjs +0 -206
- package/dist/esm-node/plugins/backend-federation/config.mjs +0 -129
- package/dist/esm-node/plugins/backend-federation/emit.mjs +0 -100
- package/dist/esm-node/plugins/backendFederationBuild.mjs +0 -2
- package/dist/esm-node/plugins/deploy/platforms/cloudflare-output-verifier/index.mjs +0 -2
- package/dist/esm-node/plugins/deploy/utils/npmAliases.mjs +0 -175
- package/dist/esm-node/plugins/ultramodernReleaseEnvelope.mjs +0 -7
- package/dist/esm-node/presetUltramodern.mjs +0 -113
- package/dist/esm-node/types/config/precompress.mjs +0 -1
- package/dist/types/builder/shared/builderPlugins/adapterPrecompress.d.ts +0 -3
- package/dist/types/config/build-environment.d.ts +0 -22
- package/dist/types/config/public.d.ts +0 -2
- package/dist/types/plugins/backend-federation/codegen.d.ts +0 -86
- package/dist/types/plugins/backend-federation/config.d.ts +0 -103
- package/dist/types/plugins/backend-federation/emit.d.ts +0 -13
- package/dist/types/plugins/backendFederationBuild.d.ts +0 -2
- package/dist/types/plugins/deploy/platforms/cloudflare-output-verifier/index.d.ts +0 -1
- package/dist/types/plugins/deploy/utils/npmAliases.d.ts +0 -14
- package/dist/types/plugins/ultramodernReleaseEnvelope.d.ts +0 -3
- package/dist/types/presetUltramodern.d.ts +0 -87
- package/dist/types/types/config/precompress.d.ts +0 -20
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The fork's default server policy (localised loaders, error responses,
|
|
3
|
+
* telemetry, module-federation CSS and asset headers, static serving).
|
|
4
|
+
*
|
|
5
|
+
* It is exposed from `@modern-js/app-tools` so a plain `appTools()` app can
|
|
6
|
+
* load it by a specifier it is guaranteed to be able to resolve: every app
|
|
7
|
+
* declares `@modern-js/app-tools`, but not necessarily
|
|
8
|
+
* `@modern-js/server-runtime-extensions`.
|
|
9
|
+
*/
|
|
10
|
+
export { default } from '@modern-js/server-runtime-extensions/server-plugin';
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { BuilderConfig } from '@modern-js/builder';
|
|
2
2
|
import type { SSGConfig, SSGMultiEntryOptions } from '@modern-js/types';
|
|
3
3
|
import type { UnwrapBuilderConfig } from '../utils.js';
|
|
4
|
-
import type { PrecompressConfig } from './precompress.js';
|
|
5
|
-
export type { PrecompressCodecOptions, PrecompressConfig } from './precompress.js';
|
|
6
4
|
export interface OutputUserConfig extends UnwrapBuilderConfig<BuilderConfig, 'output'> {
|
|
7
5
|
/**
|
|
8
6
|
* Enable SSG for self-controlled routing or conventional routing.
|
|
@@ -34,12 +32,5 @@ export interface OutputUserConfig extends UnwrapBuilderConfig<BuilderConfig, 'ou
|
|
|
34
32
|
* Specify the temporary directory for framework generated files.
|
|
35
33
|
*/
|
|
36
34
|
tempDir?: string;
|
|
37
|
-
/**
|
|
38
|
-
* Generate precompressed static assets by using compression-webpack-plugin.
|
|
39
|
-
* `true` means enabling both gzip and brotli with default options.
|
|
40
|
-
* Disabled unless explicitly configured; `presetUltramodern` enables it.
|
|
41
|
-
* @default false
|
|
42
|
-
*/
|
|
43
|
-
precompress?: boolean | PrecompressConfig;
|
|
44
35
|
}
|
|
45
36
|
export type { SSGConfig, SSGMultiEntryOptions, SSGRouteOptions, SSGSingleEntryOptions, } from '@modern-js/types';
|
|
@@ -7,4 +7,4 @@ export type { CLIPluginExtends, RuntimePluginConfig, ServerPluginConfig };
|
|
|
7
7
|
export type AppUserConfig = AppToolsUserConfig;
|
|
8
8
|
export type AppNormalizedConfig = AppToolsNormalizedConfig;
|
|
9
9
|
export type AppToolsAPI = CLIPluginAPI<AppTools>;
|
|
10
|
-
export type { AppToolsContext, AppToolsExtendAPI, AppToolsExtendContext, AppToolsExtendHooks, AppToolsHooks as AppToolsFeatureHooks, } from './plugin.js';
|
|
10
|
+
export type { AfterBffCompileFn, AppToolsContext, AppToolsExtendAPI, AppToolsExtendContext, AppToolsExtendHooks, AppToolsHooks as AppToolsFeatureHooks, BeforeBffCompileFn, BffClientArtifact, BffClientArtifacts, BffCompilation, BffGeneratedEntries, BffGeneratedModule, BffGeneration, ModifyBffClientArtifactsFn, ModifyBffGeneratedEntriesFn, } from './plugin.js';
|
|
@@ -1,11 +1,60 @@
|
|
|
1
|
+
import type { ResolvedDeployTarget } from '@modern-js/app-tools-extensions/deploy-output/target';
|
|
1
2
|
import type { AppContext, AsyncHook, InternalContext, PluginHook, PluginHookTap, TransformFunction } from '@modern-js/plugin';
|
|
2
3
|
import type { Hooks } from '@modern-js/plugin/cli';
|
|
3
|
-
import type {
|
|
4
|
+
import type { BffRuntimeFramework } from '@modern-js/plugin/server';
|
|
5
|
+
import type { Entrypoint, HtmlPartials, HtmlTemplates, HttpMethodDecider, NestedRouteForCli, PageRoute, RouteLegacy, ServerPlugin, ServerRoute } from '@modern-js/types';
|
|
4
6
|
import type { EagerRouteComponentFilesByEntry } from '@modern-js/utils';
|
|
5
7
|
import type { EnvironmentConfig } from '@rsbuild/core';
|
|
6
8
|
import type { getHookRunners } from '../compat/hooks.js';
|
|
7
9
|
import type { AppTools } from './index.js';
|
|
8
10
|
import type { AppToolsNormalizedConfig, AppToolsUserConfig } from './config/index.js';
|
|
11
|
+
export interface BffCompilation {
|
|
12
|
+
readonly appDirectory: string;
|
|
13
|
+
readonly apiDirectory: string;
|
|
14
|
+
readonly sourceDirectories: readonly string[];
|
|
15
|
+
readonly outputDirectories: readonly string[];
|
|
16
|
+
readonly distDirectory: string;
|
|
17
|
+
readonly tsconfigPath?: string;
|
|
18
|
+
readonly moduleType: AppToolsContext['moduleType'];
|
|
19
|
+
}
|
|
20
|
+
export interface BffGeneration {
|
|
21
|
+
readonly appDirectory: string;
|
|
22
|
+
readonly apiDirectory: string;
|
|
23
|
+
readonly lambdaDirectory: string;
|
|
24
|
+
readonly existLambda: boolean;
|
|
25
|
+
readonly apiFiles: readonly string[];
|
|
26
|
+
readonly relativeDistPath: string;
|
|
27
|
+
readonly prefix: string;
|
|
28
|
+
readonly port?: number;
|
|
29
|
+
readonly requestId: string;
|
|
30
|
+
readonly requestCreator?: string;
|
|
31
|
+
readonly httpMethodDecider?: HttpMethodDecider;
|
|
32
|
+
}
|
|
33
|
+
export interface BffClientArtifact {
|
|
34
|
+
/** Canonical relative source path under generation.apiDirectory. */
|
|
35
|
+
readonly sourcePath: string;
|
|
36
|
+
readonly code: string;
|
|
37
|
+
readonly declaration: string;
|
|
38
|
+
}
|
|
39
|
+
export interface BffClientArtifacts {
|
|
40
|
+
readonly generation: BffGeneration;
|
|
41
|
+
additionalArtifacts: BffClientArtifact[];
|
|
42
|
+
}
|
|
43
|
+
export interface BffGeneratedModule {
|
|
44
|
+
readonly code: string;
|
|
45
|
+
readonly declaration: string;
|
|
46
|
+
}
|
|
47
|
+
export interface BffGeneratedEntries {
|
|
48
|
+
readonly generation: BffGeneration;
|
|
49
|
+
plugin: BffGeneratedModule;
|
|
50
|
+
runtime: BffGeneratedModule | null;
|
|
51
|
+
/** Direct dependencies required by the emitted SDK modules. */
|
|
52
|
+
packageDependencies: Record<string, string>;
|
|
53
|
+
}
|
|
54
|
+
export type BeforeBffCompileFn = (context: BffCompilation) => void | Promise<void>;
|
|
55
|
+
export type AfterBffCompileFn = (context: BffCompilation) => void | Promise<void>;
|
|
56
|
+
export type ModifyBffClientArtifactsFn = TransformFunction<BffClientArtifacts>;
|
|
57
|
+
export type ModifyBffGeneratedEntriesFn = TransformFunction<BffGeneratedEntries>;
|
|
9
58
|
export type AfterPrepareFn = () => Promise<void> | void;
|
|
10
59
|
export type CheckEntryPointFn = TransformFunction<{
|
|
11
60
|
path: string;
|
|
@@ -64,6 +113,10 @@ export interface AppToolsExtendAPI {
|
|
|
64
113
|
useHookRunners: () => ReturnType<typeof getHookRunners>;
|
|
65
114
|
}
|
|
66
115
|
export interface AppToolsExtendHooks extends Record<string, PluginHook<(...args: any[]) => any>> {
|
|
116
|
+
onBeforeBffCompile: AsyncHook<BeforeBffCompileFn>;
|
|
117
|
+
onAfterBffCompile: AsyncHook<AfterBffCompileFn>;
|
|
118
|
+
modifyBffClientArtifacts: AsyncHook<ModifyBffClientArtifactsFn>;
|
|
119
|
+
modifyBffGeneratedEntries: AsyncHook<ModifyBffGeneratedEntriesFn>;
|
|
67
120
|
onAfterPrepare: AsyncHook<AfterPrepareFn>;
|
|
68
121
|
deploy: AsyncHook<DeplpoyFn>;
|
|
69
122
|
checkEntryPoint: AsyncHook<CheckEntryPointFn>;
|
|
@@ -88,6 +141,8 @@ export interface AppToolsExtendContext {
|
|
|
88
141
|
runtimeConfigFile: string;
|
|
89
142
|
serverPlugins: ServerPlugin[];
|
|
90
143
|
moduleType: 'module' | 'commonjs';
|
|
144
|
+
/** Exact generated files excluded from server compilation. */
|
|
145
|
+
serverCompileExcludedFiles?: string[];
|
|
91
146
|
/** Information for entry points */
|
|
92
147
|
entrypoints: Entrypoint[];
|
|
93
148
|
/** Selected entry points */
|
|
@@ -96,6 +151,7 @@ export interface AppToolsExtendContext {
|
|
|
96
151
|
serverRoutes: ServerRoute[];
|
|
97
152
|
/** Whether to use api only mode */
|
|
98
153
|
apiOnly: boolean;
|
|
154
|
+
deployTarget: ResolvedDeployTarget;
|
|
99
155
|
_internalContext: InternalContext<AppTools>;
|
|
100
156
|
/**
|
|
101
157
|
* Information for HTML templates by entry
|
|
@@ -115,7 +171,7 @@ export interface AppToolsExtendContext {
|
|
|
115
171
|
* Identification for bff runtime framework
|
|
116
172
|
* @private
|
|
117
173
|
*/
|
|
118
|
-
bffRuntimeFramework?:
|
|
174
|
+
bffRuntimeFramework?: BffRuntimeFramework;
|
|
119
175
|
/**
|
|
120
176
|
* Route component files collected from the FINAL file-system routes (after all
|
|
121
177
|
* `modifyFileSystemRoutes` consumers ran), keyed by entry name. Populated by
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BffRuntimeFramework } from '@modern-js/plugin/server';
|
|
1
2
|
export declare const initAppContext: ({ metaName, appDirectory, runtimeConfigFile, options, tempDir, }: {
|
|
2
3
|
metaName: string;
|
|
3
4
|
appDirectory: string;
|
|
@@ -7,7 +8,7 @@ export declare const initAppContext: ({ metaName, appDirectory, runtimeConfigFil
|
|
|
7
8
|
apiDir?: string;
|
|
8
9
|
distDir?: string;
|
|
9
10
|
sharedDir?: string;
|
|
10
|
-
bffRuntimeFramework?:
|
|
11
|
+
bffRuntimeFramework?: BffRuntimeFramework;
|
|
11
12
|
};
|
|
12
13
|
tempDir?: string;
|
|
13
14
|
}) => {
|
|
@@ -27,5 +28,5 @@ export declare const initAppContext: ({ metaName, appDirectory, runtimeConfigFil
|
|
|
27
28
|
apiOnly: boolean;
|
|
28
29
|
internalDirAlias: string;
|
|
29
30
|
internalSrcAlias: string;
|
|
30
|
-
bffRuntimeFramework:
|
|
31
|
+
bffRuntimeFramework: keyof import("@modern-js/plugin/server").BffRuntimeRegistry;
|
|
31
32
|
};
|
|
@@ -227,6 +227,7 @@ Usage: modern deploy [options]
|
|
|
227
227
|
Options:
|
|
228
228
|
-c --config <config> Specify configuration file path, either relative or absolute
|
|
229
229
|
-s --skip-build Skip the build stage
|
|
230
|
+
--deploy-target <target> Deploy target (node, vercel, netlify, ghPages, cloudflare); overrides deploy.target and MODERNJS_DEPLOY
|
|
230
231
|
-h, --help Display command help
|
|
231
232
|
```
|
|
232
233
|
|
|
@@ -45,21 +45,33 @@ Please refer to the [Enable BFF](/guides/advanced-features/bff/function.md#enabl
|
|
|
45
45
|
|
|
46
46
|
:::caution Install the Effect peers yourself
|
|
47
47
|
`effect` and `@effect/opentelemetry` are **optional exact peer dependencies** of
|
|
48
|
-
`@modern-js/
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
`/effect-server`, `/effect-edge` or `/effect-client`, install the exact cohort:
|
|
48
|
+
`@modern-js/bff-effect`. Install them in the application so its API modules and
|
|
49
|
+
the framework use the same Effect instance. Before setting
|
|
50
|
+
`runtimeFramework: 'effect'` or importing `@modern-js/bff-effect/effect`,
|
|
51
|
+
`/effect-edge` or `/effect-client`, install the exact cohort:
|
|
53
52
|
|
|
54
53
|
```bash
|
|
55
|
-
pnpm add effect@4.0.0-rc.
|
|
54
|
+
pnpm add effect@4.0.0-rc.117 @effect/opentelemetry@4.0.0-rc.117
|
|
56
55
|
```
|
|
57
56
|
|
|
58
57
|
The pin is exact because UltraModern ships Effect as one lockstep cohort. Apps
|
|
59
|
-
using only `runtimeFramework: 'hono'` or
|
|
60
|
-
package.
|
|
58
|
+
using only native `runtimeFramework: 'hono'` or
|
|
59
|
+
`@modern-js/bff-effect/data-platform` need neither package.
|
|
61
60
|
:::
|
|
62
61
|
|
|
62
|
+
Use `bffPlugin` from `@modern-js/plugin-bff-build-extensions` to register the
|
|
63
|
+
Effect runtime. It composes the native BFF plugin. Install
|
|
64
|
+
`@modern-js/bff-effect` and `@modern-js/plugin-bff-extensions` from the same
|
|
65
|
+
framework cohort as application production dependencies, so the adapter remains
|
|
66
|
+
available after development dependencies are removed. The build plugin can be a
|
|
67
|
+
development dependency. See the [runtime configuration example](/guides/advanced-features/bff/frameworks.md).
|
|
68
|
+
|
|
69
|
+
Native `@modern-js/plugin-bff/server` exports Hono APIs. For Node Effect APIs,
|
|
70
|
+
import framework helpers such as `defineEffectBff` from
|
|
71
|
+
`@modern-js/bff-effect/effect` and namespaces from the corresponding `effect/*`
|
|
72
|
+
modules. Worker handlers and worker request context use
|
|
73
|
+
`@modern-js/bff-effect/effect-edge`.
|
|
74
|
+
|
|
63
75
|
Generated UltraModern workspaces use this runtime as the only generated HTTP API
|
|
64
76
|
path. The API contract lives at `shared/api.ts`, the server runtime lives at
|
|
65
77
|
`api/index.ts`, clients live under `src/api/*-client.ts`, and generated checks
|
|
@@ -171,7 +183,6 @@ export default defineConfig({
|
|
|
171
183
|
endpoint: '/_data/batch',
|
|
172
184
|
maxBatchSize: 16,
|
|
173
185
|
maxBatchBytes: 64 * 1024,
|
|
174
|
-
flushIntervalMs: 8,
|
|
175
186
|
maxConcurrency: 4,
|
|
176
187
|
requestTimeoutMs: 10000,
|
|
177
188
|
allowedMethods: ['GET'],
|
|
@@ -205,9 +216,9 @@ export default defineConfig({
|
|
|
205
216
|
});
|
|
206
217
|
```
|
|
207
218
|
|
|
208
|
-
`
|
|
219
|
+
`maxConcurrency` and `requestTimeoutMs` control the server batch gateway. Native `HttpApiClient` calls send individual requests; they do not automatically batch requests.
|
|
209
220
|
|
|
210
|
-
|
|
221
|
+
Import a shared `HttpApi` contract and pass it to `HttpApiClient.make` or `makeEffectHttpApiClient`. The client is fully type-inferred; `defineEffectBff` exposes server handlers and does not contain a client.
|
|
211
222
|
|
|
212
223
|
## Effect cohort
|
|
213
224
|
|
|
@@ -216,14 +227,10 @@ through `pnpm-workspace.yaml` overrides. For the current UltraModern cohort,
|
|
|
216
227
|
generated apps use:
|
|
217
228
|
|
|
218
229
|
```yaml
|
|
219
|
-
trustPolicyExclude:
|
|
220
|
-
- 'effect@4.0.0-rc.112'
|
|
221
|
-
- '@effect/opentelemetry@4.0.0-rc.112'
|
|
222
|
-
|
|
223
230
|
overrides:
|
|
224
|
-
'@effect/opentelemetry': 4.0.0-rc.
|
|
225
|
-
'@effect/vitest': 4.0.0-rc.
|
|
226
|
-
effect: 4.0.0-rc.
|
|
231
|
+
'@effect/opentelemetry': 4.0.0-rc.117
|
|
232
|
+
'@effect/vitest': 4.0.0-rc.117
|
|
233
|
+
effect: 4.0.0-rc.117
|
|
227
234
|
```
|
|
228
235
|
|
|
229
236
|
Do not add a different direct `effect` version in an app package. A mismatched
|
|
@@ -231,10 +238,7 @@ Effect prerelease can fail while building layers or HTTP middleware because runt
|
|
|
231
238
|
services come from different package instances. The strict 24-hour release-age
|
|
232
239
|
gate applies to installed packages; the current cohort has no Effect age
|
|
233
240
|
exemption, and override-only `@effect/vitest` is not an installed approval
|
|
234
|
-
target.
|
|
235
|
-
its exact `effect` and `@effect/opentelemetry` exceptions cover their
|
|
236
|
-
trusted-publisher to provenance metadata transition and are not release-age
|
|
237
|
-
approvals.
|
|
241
|
+
target.
|
|
238
242
|
|
|
239
243
|
## Contract tests
|
|
240
244
|
|
|
@@ -242,7 +246,7 @@ Strict Effect APIs should test the declared `HttpApi` contract, not a raw
|
|
|
242
246
|
request handler. Edge-compatible tests can use the framework helper:
|
|
243
247
|
|
|
244
248
|
```ts
|
|
245
|
-
import { createEffectBffTestHandler } from '@modern-js/
|
|
249
|
+
import { createEffectBffTestHandler } from '@modern-js/bff-effect/effect-edge';
|
|
246
250
|
import apiModule from '../api/index';
|
|
247
251
|
|
|
248
252
|
const testApi = await createEffectBffTestHandler({
|
|
@@ -257,12 +261,9 @@ If you manually compose an Effect web handler in a low-level proof, provide the
|
|
|
257
261
|
platform services explicitly:
|
|
258
262
|
|
|
259
263
|
```ts
|
|
260
|
-
import
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
HttpServer,
|
|
264
|
-
Layer,
|
|
265
|
-
} from '@modern-js/plugin-bff/effect-server';
|
|
264
|
+
import * as Layer from 'effect/Layer';
|
|
265
|
+
import { HttpRouter, HttpServer } from 'effect/unstable/http';
|
|
266
|
+
import { HttpApiBuilder } from 'effect/unstable/httpapi';
|
|
266
267
|
|
|
267
268
|
const handler = HttpRouter.toWebHandler(
|
|
268
269
|
HttpApiBuilder.layer(api).pipe(
|
|
@@ -282,13 +283,10 @@ current Effect v4 beta cohort, `HttpRouter.middleware(...)` returns a `Layer`
|
|
|
282
283
|
directly:
|
|
283
284
|
|
|
284
285
|
```ts
|
|
285
|
-
import
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
HttpRouter,
|
|
290
|
-
Layer,
|
|
291
|
-
} from '@modern-js/plugin-bff/effect-server';
|
|
286
|
+
import * as Effect from 'effect/Effect';
|
|
287
|
+
import * as Layer from 'effect/Layer';
|
|
288
|
+
import { HttpMiddleware, HttpRouter } from 'effect/unstable/http';
|
|
289
|
+
import { HttpApiBuilder } from 'effect/unstable/httpapi';
|
|
292
290
|
|
|
293
291
|
const corsLayer = HttpRouter.middleware(
|
|
294
292
|
Effect.succeed(
|
|
@@ -9,6 +9,8 @@ Whether to enable [React Compiler](https://react.dev/learn/react-compiler). Reac
|
|
|
9
9
|
|
|
10
10
|
Modern.js implements this capability based on the Rust-based React Compiler built into Rspack's `builtin:swc-loader` (equivalent to setting SWC's `jsc.transform.reactCompiler`), reusing Rspack's built-in SWC transform chain without introducing Babel.
|
|
11
11
|
|
|
12
|
+
The compiler only runs for browser environments (`output.target: 'web'`). Server environments (`node`, the `web-worker` SSR worker and BFF code) render once per request and gain nothing from memoization, so they are never compiled.
|
|
13
|
+
|
|
12
14
|
:::tip
|
|
13
15
|
This option is disabled by default. It must be enabled explicitly for any React version, including React 19.
|
|
14
16
|
:::
|
|
@@ -15,7 +15,7 @@ Modern.js Effect API runtime now supports a request-envelope based data platform
|
|
|
15
15
|
|
|
16
16
|
## Runtime contract helpers
|
|
17
17
|
|
|
18
|
-
Use `@modern-js/
|
|
18
|
+
Use `@modern-js/bff-effect/data-platform` helpers to build and validate contracts:
|
|
19
19
|
|
|
20
20
|
```ts
|
|
21
21
|
import {
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
validateHydrationEnvelope,
|
|
29
29
|
createInvalidationEvent,
|
|
30
30
|
shouldApplyInvalidation,
|
|
31
|
-
} from '@modern-js/
|
|
31
|
+
} from '@modern-js/bff-effect/data-platform';
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
## Effect runtime validation
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
# Runtime Framework
|
|
4
4
|
|
|
5
|
-
Modern.js
|
|
5
|
+
Modern.js and the UltraModern BFF extension provide two runtime frameworks:
|
|
6
6
|
|
|
7
|
-
- `
|
|
8
|
-
- `
|
|
7
|
+
- `hono` is the native plugin default and uses file-convention handlers from `api/lambda/**`.
|
|
8
|
+
- `effect` is the UltraModern extension default and uses [Effect HttpApi](https://effect.website/) from `api/index`.
|
|
9
9
|
|
|
10
10
|
`effect` and `hono` are strict runtime modes. There is no automatic fallback between them.
|
|
11
11
|
|
|
@@ -16,12 +16,18 @@ Generated UltraModern workspaces use strict Effect APIs: author HTTP APIs in
|
|
|
16
16
|
|
|
17
17
|
## Switch to Effect runtime
|
|
18
18
|
|
|
19
|
+
Use the fork build plugin below. It includes the native BFF plugin and registers
|
|
20
|
+
the Effect adapter. The application needs `@modern-js/bff-effect` and
|
|
21
|
+
`@modern-js/plugin-bff-extensions` as production dependencies from the same
|
|
22
|
+
framework cohort. Install the exact Effect peers described in
|
|
23
|
+
[`bff.effect`](/configure/app/bff/effect.md).
|
|
24
|
+
|
|
19
25
|
```ts title="modern.config.ts"
|
|
20
|
-
import { bffPlugin } from '@modern-js/plugin-bff';
|
|
21
|
-
import { defineConfig } from '@modern-js/app-tools';
|
|
26
|
+
import { bffPlugin } from '@modern-js/plugin-bff-build-extensions';
|
|
27
|
+
import { appTools, defineConfig } from '@modern-js/app-tools';
|
|
22
28
|
|
|
23
29
|
export default defineConfig({
|
|
24
|
-
plugins: [bffPlugin()],
|
|
30
|
+
plugins: [appTools(), bffPlugin()],
|
|
25
31
|
bff: {
|
|
26
32
|
runtimeFramework: 'effect',
|
|
27
33
|
effect: {
|
|
@@ -43,7 +49,7 @@ import {
|
|
|
43
49
|
HttpApiEndpoint,
|
|
44
50
|
HttpApiGroup,
|
|
45
51
|
Schema,
|
|
46
|
-
} from '@modern-js/
|
|
52
|
+
} from '@modern-js/bff-effect/effect-client';
|
|
47
53
|
|
|
48
54
|
export const bffApi = HttpApi.make('MyApi').add(
|
|
49
55
|
HttpApiGroup.make('hello').add(
|
|
@@ -57,14 +63,12 @@ export const bffApi = HttpApi.make('MyApi').add(
|
|
|
57
63
|
Implement your Effect API entry at `api/index.ts`:
|
|
58
64
|
|
|
59
65
|
```ts title="api/index.ts"
|
|
60
|
-
import {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
ServiceMap,
|
|
67
|
-
} from '@modern-js/plugin-bff/effect-server';
|
|
66
|
+
import { defineEffectBff } from '@modern-js/bff-effect/effect';
|
|
67
|
+
import * as Context from 'effect/Context';
|
|
68
|
+
import * as Effect from 'effect/Effect';
|
|
69
|
+
import * as Layer from 'effect/Layer';
|
|
70
|
+
import * as Schema from 'effect/Schema';
|
|
71
|
+
import { HttpApiBuilder } from 'effect/unstable/httpapi';
|
|
68
72
|
import { bffApi } from '../shared/api';
|
|
69
73
|
|
|
70
74
|
class GreetingUnavailableError extends Schema.TaggedError<GreetingUnavailableError>()(
|
|
@@ -74,7 +78,7 @@ class GreetingUnavailableError extends Schema.TaggedError<GreetingUnavailableErr
|
|
|
74
78
|
},
|
|
75
79
|
) {}
|
|
76
80
|
|
|
77
|
-
class GreetingService extends
|
|
81
|
+
class GreetingService extends Context.Service<GreetingService>()('GreetingService', {
|
|
78
82
|
make: Effect.succeed({
|
|
79
83
|
hello: Effect.fn('GreetingService.hello')(function* () {
|
|
80
84
|
if (Date.now() < 0) {
|
|
@@ -109,19 +113,27 @@ const layer = HttpApiBuilder.layer(bffApi).pipe(
|
|
|
109
113
|
export default defineEffectBff({ api: bffApi, layer });
|
|
110
114
|
```
|
|
111
115
|
|
|
112
|
-
|
|
116
|
+
Create a native, fully inferred client from the shared contract:
|
|
113
117
|
|
|
114
118
|
```ts title="src/routes/page.tsx"
|
|
115
|
-
import
|
|
119
|
+
import { Effect, makeEffectHttpApiClient } from '@modern-js/bff-effect/effect-client';
|
|
120
|
+
import { bffApi } from '../../shared/api';
|
|
116
121
|
|
|
117
|
-
const response = await
|
|
122
|
+
const response = await Effect.runPromise(
|
|
123
|
+
makeEffectHttpApiClient(bffApi, { baseUrl: '/api' }).pipe(
|
|
124
|
+
Effect.flatMap(client => client.hello.ping({})),
|
|
125
|
+
),
|
|
126
|
+
);
|
|
118
127
|
```
|
|
119
128
|
|
|
120
|
-
|
|
129
|
+
Requests, responses, and declared errors are inferred from `bffApi`. No client generation or server-entry import is needed.
|
|
121
130
|
|
|
122
131
|
For UltraModern, Effect `HttpApi` plus Effect BFF is the single blessed authored HTTP path. Use `HttpApi` endpoints with `query`, `params`, `payload`, `success`, and declared errors such as `HttpApiSchema.status(...)`; implement them with `HttpApiBuilder.group(...).handle(...)` and `HttpApiBuilder.layer(...).pipe(Layer.provide(...))`, then default-export the entry as `defineEffectBff({ api, layer })`. See `packages/server/bff-effect/tests/effect-edge-runtime.test.ts` for the live runtime shape.
|
|
123
132
|
|
|
124
|
-
Hono
|
|
133
|
+
Native Hono applications import operators from `@modern-js/plugin-bff/server`.
|
|
134
|
+
UltraModern-generated applications keep their strict Effect API model. Worker
|
|
135
|
+
handlers use `@modern-js/bff-effect/effect-edge`, including its worker request
|
|
136
|
+
context exports; Node handlers use the Effect entry shown above.
|
|
125
137
|
|
|
126
138
|
### Getting Request Context
|
|
127
139
|
|
|
@@ -146,7 +158,7 @@ For more details, refer to [useHonoContext](/apis/app/runtime/bff/use-backend-co
|
|
|
146
158
|
When getting cookies in BFF functions, you need to get the request context through `useHonoContext`, then use `c.req.header('cookie')` to get the Cookie string and parse it manually:
|
|
147
159
|
|
|
148
160
|
```ts title="api/lambda/cookies.ts"
|
|
149
|
-
import { Api, Get } from '@modern-js/plugin-bff/
|
|
161
|
+
import { Api, Get } from '@modern-js/plugin-bff/server';
|
|
150
162
|
import { useHonoContext } from '@modern-js/server-runtime';
|
|
151
163
|
|
|
152
164
|
// Helper function to parse Cookie string
|
|
@@ -189,7 +201,7 @@ The `c.req.cookie()` method does not exist in the current version. You need to u
|
|
|
189
201
|
When using Hono as the runtime framework, you can define interfaces through [Api functions](/guides/advanced-features/bff/operators.md):
|
|
190
202
|
|
|
191
203
|
```ts title="api/lambda/user.ts"
|
|
192
|
-
import { Api, Get, Query } from '@modern-js/plugin-bff/
|
|
204
|
+
import { Api, Get, Query } from '@modern-js/plugin-bff/server';
|
|
193
205
|
import { z } from 'zod';
|
|
194
206
|
|
|
195
207
|
const QuerySchema = z.object({
|
|
@@ -218,7 +230,7 @@ For more details about Api functions and operators, refer to [Creating Extensibl
|
|
|
218
230
|
Hono supports a rich middleware ecosystem, and you can use middleware in BFF functions:
|
|
219
231
|
|
|
220
232
|
```ts title="api/lambda/user.ts"
|
|
221
|
-
import { Api, Get, Middleware } from '@modern-js/plugin-bff/
|
|
233
|
+
import { Api, Get, Middleware } from '@modern-js/plugin-bff/server';
|
|
222
234
|
|
|
223
235
|
export const getUser = Api(
|
|
224
236
|
Get('/user'),
|
|
@@ -246,7 +246,7 @@ Parameters following the dynamic path are an object called `RequestOption`, whic
|
|
|
246
246
|
In a standard function without dynamic routes, `RequestOption` can be obtained from the first parameter, for example:
|
|
247
247
|
|
|
248
248
|
```ts title="api/lambda/hello.ts"
|
|
249
|
-
import type { RequestOption } from '@modern-js/plugin-bff/
|
|
249
|
+
import type { RequestOption } from '@modern-js/plugin-bff/server';
|
|
250
250
|
|
|
251
251
|
export async function post({
|
|
252
252
|
query,
|
|
@@ -259,7 +259,7 @@ export async function post({
|
|
|
259
259
|
Custom types can also be used here:
|
|
260
260
|
|
|
261
261
|
```ts title="api/lambda/hello.ts"
|
|
262
|
-
import type { RequestOption } from '@modern-js/plugin-bff/
|
|
262
|
+
import type { RequestOption } from '@modern-js/plugin-bff/server';
|
|
263
263
|
|
|
264
264
|
type IQuery = {
|
|
265
265
|
// some types
|
|
@@ -29,7 +29,7 @@ A BFF function created by the `Api` function consists of the following parts:
|
|
|
29
29
|
The server can define the input parameters and types of the interface. Based on the types, the server will automatically perform type validation at runtime:
|
|
30
30
|
|
|
31
31
|
```typescript title="api/lambda/user.ts"
|
|
32
|
-
import { Api, Post, Query, Data } from '@modern-js/plugin-bff/
|
|
32
|
+
import { Api, Post, Query, Data } from '@modern-js/plugin-bff/server';
|
|
33
33
|
import { z } from 'zod';
|
|
34
34
|
|
|
35
35
|
const UserSchema = z.object({
|
|
@@ -78,7 +78,7 @@ addUser({
|
|
|
78
78
|
As shown in the example below, you can specify the route and HTTP Method through the `Get` function:
|
|
79
79
|
|
|
80
80
|
```typescript title="api/lambda/user.ts"
|
|
81
|
-
import { Api, Get, Query, Data } from '@modern-js/plugin-bff/
|
|
81
|
+
import { Api, Get, Query, Data } from '@modern-js/plugin-bff/server';
|
|
82
82
|
|
|
83
83
|
// Specify the interface route, Modern.js sets `bff.prefix` to `/api` by default,
|
|
84
84
|
// so the interface route is `/api/user`, and the HTTP Method is GET.
|
|
@@ -92,7 +92,7 @@ export const getHello = Api(
|
|
|
92
92
|
When the route is not specified, the interface route is defined according to the file convention. As shown in the example below, with the function writing method, there is a code path `api/lambda/user.ts`, which will register the corresponding interface `/api/user`.
|
|
93
93
|
|
|
94
94
|
```typescript title="api/lambda/user.ts"
|
|
95
|
-
import { Api, Get, Query, Data } from '@modern-js/plugin-bff/
|
|
95
|
+
import { Api, Get, Query, Data } from '@modern-js/plugin-bff/server';
|
|
96
96
|
|
|
97
97
|
// No interface route specified, according to file convention and function name, the interface is api/user, HTTP Method is get.
|
|
98
98
|
export const get = Api(Query(UserSchema), async ({ query }) => query);
|
|
@@ -125,7 +125,7 @@ Using the `Query` function, you can define the type of query. After using the `Q
|
|
|
125
125
|
|
|
126
126
|
```typescript title="api/lambda/user.ts"
|
|
127
127
|
// Server-side code
|
|
128
|
-
import { Api, Query } from '@modern-js/plugin-bff/
|
|
128
|
+
import { Api, Query } from '@modern-js/plugin-bff/server';
|
|
129
129
|
import { z } from 'zod';
|
|
130
130
|
|
|
131
131
|
const UserSchema = z.object({
|
|
@@ -153,7 +153,7 @@ get({
|
|
|
153
153
|
URL query parameters are strings by default. If you need numeric types, you need to use `z.coerce.number()` for type conversion:
|
|
154
154
|
|
|
155
155
|
```typescript title="api/lambda/user.ts"
|
|
156
|
-
import { Api, Get, Query } from '@modern-js/plugin-bff/
|
|
156
|
+
import { Api, Get, Query } from '@modern-js/plugin-bff/server';
|
|
157
157
|
import { z } from 'zod';
|
|
158
158
|
|
|
159
159
|
const QuerySchema = z.object({
|
|
@@ -189,7 +189,7 @@ If you use the Data function, you must follow the HTTP protocol. When the HTTP M
|
|
|
189
189
|
:::
|
|
190
190
|
|
|
191
191
|
```typescript title="api/lambda/user.ts"
|
|
192
|
-
import { Api, Data } from '@modern-js/plugin-bff/
|
|
192
|
+
import { Api, Data } from '@modern-js/plugin-bff/server';
|
|
193
193
|
import { z } from 'zod';
|
|
194
194
|
|
|
195
195
|
const DataSchema = z.object({
|
|
@@ -218,7 +218,7 @@ post({
|
|
|
218
218
|
Route parameters can implement dynamic routes and get parameters from the path. You can specify path parameters through `Params<T>(schema: z.ZodType<T>)`
|
|
219
219
|
|
|
220
220
|
```typescript
|
|
221
|
-
import { Api, Get, Params } from '@modern-js/plugin-bff/
|
|
221
|
+
import { Api, Get, Params } from '@modern-js/plugin-bff/server';
|
|
222
222
|
import { z } from 'zod';
|
|
223
223
|
|
|
224
224
|
const UserSchema = z.object({
|
|
@@ -239,7 +239,7 @@ export const queryUser = Api(
|
|
|
239
239
|
You can define the request headers required by the interface through the `Headers<T>(schema: z.ZodType<T>)` function and pass the request headers through integrated calls:
|
|
240
240
|
|
|
241
241
|
```typescript
|
|
242
|
-
import { Api, Headers } from '@modern-js/plugin-bff/
|
|
242
|
+
import { Api, Headers } from '@modern-js/plugin-bff/server';
|
|
243
243
|
import { z } from 'zod';
|
|
244
244
|
|
|
245
245
|
const headerSchema = z.object({
|
|
@@ -297,7 +297,7 @@ The `Middleware` operator can be configured multiple times, and the execution or
|
|
|
297
297
|
:::
|
|
298
298
|
|
|
299
299
|
```typescript
|
|
300
|
-
import { Api, Query, Middleware } from '@modern-js/plugin-bff/
|
|
300
|
+
import { Api, Query, Middleware } from '@modern-js/plugin-bff/server';
|
|
301
301
|
import { z } from 'zod';
|
|
302
302
|
|
|
303
303
|
const UserSchema = z.object({
|
|
@@ -333,7 +333,7 @@ The `Pipe` operator can be configured multiple times. The execution order of fun
|
|
|
333
333
|
:::
|
|
334
334
|
|
|
335
335
|
```typescript
|
|
336
|
-
import { Api, Query, Pipe } from '@modern-js/plugin-bff/
|
|
336
|
+
import { Api, Query, Pipe } from '@modern-js/plugin-bff/server';
|
|
337
337
|
import { z } from 'zod';
|
|
338
338
|
|
|
339
339
|
const UserSchema = z.object({
|
|
@@ -361,7 +361,7 @@ export const get = Api(
|
|
|
361
361
|
Also,
|
|
362
362
|
|
|
363
363
|
```typescript
|
|
364
|
-
import { Api, Query, Pipe } from '@modern-js/plugin-bff/
|
|
364
|
+
import { Api, Query, Pipe } from '@modern-js/plugin-bff/server';
|
|
365
365
|
import { z } from 'zod';
|
|
366
366
|
|
|
367
367
|
const UserSchema = z.object({
|
|
@@ -392,7 +392,7 @@ export const get = Api(
|
|
|
392
392
|
If you need to do more custom operations on the response, you can pass a function to the `end` function. The input parameter of the function is Hono's Context (`c`), and you can operate on `c.req` and `c.res`:
|
|
393
393
|
|
|
394
394
|
```typescript
|
|
395
|
-
import { Api, Query, Pipe } from '@modern-js/plugin-bff/
|
|
395
|
+
import { Api, Query, Pipe } from '@modern-js/plugin-bff/server';
|
|
396
396
|
import { z } from 'zod';
|
|
397
397
|
|
|
398
398
|
const UserSchema = z.object({
|
|
@@ -432,7 +432,7 @@ The following are response-related operators. Through response operators, you ca
|
|
|
432
432
|
You can specify the status code returned by the interface through the `HttpCode(statusCode: number)` function
|
|
433
433
|
|
|
434
434
|
```typescript
|
|
435
|
-
import { Api, Query, Data, HttpCode } from '@modern-js/plugin-bff/
|
|
435
|
+
import { Api, Query, Data, HttpCode } from '@modern-js/plugin-bff/server';
|
|
436
436
|
import { z } from 'zod';
|
|
437
437
|
|
|
438
438
|
const UserSchema = z.object({
|
|
@@ -464,7 +464,7 @@ export const post = Api(
|
|
|
464
464
|
Supports setting response headers through the `SetHeaders(headers: Record<string, string>)` function
|
|
465
465
|
|
|
466
466
|
```typescript
|
|
467
|
-
import { Api, Get, SetHeaders } from '@modern-js/plugin-bff/
|
|
467
|
+
import { Api, Get, SetHeaders } from '@modern-js/plugin-bff/server';
|
|
468
468
|
|
|
469
469
|
export default Api(
|
|
470
470
|
Get('/hello'),
|
|
@@ -480,7 +480,7 @@ export default Api(
|
|
|
480
480
|
Supports redirecting the interface through `Redirect(url: string)`:
|
|
481
481
|
|
|
482
482
|
```typescript
|
|
483
|
-
import { Api, Get, Redirect } from '@modern-js/plugin-bff/
|
|
483
|
+
import { Api, Get, Redirect } from '@modern-js/plugin-bff/server';
|
|
484
484
|
|
|
485
485
|
export default Api(
|
|
486
486
|
Get('/hello'),
|
|
@@ -494,7 +494,7 @@ export default Api(
|
|
|
494
494
|
As mentioned above, through operators, you can get `query`, `data`, `params`, etc. in the input parameters of the interface processing function. But sometimes we need to get more request context information. At this time, we can get it through [`useHonoContext`](/apis/app/runtime/bff/use-backend-context.md):
|
|
495
495
|
|
|
496
496
|
```typescript title="api/lambda/user.ts"
|
|
497
|
-
import { Api, Get, Query } from '@modern-js/plugin-bff/
|
|
497
|
+
import { Api, Get, Query } from '@modern-js/plugin-bff/server';
|
|
498
498
|
import { useHonoContext } from '@modern-js/server-runtime';
|
|
499
499
|
import { z } from 'zod';
|
|
500
500
|
|
|
@@ -539,7 +539,7 @@ For specific comparisons of different solutions, you can refer to [Why Use Zod](
|
|
|
539
539
|
In frontend development, some server interfaces (such as some configuration interfaces) have long response times, but actually don't need to be updated for a long time. For such interfaces, we can set HTTP cache to improve page performance:
|
|
540
540
|
|
|
541
541
|
```typescript
|
|
542
|
-
import { Api, SetHeaders } from '@modern-js/plugin-bff/
|
|
542
|
+
import { Api, SetHeaders } from '@modern-js/plugin-bff/server';
|
|
543
543
|
|
|
544
544
|
export const get = Api(
|
|
545
545
|
// Cache will only take effect when using integrated calls or fetch for requests
|