@bleedingdev/modern-js-app-tools 3.9.0-ultramodern.8 → 3.9.3-ultramodern.1

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.
Files changed (149) hide show
  1. package/bin/modern-bundle-docs.js +2 -2
  2. package/bin/modern.js +2 -2
  3. package/dist/cjs/builder/generator/adapterCopy.js +26 -0
  4. package/dist/cjs/builder/generator/createCopyPattern.js +2 -1
  5. package/dist/cjs/builder/index.js +4 -0
  6. package/dist/cjs/builder/shared/builderPlugins/adapterHtml.js +2 -1
  7. package/dist/cjs/builder/shared/builderPlugins/adapterSSR.js +11 -6
  8. package/dist/cjs/builder/shared/lazyCompilation.js +26 -0
  9. package/dist/cjs/commands/build.js +1 -2
  10. package/dist/cjs/commands/deploy.js +1 -3
  11. package/dist/cjs/commands/index.js +10 -2
  12. package/dist/cjs/compat/hooks.js +1 -1
  13. package/dist/cjs/esm/ts-paths-loader.js +5 -4
  14. package/dist/cjs/esm/ts-paths-loader.mjs +5 -4
  15. package/dist/cjs/index.js +89 -110
  16. package/dist/cjs/plugins/analyze/getFileSystemEntry.js +1 -1
  17. package/dist/cjs/plugins/analyze/getServerRoutes.js +1 -1
  18. package/dist/cjs/plugins/analyze/index.js +2 -2
  19. package/dist/cjs/plugins/analyze/utils.js +6 -6
  20. package/dist/cjs/plugins/deploy/index.js +7 -28
  21. package/dist/cjs/plugins/deploy/platforms/netlify.js +2 -1
  22. package/dist/cjs/plugins/deploy/platforms/node.js +12 -3
  23. package/dist/cjs/plugins/deploy/platforms/templates/node-entry.cjs +3 -2
  24. package/dist/cjs/plugins/deploy/platforms/templates/node-entry.mjs +3 -2
  25. package/dist/cjs/plugins/deploy/platforms/vercel.js +2 -1
  26. package/dist/cjs/plugins/deploy/utils/index.js +15 -12
  27. package/dist/cjs/plugins/initialize/index.js +6 -5
  28. package/dist/cjs/plugins/serverBuild.js +0 -2
  29. package/dist/cjs/run/index.js +5 -5
  30. package/dist/cjs/{plugins/serverRuntime.js → server-plugin.js} +13 -16
  31. package/dist/cjs/types/config/base.js +62 -0
  32. package/dist/cjs/types/plugin-base.js +18 -0
  33. package/dist/cjs/types/plugin.js +46 -2
  34. package/dist/cjs/utils/initAppContext.js +1 -1
  35. package/dist/cjs/utils/loadPlugins.js +13 -7
  36. package/dist/cjs/utils/register.js +1 -1
  37. package/dist/esm/builder/generator/adapterCopy.mjs +23 -1
  38. package/dist/esm/builder/generator/createCopyPattern.mjs +2 -1
  39. package/dist/esm/builder/index.mjs +1 -0
  40. package/dist/esm/builder/shared/builderPlugins/adapterHtml.mjs +2 -1
  41. package/dist/esm/builder/shared/builderPlugins/adapterSSR.mjs +9 -7
  42. package/dist/esm/builder/shared/lazyCompilation.mjs +14 -1
  43. package/dist/esm/commands/build.mjs +1 -2
  44. package/dist/esm/commands/deploy.mjs +1 -3
  45. package/dist/esm/commands/index.mjs +10 -2
  46. package/dist/esm/compat/hooks.mjs +1 -1
  47. package/dist/esm/esm/ts-paths-loader.mjs +5 -4
  48. package/dist/esm/index.mjs +13 -20
  49. package/dist/esm/plugins/analyze/getFileSystemEntry.mjs +1 -1
  50. package/dist/esm/plugins/analyze/getServerRoutes.mjs +1 -1
  51. package/dist/esm/plugins/analyze/index.mjs +2 -2
  52. package/dist/esm/plugins/analyze/utils.mjs +7 -7
  53. package/dist/esm/plugins/deploy/index.mjs +5 -21
  54. package/dist/esm/plugins/deploy/platforms/netlify.mjs +2 -1
  55. package/dist/esm/plugins/deploy/platforms/node.mjs +12 -3
  56. package/dist/esm/plugins/deploy/platforms/templates/node-entry.cjs +3 -2
  57. package/dist/esm/plugins/deploy/platforms/templates/node-entry.mjs +3 -2
  58. package/dist/esm/plugins/deploy/platforms/vercel.mjs +2 -1
  59. package/dist/esm/plugins/deploy/utils/index.mjs +17 -14
  60. package/dist/esm/plugins/initialize/index.mjs +6 -5
  61. package/dist/esm/plugins/serverBuild.mjs +0 -2
  62. package/dist/esm/run/index.mjs +5 -5
  63. package/dist/esm/server-plugin.mjs +1 -0
  64. package/dist/esm/types/config/base.mjs +1 -0
  65. package/dist/esm/types/plugin-base.mjs +0 -0
  66. package/dist/esm/types/plugin.mjs +1 -0
  67. package/dist/esm/utils/initAppContext.mjs +2 -2
  68. package/dist/esm/utils/loadPlugins.mjs +4 -8
  69. package/dist/esm/utils/register.mjs +1 -1
  70. package/dist/esm-node/builder/generator/adapterCopy.mjs +23 -1
  71. package/dist/esm-node/builder/generator/createCopyPattern.mjs +2 -1
  72. package/dist/esm-node/builder/index.mjs +1 -0
  73. package/dist/esm-node/builder/shared/builderPlugins/adapterHtml.mjs +2 -1
  74. package/dist/esm-node/builder/shared/builderPlugins/adapterSSR.mjs +9 -7
  75. package/dist/esm-node/builder/shared/lazyCompilation.mjs +14 -1
  76. package/dist/esm-node/commands/build.mjs +1 -2
  77. package/dist/esm-node/commands/deploy.mjs +1 -3
  78. package/dist/esm-node/commands/index.mjs +10 -2
  79. package/dist/esm-node/compat/hooks.mjs +1 -1
  80. package/dist/esm-node/esm/ts-paths-loader.mjs +5 -4
  81. package/dist/esm-node/index.mjs +14 -22
  82. package/dist/esm-node/plugins/analyze/getFileSystemEntry.mjs +1 -1
  83. package/dist/esm-node/plugins/analyze/getServerRoutes.mjs +1 -1
  84. package/dist/esm-node/plugins/analyze/index.mjs +2 -2
  85. package/dist/esm-node/plugins/analyze/utils.mjs +7 -7
  86. package/dist/esm-node/plugins/deploy/index.mjs +5 -21
  87. package/dist/esm-node/plugins/deploy/platforms/netlify.mjs +2 -1
  88. package/dist/esm-node/plugins/deploy/platforms/node.mjs +12 -3
  89. package/dist/esm-node/plugins/deploy/platforms/templates/node-entry.cjs +3 -2
  90. package/dist/esm-node/plugins/deploy/platforms/templates/node-entry.mjs +3 -2
  91. package/dist/esm-node/plugins/deploy/platforms/vercel.mjs +2 -1
  92. package/dist/esm-node/plugins/deploy/utils/index.mjs +17 -15
  93. package/dist/esm-node/plugins/initialize/index.mjs +6 -5
  94. package/dist/esm-node/plugins/serverBuild.mjs +0 -2
  95. package/dist/esm-node/run/index.mjs +5 -5
  96. package/dist/esm-node/server-plugin.mjs +2 -0
  97. package/dist/esm-node/types/config/base.mjs +2 -0
  98. package/dist/esm-node/types/plugin-base.mjs +1 -0
  99. package/dist/esm-node/types/plugin.mjs +1 -0
  100. package/dist/esm-node/utils/initAppContext.mjs +2 -2
  101. package/dist/esm-node/utils/loadPlugins.mjs +4 -8
  102. package/dist/esm-node/utils/register.mjs +1 -1
  103. package/dist/types/builder/generator/adapterCopy.d.ts +13 -1
  104. package/dist/types/builder/index.d.ts +1 -0
  105. package/dist/types/builder/shared/builderPlugins/adapterBasic.d.ts +4 -2
  106. package/dist/types/builder/shared/builderPlugins/adapterSSR.d.ts +2 -1
  107. package/dist/types/builder/shared/builderPlugins/builderHooks.d.ts +10 -2
  108. package/dist/types/builder/shared/lazyCompilation.d.ts +15 -0
  109. package/dist/types/compat/hooks.d.ts +3 -2
  110. package/dist/types/index.d.ts +3 -4
  111. package/dist/types/plugins/analyze/getBundleEntry.d.ts +5 -4
  112. package/dist/types/plugins/analyze/getFileSystemEntry.d.ts +5 -4
  113. package/dist/types/plugins/analyze/utils.d.ts +2 -2
  114. package/dist/types/plugins/deploy/index.d.ts +1 -4
  115. package/dist/types/plugins/deploy/utils/generator.d.ts +1 -1
  116. package/dist/types/plugins/deploy/utils/index.d.ts +1 -1
  117. package/dist/types/run/index.d.ts +1 -1
  118. package/dist/types/server-plugin.d.ts +10 -0
  119. package/dist/types/types/config/base.d.ts +58 -0
  120. package/dist/types/types/config/deploy.d.ts +2 -50
  121. package/dist/types/types/config/dev.d.ts +1 -1
  122. package/dist/types/types/config/index.d.ts +18 -42
  123. package/dist/types/types/config/output.d.ts +2 -2
  124. package/dist/types/types/config/testing.d.ts +1 -1
  125. package/dist/types/types/config/tools.d.ts +1 -1
  126. package/dist/types/types/plugin-base.d.ts +188 -0
  127. package/dist/types/types/plugin.d.ts +9 -183
  128. package/dist/types/utils/initAppContext.d.ts +2 -2
  129. package/docs/apis/app/commands.md +1 -0
  130. package/docs/configure/app/bff/effect.md +5 -12
  131. package/docs/configure/app/output/disable-svgr.md +4 -0
  132. package/docs/configure/app/output/svg-default-export.md +4 -0
  133. package/docs/configure/app/source/react-compiler.md +2 -0
  134. package/docs/configure/app/tools/less.md +94 -19
  135. package/docs/configure/app/tools/sass.md +87 -18
  136. package/docs/configure/app/tools/svgr.md +91 -0
  137. package/docs/configure/app/tools/ts-checker.md +7 -21
  138. package/docs/guides/basic-features/render/ssr-cache.md +14 -1
  139. package/docs/guides/basic-features/static-assets/svg-assets.md +29 -17
  140. package/docs/guides/basic-features/testing/rstest.md +0 -2
  141. package/docs/guides/get-started/quick-start.md +1 -1
  142. package/docs/guides/get-started/ultramodern.md +45 -14
  143. package/docs/llms.txt +4 -3
  144. package/docs/plugin/introduction.md +10 -10
  145. package/docs/plugin/server-plugins/api.md +1 -0
  146. package/package.json +67 -30
  147. package/dist/esm/plugins/serverRuntime.mjs +0 -15
  148. package/dist/esm-node/plugins/serverRuntime.mjs +0 -16
  149. package/dist/types/plugins/serverRuntime.d.ts +0 -3
@@ -0,0 +1,188 @@
1
+ import type { ResolvedDeployTarget } from '@modern-js/app-tools-extensions/deploy-output/target';
2
+ import type { AppContext, AsyncHook, CLIPluginExtends, InternalContext, PluginHook, PluginHookTap, TransformFunction } from '@modern-js/plugin/cli';
3
+ import type { BffRuntimeFramework } from '@modern-js/plugin/server';
4
+ import type { Entrypoint, HtmlPartials, HtmlTemplates, RouteLegacy } from '@modern-js/types/cli/base';
5
+ import type { ServerPlugin } from '@modern-js/types/common';
6
+ import type { HttpMethodDecider, ServerRoute } from '@modern-js/types/server';
7
+ import type { EagerRouteComponentFilesByEntry } from '@modern-js/utils/route-component-files';
8
+ import type { EnvironmentConfig } from '@rsbuild/core';
9
+ export type AppToolsModuleType = 'module' | 'commonjs';
10
+ export type AppToolsHookRunners = Record<string, any>;
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: AppToolsModuleType;
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>;
58
+ export type AfterPrepareFn = () => Promise<void> | void;
59
+ export type CheckEntryPointFn = TransformFunction<{
60
+ path: string;
61
+ entry: false | string;
62
+ }>;
63
+ export type ModifyEntrypointsFn = TransformFunction<{
64
+ entrypoints: Entrypoint[];
65
+ }>;
66
+ export type ModifyBuilderEnvironmentsFn = TransformFunction<{
67
+ environments: Record<string, EnvironmentConfig>;
68
+ }>;
69
+ export type ModifyFileSystemRoutesFn<Routes> = TransformFunction<{
70
+ entrypoint: Entrypoint;
71
+ routes: RouteLegacy[] | Routes[];
72
+ }>;
73
+ export type DeplpoyFn = () => Promise<void> | void;
74
+ export type GenerateEntryCodeFn = (params: {
75
+ entrypoints: Entrypoint[];
76
+ }) => Promise<void> | void;
77
+ export type BeforeGenerateRoutesFn = TransformFunction<{
78
+ entrypoint: Entrypoint;
79
+ code: string;
80
+ }>;
81
+ export type BeforePrintInstructionsFn = TransformFunction<{
82
+ instructions: string;
83
+ }>;
84
+ export type AddRuntimeExportsFn = () => Promise<void> | void;
85
+ export interface AppToolsExtendAPIBase<Extends extends CLIPluginExtends, Routes> {
86
+ onAfterPrepare: PluginHookTap<AfterPrepareFn>;
87
+ deploy: PluginHookTap<DeplpoyFn>;
88
+ checkEntryPoint: PluginHookTap<CheckEntryPointFn>;
89
+ modifyEntrypoints: PluginHookTap<ModifyEntrypointsFn>;
90
+ modifyBuilderEnvironments: PluginHookTap<ModifyBuilderEnvironmentsFn>;
91
+ modifyFileSystemRoutes: PluginHookTap<ModifyFileSystemRoutesFn<Routes>>;
92
+ generateEntryCode: PluginHookTap<GenerateEntryCodeFn>;
93
+ onBeforeGenerateRoutes: PluginHookTap<BeforeGenerateRoutesFn>;
94
+ /**
95
+ * @deprecated
96
+ */
97
+ onBeforePrintInstructions: PluginHookTap<BeforePrintInstructionsFn>;
98
+ /**
99
+ * @deprecated use getAppContext instead
100
+ */
101
+ useAppContext: () => AppContext<Extends> & Extends['extendContext'];
102
+ /**
103
+ * @deprecated use getConfig instead
104
+ */
105
+ useConfigContext: () => Extends['config'];
106
+ /**
107
+ * @deprecated use getNormalizedConfig instead
108
+ */
109
+ useResolvedConfigContext: () => Extends['normalizedConfig'];
110
+ /**
111
+ * @deprecated use api.xx instead
112
+ */
113
+ useHookRunners: () => AppToolsHookRunners;
114
+ }
115
+ export interface AppToolsExtendHooksBase<Routes> extends Record<string, PluginHook<(...args: any[]) => any>> {
116
+ onBeforeBffCompile: AsyncHook<BeforeBffCompileFn>;
117
+ onAfterBffCompile: AsyncHook<AfterBffCompileFn>;
118
+ modifyBffClientArtifacts: AsyncHook<ModifyBffClientArtifactsFn>;
119
+ modifyBffGeneratedEntries: AsyncHook<ModifyBffGeneratedEntriesFn>;
120
+ onAfterPrepare: AsyncHook<AfterPrepareFn>;
121
+ deploy: AsyncHook<DeplpoyFn>;
122
+ checkEntryPoint: AsyncHook<CheckEntryPointFn>;
123
+ modifyEntrypoints: AsyncHook<ModifyEntrypointsFn>;
124
+ modifyBuilderEnvironments: AsyncHook<ModifyBuilderEnvironmentsFn>;
125
+ modifyFileSystemRoutes: AsyncHook<ModifyFileSystemRoutesFn<Routes>>;
126
+ generateEntryCode: AsyncHook<GenerateEntryCodeFn>;
127
+ onBeforeGenerateRoutes: AsyncHook<BeforeGenerateRoutesFn>;
128
+ /**
129
+ * @deprecated
130
+ */
131
+ onBeforePrintInstructions: AsyncHook<BeforePrintInstructionsFn>;
132
+ }
133
+ export interface AppToolsExtendContextBase<Extends extends CLIPluginExtends> {
134
+ metaName: string;
135
+ internalDirectory: string;
136
+ sharedDirectory: string;
137
+ internalDirAlias: string;
138
+ internalSrcAlias: string;
139
+ apiDirectory: string;
140
+ lambdaDirectory: string;
141
+ runtimeConfigFile: string;
142
+ serverPlugins: ServerPlugin[];
143
+ moduleType: AppToolsModuleType;
144
+ /** Exact generated files excluded from server compilation. */
145
+ serverCompileExcludedFiles?: string[];
146
+ /** Information for entry points */
147
+ entrypoints: Entrypoint[];
148
+ /** Selected entry points */
149
+ checkedEntries: string[];
150
+ /** Information for server routes */
151
+ serverRoutes: ServerRoute[];
152
+ /** Whether to use api only mode */
153
+ apiOnly: boolean;
154
+ deployTarget: ResolvedDeployTarget;
155
+ _internalContext: InternalContext<Extends>;
156
+ /**
157
+ * Information for HTML templates by entry
158
+ * @private
159
+ */
160
+ partialsByEntrypoint?: Record<string, HtmlPartials>;
161
+ /**
162
+ * Information for HTML templates
163
+ * @private
164
+ */
165
+ htmlTemplates: HtmlTemplates;
166
+ /**
167
+ * @deprecated compat old plugin, default is app tools
168
+ */
169
+ toolsType?: string;
170
+ /**
171
+ * Identification for bff runtime framework
172
+ * @private
173
+ */
174
+ bffRuntimeFramework?: BffRuntimeFramework;
175
+ /**
176
+ * Route component files collected from the FINAL file-system routes (after all
177
+ * `modifyFileSystemRoutes` consumers ran), keyed by entry name. Populated by
178
+ * the router plugin during route generation and consumed (currently by stream
179
+ * SSR lazy compilation) to force route component chunks eager.
180
+ *
181
+ * Published via the app context (`api.updateAppContext`) by the router plugin,
182
+ * then read fresh when assembling the builder options and threaded into
183
+ * `BuilderOptions.eagerRouteComponentFilesByEntry`; the SSR builder plugin
184
+ * reads it from those options (not from the context directly).
185
+ * @private
186
+ */
187
+ eagerRouteComponentFilesByEntry?: EagerRouteComponentFilesByEntry;
188
+ }
@@ -1,188 +1,14 @@
1
- import type { AppContext, AsyncHook, InternalContext, PluginHook, PluginHookTap, TransformFunction } from '@modern-js/plugin';
2
- import type { Hooks } from '@modern-js/plugin/cli';
3
- import type { BffRuntimeFramework } from '@modern-js/plugin/server';
4
- import type { Entrypoint, HtmlPartials, HtmlTemplates, HttpMethodDecider, NestedRouteForCli, PageRoute, RouteLegacy, ServerPlugin, ServerRoute } from '@modern-js/types';
5
- import type { EagerRouteComponentFilesByEntry } from '@modern-js/utils';
6
- import type { EnvironmentConfig } from '@rsbuild/core';
7
- import type { getHookRunners } from '../compat/hooks.js';
8
- import type { AppTools } from './index.js';
9
- import type { AppToolsNormalizedConfig, AppToolsUserConfig } from './config/index.js';
10
- export interface BffCompilation {
11
- readonly appDirectory: string;
12
- readonly apiDirectory: string;
13
- readonly sourceDirectories: readonly string[];
14
- readonly outputDirectories: readonly string[];
15
- readonly distDirectory: string;
16
- readonly tsconfigPath?: string;
17
- readonly moduleType: AppToolsContext['moduleType'];
1
+ import type { AppContext, Hooks } from '@modern-js/plugin/cli';
2
+ import type { NestedRouteForCli, PageRoute } from '@modern-js/types/cli';
3
+ import type { AppTools, AppToolsNormalizedConfig, AppToolsUserConfig } from './config/index.js';
4
+ import type { AppToolsExtendAPIBase, AppToolsExtendContextBase, AppToolsExtendHooksBase, ModifyFileSystemRoutesFn as BaseModifyFileSystemRoutesFn } from './plugin-base.js';
5
+ export * from './plugin-base.js';
6
+ export type ModifyFileSystemRoutesFn = BaseModifyFileSystemRoutesFn<NestedRouteForCli | PageRoute>;
7
+ export interface AppToolsExtendAPI extends AppToolsExtendAPIBase<AppTools, NestedRouteForCli | PageRoute> {
18
8
  }
19
- export interface BffGeneration {
20
- readonly appDirectory: string;
21
- readonly apiDirectory: string;
22
- readonly lambdaDirectory: string;
23
- readonly existLambda: boolean;
24
- readonly apiFiles: readonly string[];
25
- readonly relativeDistPath: string;
26
- readonly prefix: string;
27
- readonly port?: number;
28
- readonly requestId: string;
29
- readonly requestCreator?: string;
30
- readonly httpMethodDecider?: HttpMethodDecider;
9
+ export interface AppToolsExtendHooks extends AppToolsExtendHooksBase<NestedRouteForCli | PageRoute> {
31
10
  }
32
- export interface BffClientArtifact {
33
- /** Canonical relative source path under generation.apiDirectory. */
34
- readonly sourcePath: string;
35
- readonly code: string;
36
- readonly declaration: string;
37
- }
38
- export interface BffClientArtifacts {
39
- readonly generation: BffGeneration;
40
- additionalArtifacts: BffClientArtifact[];
41
- }
42
- export interface BffGeneratedModule {
43
- readonly code: string;
44
- readonly declaration: string;
45
- }
46
- export interface BffGeneratedEntries {
47
- readonly generation: BffGeneration;
48
- plugin: BffGeneratedModule;
49
- runtime: BffGeneratedModule | null;
50
- /** Direct dependencies required by the emitted SDK modules. */
51
- packageDependencies: Record<string, string>;
52
- }
53
- export type BeforeBffCompileFn = (context: BffCompilation) => void | Promise<void>;
54
- export type AfterBffCompileFn = (context: BffCompilation) => void | Promise<void>;
55
- export type ModifyBffClientArtifactsFn = TransformFunction<BffClientArtifacts>;
56
- export type ModifyBffGeneratedEntriesFn = TransformFunction<BffGeneratedEntries>;
57
- export type AfterPrepareFn = () => Promise<void> | void;
58
- export type CheckEntryPointFn = TransformFunction<{
59
- path: string;
60
- entry: false | string;
61
- }>;
62
- export type ModifyEntrypointsFn = TransformFunction<{
63
- entrypoints: Entrypoint[];
64
- }>;
65
- export type ModifyBuilderEnvironmentsFn = TransformFunction<{
66
- environments: Record<string, EnvironmentConfig>;
67
- }>;
68
- export type ModifyFileSystemRoutesFn = TransformFunction<{
69
- entrypoint: Entrypoint;
70
- routes: RouteLegacy[] | (NestedRouteForCli | PageRoute)[];
71
- }>;
72
- export type DeplpoyFn = () => Promise<void> | void;
73
- export type GenerateEntryCodeFn = (params: {
74
- entrypoints: Entrypoint[];
75
- }) => Promise<void> | void;
76
- export type BeforeGenerateRoutesFn = TransformFunction<{
77
- entrypoint: Entrypoint;
78
- code: string;
79
- }>;
80
- export type BeforePrintInstructionsFn = TransformFunction<{
81
- instructions: string;
82
- }>;
83
- export type AddRuntimeExportsFn = () => Promise<void> | void;
84
- export interface AppToolsExtendAPI {
85
- onAfterPrepare: PluginHookTap<AfterPrepareFn>;
86
- deploy: PluginHookTap<DeplpoyFn>;
87
- checkEntryPoint: PluginHookTap<CheckEntryPointFn>;
88
- modifyEntrypoints: PluginHookTap<ModifyEntrypointsFn>;
89
- modifyBuilderEnvironments: PluginHookTap<ModifyBuilderEnvironmentsFn>;
90
- modifyFileSystemRoutes: PluginHookTap<ModifyFileSystemRoutesFn>;
91
- generateEntryCode: PluginHookTap<GenerateEntryCodeFn>;
92
- onBeforeGenerateRoutes: PluginHookTap<BeforeGenerateRoutesFn>;
93
- /**
94
- * @deprecated
95
- */
96
- onBeforePrintInstructions: PluginHookTap<BeforePrintInstructionsFn>;
97
- /**
98
- * @deprecated use getAppContext instead
99
- */
100
- useAppContext: () => AppToolsContext;
101
- /**
102
- * @deprecated use getConfig instead
103
- */
104
- useConfigContext: () => AppToolsUserConfig;
105
- /**
106
- * @deprecated use getNormalizedConfig instead
107
- */
108
- useResolvedConfigContext: () => AppToolsNormalizedConfig<AppToolsUserConfig>;
109
- /**
110
- * @deprecated use api.xx instead
111
- */
112
- useHookRunners: () => ReturnType<typeof getHookRunners>;
113
- }
114
- export interface AppToolsExtendHooks extends Record<string, PluginHook<(...args: any[]) => any>> {
115
- onBeforeBffCompile: AsyncHook<BeforeBffCompileFn>;
116
- onAfterBffCompile: AsyncHook<AfterBffCompileFn>;
117
- modifyBffClientArtifacts: AsyncHook<ModifyBffClientArtifactsFn>;
118
- modifyBffGeneratedEntries: AsyncHook<ModifyBffGeneratedEntriesFn>;
119
- onAfterPrepare: AsyncHook<AfterPrepareFn>;
120
- deploy: AsyncHook<DeplpoyFn>;
121
- checkEntryPoint: AsyncHook<CheckEntryPointFn>;
122
- modifyEntrypoints: AsyncHook<ModifyEntrypointsFn>;
123
- modifyBuilderEnvironments: AsyncHook<ModifyBuilderEnvironmentsFn>;
124
- modifyFileSystemRoutes: AsyncHook<ModifyFileSystemRoutesFn>;
125
- generateEntryCode: AsyncHook<GenerateEntryCodeFn>;
126
- onBeforeGenerateRoutes: AsyncHook<BeforeGenerateRoutesFn>;
127
- /**
128
- * @deprecated
129
- */
130
- onBeforePrintInstructions: AsyncHook<BeforePrintInstructionsFn>;
131
- }
132
- export interface AppToolsExtendContext {
133
- metaName: string;
134
- internalDirectory: string;
135
- sharedDirectory: string;
136
- internalDirAlias: string;
137
- internalSrcAlias: string;
138
- apiDirectory: string;
139
- lambdaDirectory: string;
140
- runtimeConfigFile: string;
141
- serverPlugins: ServerPlugin[];
142
- moduleType: 'module' | 'commonjs';
143
- /** Exact generated files excluded from server compilation. */
144
- serverCompileExcludedFiles?: string[];
145
- /** Information for entry points */
146
- entrypoints: Entrypoint[];
147
- /** Selected entry points */
148
- checkedEntries: string[];
149
- /** Information for server routes */
150
- serverRoutes: ServerRoute[];
151
- /** Whether to use api only mode */
152
- apiOnly: boolean;
153
- _internalContext: InternalContext<AppTools>;
154
- /**
155
- * Information for HTML templates by entry
156
- * @private
157
- */
158
- partialsByEntrypoint?: Record<string, HtmlPartials>;
159
- /**
160
- * Information for HTML templates
161
- * @private
162
- */
163
- htmlTemplates: HtmlTemplates;
164
- /**
165
- * @deprecated compat old plugin, default is app tools
166
- */
167
- toolsType?: string;
168
- /**
169
- * Identification for bff runtime framework
170
- * @private
171
- */
172
- bffRuntimeFramework?: BffRuntimeFramework;
173
- /**
174
- * Route component files collected from the FINAL file-system routes (after all
175
- * `modifyFileSystemRoutes` consumers ran), keyed by entry name. Populated by
176
- * the router plugin during route generation and consumed (currently by stream
177
- * SSR lazy compilation) to force route component chunks eager.
178
- *
179
- * Published via the app context (`api.updateAppContext`) by the router plugin,
180
- * then read fresh when assembling the builder options and threaded into
181
- * `BuilderOptions.eagerRouteComponentFilesByEntry`; the SSR builder plugin
182
- * reads it from those options (not from the context directly).
183
- * @private
184
- */
185
- eagerRouteComponentFilesByEntry?: EagerRouteComponentFilesByEntry;
11
+ export interface AppToolsExtendContext extends AppToolsExtendContextBase<AppTools> {
186
12
  }
187
13
  export type AppToolsContext = AppContext<AppTools> & AppToolsExtendContext;
188
14
  export type AppToolsHooks = Hooks<AppToolsUserConfig, AppToolsNormalizedConfig, {}, {}> & AppToolsExtendHooks;
@@ -13,7 +13,7 @@ export declare const initAppContext: ({ metaName, appDirectory, runtimeConfigFil
13
13
  tempDir?: string;
14
14
  }) => {
15
15
  runtimeConfigFile: string;
16
- ip: any;
16
+ ip: string | undefined;
17
17
  port: number;
18
18
  moduleType: any;
19
19
  apiDirectory: string;
@@ -28,5 +28,5 @@ export declare const initAppContext: ({ metaName, appDirectory, runtimeConfigFil
28
28
  apiOnly: boolean;
29
29
  internalDirAlias: string;
30
30
  internalSrcAlias: string;
31
- bffRuntimeFramework: "hono";
31
+ bffRuntimeFramework: keyof import("@modern-js/plugin/server").BffRuntimeRegistry;
32
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
 
@@ -51,7 +51,7 @@ the framework use the same Effect instance. Before setting
51
51
  `/effect-edge` or `/effect-client`, install the exact cohort:
52
52
 
53
53
  ```bash
54
- pnpm add effect@4.0.0-rc.112 @effect/opentelemetry@4.0.0-rc.112
54
+ pnpm add effect@4.0.0-rc.117 @effect/opentelemetry@4.0.0-rc.117
55
55
  ```
56
56
 
57
57
  The pin is exact because UltraModern ships Effect as one lockstep cohort. Apps
@@ -227,14 +227,10 @@ through `pnpm-workspace.yaml` overrides. For the current UltraModern cohort,
227
227
  generated apps use:
228
228
 
229
229
  ```yaml
230
- trustPolicyExclude:
231
- - 'effect@4.0.0-rc.112'
232
- - '@effect/opentelemetry@4.0.0-rc.112'
233
-
234
230
  overrides:
235
- '@effect/opentelemetry': 4.0.0-rc.112
236
- '@effect/vitest': 4.0.0-rc.112
237
- effect: 4.0.0-rc.112
231
+ '@effect/opentelemetry': 4.0.0-rc.117
232
+ '@effect/vitest': 4.0.0-rc.117
233
+ effect: 4.0.0-rc.117
238
234
  ```
239
235
 
240
236
  Do not add a different direct `effect` version in an app package. A mismatched
@@ -242,10 +238,7 @@ Effect prerelease can fail while building layers or HTTP middleware because runt
242
238
  services come from different package instances. The strict 24-hour release-age
243
239
  gate applies to installed packages; the current cohort has no Effect age
244
240
  exemption, and override-only `@effect/vitest` is not an installed approval
245
- target. `trustPolicyExclude` is a separate policy:
246
- its exact `effect` and `@effect/opentelemetry` exceptions cover their
247
- trusted-publisher to provenance metadata transition and are not release-age
248
- approvals.
241
+ target.
249
242
 
250
243
  ## Contract tests
251
244
 
@@ -5,6 +5,10 @@
5
5
  - **Type:** `boolean`
6
6
  - **Default:** `false`
7
7
 
8
+ :::warning Deprecated
9
+ `output.disableSvgr` is deprecated and will be removed in the next major version. Replace `output.disableSvgr: true` with [tools.svgr](/configure/app/tools/svgr.md) set to `false`; `output.disableSvgr: false` is the default behavior and can simply be removed. When both are set, `tools.svgr` wins.
10
+ :::
11
+
8
12
  Whether to transform SVGs into React components. If true, will treat all .svg files as assets.
9
13
 
10
14
  By default, when an SVG resource is referenced in a JS file, Modern.js will call SVGR to convert the SVG into a React component. If you are sure that all SVG resources in your project are not being used as React components, you can turn off this conversion by setting `disableSvgr` to true to improve build performance.
@@ -5,6 +5,10 @@
5
5
  - **Type:** `'url' | 'component'`
6
6
  - **Default:** `'url'`
7
7
 
8
+ :::warning Deprecated
9
+ `output.svgDefaultExport` is deprecated and will be removed in the next major version. Use `svgrOptions.exportType` of [tools.svgr](/configure/app/tools/svgr.md) instead: `'component'` maps to `exportType: 'default'`, `'url'` maps to `exportType: 'named'`. When both are set, `tools.svgr` wins.
10
+ :::
11
+
8
12
  `output.svgDefaultExport` is used to configure the default export type of SVG files.
9
13
 
10
14
  When `output.svgDefaultExport` is set to `url` , the default export of SVG files is the URL of the file. For example:
@@ -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
  :::
@@ -7,49 +7,78 @@
7
7
 
8
8
  ```js
9
9
  const defaultOptions = {
10
- lessOptions: {
11
- javascriptEnabled: true,
10
+ lessLoaderOptions: {
11
+ lessOptions: {
12
+ javascriptEnabled: true,
13
+ },
14
+ // CSS Source Map enabled by default in development environment
15
+ sourceMap: isDev,
12
16
  },
13
- // CSS Source Map enabled by default in development environment
14
- sourceMap: isDev,
15
17
  };
16
18
  ```
17
19
 
18
- You can modify the config of [less-loader](https://github.com/webpack-contrib/less-loader) via `tools.less`.
20
+ `tools.less` modifies the options of [@rsbuild/plugin-less](https://rsbuild.rs/plugins/list/plugin-less). It accepts the full plugin options:
21
+
22
+ | Option | Description |
23
+ | ------------------- | --------------------------------------------------------------------------------------------------- |
24
+ | `lessLoaderOptions` | Options passed to [less-loader](https://github.com/webpack-contrib/less-loader), object or function |
25
+ | `include` | Files handled by less-loader, defaults to `/\.less$/` |
26
+ | `exclude` | Files that less-loader should skip |
27
+ | `parallel` | Whether to compile Less modules in worker threads, defaults to `false` |
28
+
29
+ ### Modifying less-loader options
19
30
 
20
- ### Object Type
31
+ When `lessLoaderOptions` is an `Object`, it is merged with the default config through Object.assign in a shallow way. It should be noted that `lessOptions` is merged through deepMerge in a deep way. For example:
32
+
33
+ ```js
34
+ export default {
35
+ tools: {
36
+ less: {
37
+ lessLoaderOptions: {
38
+ lessOptions: {
39
+ javascriptEnabled: false,
40
+ },
41
+ },
42
+ },
43
+ },
44
+ };
45
+ ```
21
46
 
22
- When `tools.less` is configured as `Object` type, it is merged with the default config through Object.assign in a shallow way. It should be noted that `lessOptions` is merged through deepMerge in a deep way. For example:
47
+ When `lessLoaderOptions` is a `Function`, the default config is passed as the first parameter, which can be directly modified or returned as the final result. The second parameter provides some utility functions that can be called directly. For example:
23
48
 
24
49
  ```js
25
50
  export default {
26
51
  tools: {
27
52
  less: {
28
- lessOptions: {
29
- javascriptEnabled: false,
53
+ lessLoaderOptions(config) {
54
+ // Modify the config of lessOptions
55
+ config.lessOptions = {
56
+ javascriptEnabled: false,
57
+ };
30
58
  },
31
59
  },
32
60
  },
33
61
  };
34
62
  ```
35
63
 
36
- ### Function Type
64
+ ### Parallel compilation
37
65
 
38
- When `tools.less` is a Function, the default config is passed as the first parameter, which can be directly modified or returned as the final result. The second parameter provides some utility functions that can be called directly. For example:
66
+ Less compilation is pure JavaScript and runs on the Node.js main thread by default. With `parallel` enabled, Less modules are compiled in a pool of worker threads, which shortens the build when a project has many Less files.
39
67
 
40
68
  ```js
41
69
  export default {
42
70
  tools: {
43
- less(config) {
44
- // Modify the config of lessOptions
45
- config.lessOptions = {
46
- javascriptEnabled: false,
47
- };
71
+ less: {
72
+ parallel: true,
48
73
  },
49
74
  },
50
75
  };
51
76
  ```
52
77
 
78
+ :::tip
79
+ Options sent to worker threads must satisfy the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm). With `parallel` enabled, `lessLoaderOptions` therefore cannot contain functions, such as an `additionalData` function or a custom `implementation`.
80
+ :::
81
+
53
82
  ### Modifying Less Version
54
83
 
55
84
  In some scenarios, if you need to use a specific version of Less instead of the built-in Less v4 in Modern.js, you can install the desired Less version in your project and set it up using the `implementation` option of the `less-loader`.
@@ -58,7 +87,9 @@ In some scenarios, if you need to use a specific version of Less instead of the
58
87
  export default {
59
88
  tools: {
60
89
  less: {
61
- implementation: require('less'),
90
+ lessLoaderOptions: {
91
+ implementation: require('less'),
92
+ },
62
93
  },
63
94
  },
64
95
  };
@@ -75,8 +106,52 @@ Used to specify which files `less-loader` does not compile, You can pass in one
75
106
  ```js
76
107
  export default {
77
108
  tools: {
78
- less(config, { addExcludes }) {
79
- addExcludes(/node_modules/);
109
+ less: {
110
+ lessLoaderOptions(config, { addExcludes }) {
111
+ addExcludes(/node_modules/);
112
+ },
113
+ },
114
+ },
115
+ };
116
+ ```
117
+
118
+ The plugin's `exclude` option is the recommended equivalent:
119
+
120
+ ```js
121
+ export default {
122
+ tools: {
123
+ less: {
124
+ exclude: /node_modules/,
125
+ },
126
+ },
127
+ };
128
+ ```
129
+
130
+ ### Legacy form
131
+
132
+ :::warning Do not mix the two layers
133
+ As soon as an object contains a plugin-level key (`lessLoaderOptions`, `include`, `exclude`, ...), the whole object is parsed as plugin options and any loader option in it has no effect. For example, `lessOptions` in `tools.less: { parallel: true, lessOptions: { ... } }` is ignored and must be moved under `lessLoaderOptions`; a hint is printed in development.
134
+ :::
135
+
136
+ In earlier versions, `tools.less` took the less-loader options directly, e.g. `tools.less: { lessOptions: {} }` or `tools.less(config, { addExcludes }) {}`. This form still works: Modern.js wraps it into `lessLoaderOptions` and produces exactly the same config as before. A migration hint is printed in development, and the legacy form will be removed in the next major version.
137
+
138
+ ```js
139
+ // legacy
140
+ export default {
141
+ tools: {
142
+ less: {
143
+ lessOptions: { javascriptEnabled: false },
144
+ },
145
+ },
146
+ };
147
+
148
+ // current
149
+ export default {
150
+ tools: {
151
+ less: {
152
+ lessLoaderOptions: {
153
+ lessOptions: { javascriptEnabled: false },
154
+ },
80
155
  },
81
156
  },
82
157
  };