@bleedingdev/modern-js-app-tools 3.9.0-ultramodern.2 → 3.9.0-ultramodern.21
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
|
@@ -37,7 +37,7 @@ export interface CacheControl {
|
|
|
37
37
|
}
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
Here, `customKey` is the custom cache key. By default,
|
|
40
|
+
Here, `customKey` is the custom cache key. By default, the cache key is derived from the request's origin, normalized pathname (trailing slash removed), and query string. When `customKey` is set, it fully replaces the default key: the `customKey` callback receives the normalized pathname (not the `CacheOptionProvider`'s `req`) and is responsible for the whole partition (e.g. by tenant, host, or query) — it must not embed raw cookies or other credentials into the returned key.
|
|
41
41
|
|
|
42
42
|
**Function Type**
|
|
43
43
|
|
|
@@ -108,6 +108,19 @@ export const cacheOption: CacheOption = {
|
|
|
108
108
|
|
|
109
109
|
The above `/home` and `/about` are patterns, meaning `/home/abc` will also match. You can use regex in these patterns, such as `/home/.+`.
|
|
110
110
|
|
|
111
|
+
### Cache Policy
|
|
112
|
+
|
|
113
|
+
The following policy is enforced automatically and cannot be overridden by the returned `CacheControl`:
|
|
114
|
+
|
|
115
|
+
- Only `GET` requests are cached.
|
|
116
|
+
- A request carrying a `Cookie` or `Authorization` header skips the cache unless `customKey` is set, since a custom key is treated as an explicit partitioning contract.
|
|
117
|
+
- A request with `Cache-Control: private`, `no-cache`, or `no-store` skips the cache.
|
|
118
|
+
- A response is only stored when it is `200`, has no `private`/`no-cache`/`no-store` in `Cache-Control`, has no `Set-Cookie`, and has no nonempty `Vary` header; otherwise any existing cache entry for that key is deleted instead of being written.
|
|
119
|
+
- If a `stale` revalidation produces a response that is no longer cacheable (for example, it became per-user), that already-served stale response is unaffected, but the cache entry is evicted so subsequent requests no longer hit it.
|
|
120
|
+
- A `CacheOptionProvider` returning `false` still disables caching entirely for that request, independent of the policy above.
|
|
121
|
+
|
|
122
|
+
Cache keys are namespaced (`__ssr__cache:v2:...`). Older un-namespaced entries — including ones already stored in a custom `Container` — are never read back; they simply age out under the container's own eviction/TTL. There is no global cache flush.
|
|
123
|
+
|
|
111
124
|
### Cache Container
|
|
112
125
|
|
|
113
126
|
By default, the server uses memory for caching. Typically, services are deployed in a Serverless container, creating a new process for each access, making it impossible to use the previous cache.
|
|
@@ -40,7 +40,7 @@ Additionally, after installing nvm or fnm, when there is a `.nvmrc` file contain
|
|
|
40
40
|
It is recommended to use [pnpm](https://pnpm.io/installation) to manage dependencies:
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
mise use pnpm@11.
|
|
43
|
+
mise use pnpm@11.27.1
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
:::note
|
|
@@ -125,11 +125,7 @@ Now, the project structure is as follows:
|
|
|
125
125
|
```
|
|
126
126
|
|
|
127
127
|
The default workspace starts shell-only and installs the published BleedingDev
|
|
128
|
-
package aliases
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
pnpm dlx @bleedingdev/modern-js-ultramodern-create my-super-app
|
|
132
|
-
```
|
|
128
|
+
package aliases.
|
|
133
129
|
|
|
134
130
|
From a generated SuperApp workspace, add a business MicroVertical in place:
|
|
135
131
|
|
|
@@ -15,17 +15,9 @@ UltraModern.js 3.0 is our SuperApp framework forked from Modern.js. It keeps the
|
|
|
15
15
|
- Add platform-level contracts only where they improve cross-team reliability.
|
|
16
16
|
- Keep escape hatches explicit and outside the generated HTTP API path.
|
|
17
17
|
|
|
18
|
-
##
|
|
18
|
+
## Current Workspace Contract
|
|
19
19
|
|
|
20
|
-
UltraModern.js
|
|
21
|
-
|
|
22
|
-
- Modern.js app/config/plugin mental model.
|
|
23
|
-
- Existing project structure and command flow.
|
|
24
|
-
- Progressive adoption path (apps can stay mostly unchanged).
|
|
25
|
-
|
|
26
|
-
UltraModern.js additions are designed as the default product surface for new SuperApps. The framework direction is Effect + TanStack + SSR + Micro Verticals, and generated HTTP API work uses that direction by default instead of preserving parallel raw-handler layouts.
|
|
27
|
-
Existing Modern.js apps can migrate gradually; once an API surface is generated
|
|
28
|
-
or migrated as UltraModern HTTP API, it must use the strict Effect HttpApi path.
|
|
20
|
+
UltraModern.js uses Effect HttpApi, TanStack Router, SSR, and independently deployable Micro Verticals. Generated workspaces use `api/index.ts`, `shared/api.ts`, and `src/api/*` with concrete Effect schemas. The CLI creates, adds to, and validates workspaces against the current contract.
|
|
29
21
|
|
|
30
22
|
## Intentional Differences (v3 line)
|
|
31
23
|
|
|
@@ -53,21 +45,9 @@ or migrated as UltraModern HTTP API, it must use the strict Effect HttpApi path.
|
|
|
53
45
|
- Generated UltraModern API work uses the Effect runtime only; raw Hono/function handlers are not part of the generated API architecture.
|
|
54
46
|
- We make incompatible scaffold changes when they remove architecture drift.
|
|
55
47
|
|
|
56
|
-
##
|
|
57
|
-
|
|
58
|
-
For teams already on Modern.js 3.0 or an older BleedingDev UltraModern scaffold, the adoption path is to move API work onto the strict Effect HttpApi surface instead of preserving older raw handler layouts.
|
|
59
|
-
|
|
60
|
-
1. Keep existing Modern.js apps running as-is while they are outside the generated UltraModern surface. TanStack Router is the preferred path for new scaffolds and incremental route adoption, but route migration can happen on the team's schedule.
|
|
61
|
-
2. Use `bff.runtimeFramework: 'effect'` with `bff.effect.strictEffectApproach: true` for API work. Entries live at `api/index.ts`, contracts live at `shared/api.ts`, clients live under `src/api/*`, and request/response/error shapes come from Effect `Schema` plus `HttpApi`.
|
|
62
|
-
3. Treat raw handlers, `api/lambda/**`, manual `Response` construction, and manual request parsing as migration defects in generated or migrated UltraModern workspaces.
|
|
63
|
-
4. The public preset now ships with explicit release and certification gates. Generated workspaces include `.github/workflows/ultramodern-workspace-gates.yml`, so `pnpm check` and `pnpm build` stay part of the local adoption contract from day one while CI runs the primitive gates as parallel matrix jobs.
|
|
64
|
-
|
|
65
|
-
For an older generated workspace, migrate by treating the published cohort as
|
|
66
|
-
the source of truth:
|
|
48
|
+
## Create and Validate a Workspace
|
|
67
49
|
|
|
68
50
|
```bash
|
|
69
|
-
pnpm dlx @bleedingdev/modern-js-ultramodern-create@latest --help
|
|
70
|
-
pnpm dlx @bleedingdev/modern-js-ultramodern-create@latest catalog --vertical --dry-run
|
|
71
51
|
pnpm dlx @bleedingdev/modern-js-ultramodern-create@latest catalog --vertical
|
|
72
52
|
mise install
|
|
73
53
|
mise exec -- pnpm install
|
|
@@ -75,94 +55,31 @@ mise exec -- pnpm check
|
|
|
75
55
|
mise exec -- pnpm build
|
|
76
56
|
```
|
|
77
57
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
Current cohorts localize Cloudflare SSR workspaces.
|
|
81
|
-
The framework moves bare locale-root redirects into the framework-owned
|
|
82
|
-
Cloudflare Worker entry and the i18n server runtime. A request for `/` is
|
|
83
|
-
redirected server-side with `302` to the negotiated locale path, for example
|
|
84
|
-
`/cs` for `Accept-Language: cs-CZ` or `/en` for English and fallback traffic.
|
|
85
|
-
|
|
86
|
-
Existing generated workspaces should upgrade the whole BleedingDev Modern
|
|
87
|
-
package cohort together. Resolve the current cohort version first, then run
|
|
88
|
-
the matching migration:
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
COHORT="$(npm view @bleedingdev/modern-js-ultramodern-create version)"
|
|
92
|
-
pnpm dlx "@bleedingdev/modern-js-ultramodern-create@$COHORT" ultramodern \
|
|
93
|
-
migrate-strict-effect --version "$COHORT"
|
|
94
|
-
pnpm install
|
|
95
|
-
pnpm check
|
|
96
|
-
pnpm build
|
|
97
|
-
pnpm cloudflare:build
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
For deployed Cloudflare Workers, redeploy after the cohort update and verify
|
|
101
|
-
the root response before accepting the migration:
|
|
58
|
+
Localized Cloudflare SSR workspaces redirect `/` on the server to the negotiated locale. For example, `Accept-Language: cs-CZ` returns `302` with `Location: /cs`, `Cache-Control: private, no-store`, and `Vary` covering locale detection headers. Validate the deployed Worker with:
|
|
102
59
|
|
|
103
60
|
```bash
|
|
104
61
|
curl -I -H 'Accept-Language: cs-CZ,cs;q=0.9,en;q=0.1' https://<worker-host>/
|
|
105
62
|
```
|
|
106
63
|
|
|
107
|
-
The expected response is `302` with `Location: /cs` or the matching locale,
|
|
108
|
-
`Cache-Control: private, no-store`, and `Vary` covering the locale detection
|
|
109
|
-
headers. Following the redirect should return the SSR locale page with the
|
|
110
|
-
matching document language and i18n SSR data.
|
|
111
|
-
|
|
112
|
-
Do not fix older root `404` responses by adding app-owned root route files,
|
|
113
|
-
client-side redirects, custom navigation wrappers, Cloudflare Worker
|
|
114
|
-
postprocessing, generated output edits, or local redirect shims. If `/` still
|
|
115
|
-
returns `404` after upgrading, confirm the production build log shows
|
|
116
|
-
`Modern.js Framework v<cohort-version>` for the cohort you migrated to and
|
|
117
|
-
redeploy the Worker.
|
|
118
|
-
|
|
119
|
-
Strict generated API migration is part of every current cohort: the direct
|
|
120
|
-
`api/index.ts` generator, generated `.mts` checks, the strict Oxlint boundary
|
|
121
|
-
rule set, Effect cohort overrides, and the strict Effect migration command.
|
|
122
|
-
Agents that cannot install the BleedingDev cohort yet should use the local
|
|
123
|
-
Modern.js workspace for migration validation; otherwise pin the target cohort
|
|
124
|
-
with `--ultramodern-package-version`.
|
|
125
|
-
|
|
126
|
-
Before hand-editing package aliases or generated metadata, run the framework
|
|
127
|
-
migration command from the target workspace:
|
|
128
|
-
|
|
129
|
-
```bash
|
|
130
|
-
COHORT="$(npm view @bleedingdev/modern-js-ultramodern-create version)"
|
|
131
|
-
pnpm dlx "@bleedingdev/modern-js-ultramodern-create@$COHORT" ultramodern \
|
|
132
|
-
migrate-strict-effect --version "$COHORT"
|
|
133
|
-
pnpm api:check
|
|
134
|
-
pnpm contract:check
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
The command updates `.modernjs/ultramodern.json`, root
|
|
138
|
-
`modernjs.packageSource`, generated Modern package aliases, framework-owned
|
|
139
|
-
toolchain pins, direct topology API metadata, strict Effect pnpm
|
|
140
|
-
overrides/trust policy, and the pnpm lockfile. Remaining failures are source
|
|
141
|
-
migration work: move code to `shared/api.ts`, `api/index.ts`, and
|
|
142
|
-
`src/api/*-client.ts`, then delete `api/effect`, `api/lambda`, `shared/effect`,
|
|
143
|
-
and `src/effect`.
|
|
144
|
-
|
|
145
64
|
Generated strict Effect workspaces pin the compatible Effect cohort with pnpm
|
|
146
|
-
overrides: `effect@4.0.0-rc.
|
|
147
|
-
and `@effect/vitest@4.0.0-rc.
|
|
65
|
+
overrides: `effect@4.0.0-rc.117`, `@effect/opentelemetry@4.0.0-rc.117`,
|
|
66
|
+
and `@effect/vitest@4.0.0-rc.117`. Do not add app-local direct Effect
|
|
148
67
|
versions that disagree with those overrides. The strict 24-hour release-age
|
|
149
68
|
gate applies to installed packages; this cohort carries no Effect age
|
|
150
69
|
exemption, and override-only `@effect/vitest` is not an installed approval
|
|
151
|
-
target.
|
|
152
|
-
and `@effect/opentelemetry` cover their trusted-publisher to provenance
|
|
153
|
-
metadata transition; they are not release-age approvals.
|
|
70
|
+
target.
|
|
154
71
|
|
|
155
72
|
### Current generated dependency baseline
|
|
156
73
|
|
|
157
74
|
| Surface | Pin |
|
|
158
75
|
| ------------------------------ | --------------------------------------------------------------------------------------------------- |
|
|
159
|
-
| Effect runtime and test cohort | `effect`, `@effect/opentelemetry`, and `@effect/vitest`: `4.0.0-rc.
|
|
160
|
-
| Effect compiler | `@effect/tsgo@0.
|
|
161
|
-
| Oxc and Ultracite | `oxlint@1.
|
|
162
|
-
| TanStack Router | `@tanstack/react-router@1.170.
|
|
163
|
-
| Module Federation | `bridge-react`, `manifest`, `modern-js-v3`, and `rspack`: `2.9.
|
|
76
|
+
| Effect runtime and test cohort | `effect`, `@effect/opentelemetry`, and `@effect/vitest`: `4.0.0-rc.117` |
|
|
77
|
+
| Effect compiler | `@effect/tsgo@0.45.0` |
|
|
78
|
+
| Oxc and Ultracite | `oxlint@1.85.0`, `oxfmt@0.70.0`, `ultracite@7.12.0` |
|
|
79
|
+
| TanStack Router | `@tanstack/react-router@1.170.39`, `@tanstack/router-core@1.171.32`, `@tanstack/history@1.162.4` |
|
|
80
|
+
| Module Federation | `bridge-react`, `manifest`, `modern-js-v3`, and `rspack`: `2.9.2`; `@module-federation/node@2.7.52` |
|
|
164
81
|
| Tailwind CSS | `tailwindcss@4.3.3` |
|
|
165
|
-
| Node and package tooling | Node `26.7.0`, `@types/node@^26.
|
|
82
|
+
| Node and package tooling | Node `26.7.0`, `@types/node@^26.6.2`, pnpm `11.27.1` |
|
|
166
83
|
|
|
167
84
|
Generated workspaces default to Module Federation bridge-react's router-free
|
|
168
85
|
base entry (`bridge.enableBridgeRouter: false`), with TanStack Router as the
|
|
@@ -210,7 +127,7 @@ transport surfaces when needed. They do not make raw request handlers valid
|
|
|
210
127
|
inside generated HTTP API modules.
|
|
211
128
|
|
|
212
129
|
Strict API tests should exercise the `HttpApi` contract. Use
|
|
213
|
-
`createEffectBffTestHandler` from `@modern-js/
|
|
130
|
+
`createEffectBffTestHandler` from `@modern-js/bff-effect/effect-edge` for
|
|
214
131
|
edge-compatible proof tests; if you manually compose a web handler, provide
|
|
215
132
|
`HttpServer.layerServices` beside your API group layer before calling
|
|
216
133
|
`HttpRouter.toWebHandler`.
|
package/docs/llms.txt
CHANGED
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
- [Deploy Application](/guides/basic-features/deploy.md): Currently, Modern.js offers two deployment way: You can host your application in a container that includes a Node.js environment on your own, which provides flexibility for the deployment of the application.You can also deploy your application through a platform. Currently, Modern.js officially supports deployment on Netlify, Vercel, and Github pages.
|
|
48
48
|
- [BFF](/guides/advanced-features/bff.md): BFF (Backends for Frontends) is an architectural pattern primarily used to address issues of data aggregation in front-end and back-end collaboration. Under the BFF architecture, front-end applications do not communicate directly with backend services. Instead, they interact with backend services through a dedicated BFF middleware layer, custom-made for the front end. The main problems it tries to solve include: Aggregation, mapping, clipping, and proxying of lower-level APIs according to their own business needs.Cache data for some specific scenarios to improve performance and thus improve user experience.Quickly development of new products based on existing interfaces.Interface with third-party systems, such as login authentication. Modern.js officially supported the BFF and provided the Integrated BFF to further strengthen the BFF's capabilities, mainly including the following capabilities: Quick development and debugging go live, running, building, and deploying BFF code in the same project.Minimal pure function call, directly import BFF function on the front end, and can be automatically converted into HTTP request when called.No private protocol, follow RESTful API specification, all BFF interfaces are standardized.Full TypeScript support.Meet user preferences and support multi-frame extension writing.
|
|
49
49
|
- [Basic Usage](/guides/advanced-features/bff/function.md): In a Modern.js application, developers can define API files under the api/lambda directory and export API functions from these files. In the frontend code, these API functions can be directly invoked by importing the file, which initiates the API requests. This invocation method is called unified invocation, where developers do not need to write glue code for the frontend and backend separately, thereby ensuring type safety across both.
|
|
50
|
-
- [Runtime Framework](/guides/advanced-features/bff/frameworks.md): Modern.js
|
|
50
|
+
- [Runtime Framework](/guides/advanced-features/bff/frameworks.md): Modern.js and the UltraModern BFF extension provide two runtime frameworks: hono is the native plugin default and uses file-convention handlers from api/lambda/**.effect is the UltraModern extension default and uses Effect HttpApi from api/index. effect and hono are strict runtime modes. There is no automatic fallback between them. ::::info Generated UltraModern workspaces use strict Effect APIs: author HTTP APIs in shared/api.ts and api/index.ts, not Hono/file-convention handlers. ::::
|
|
51
51
|
- [Data Platform](/guides/advanced-features/bff/data-platform.md): Modern.js Effect API runtime now supports a request-envelope based data platform contract for safer and more predictable data orchestration in complex applications such as Module Federation and micro frontends.
|
|
52
52
|
- [Creating Extensible BFF Functions](/guides/advanced-features/bff/operators.md): The previous section showed how to export a simple BFF function in a file. In more complex scenarios, each BFF function may need to do independent type validation, pre-logic, etc. Therefore, Modern.js exposes Api, which supports creating BFF functions through this API. BFF functions created in this way can be easily extended with functionality.
|
|
53
53
|
- [Extend BFF Server](/guides/advanced-features/bff/extend-server.md): In some applications, developers may want to handle all BFF functions uniformly, such as authentication, logging, data processing, etc. Modern.js allows users to freely extend the BFF Server through Middleware method.
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
- [watchFiles](/configure/app/dev/watch-files.md): Type: Default: undefined Watch specified files and directories for changes. When a file change is detected, it can trigger a page reload or restart the dev server.
|
|
112
112
|
- [writeToDisk](/configure/app/dev/write-to-disk.md): Type: boolean | ((filename: string) => boolean)Default: (file) => !file.includes('.hot-update.') Controls whether the build output from development mode is written to disk.
|
|
113
113
|
- [crossProject](/configure/app/bff/cross-project.md): Type: booleanDefault: false This configuration is used to enable BFF cross-project invocation functionality. When enabled, the current project can be used as a BFF producer, generating an SDK that can be directly called by other projects. For detailed configuration and usage of BFF cross-project invocation, please refer to the BFF Cross-Project Invocation Guide.
|
|
114
|
-
- [effect](/configure/app/bff/effect.md): Type: Default: {} bff.effect is only effective when bff.runtimeFramework is set to 'effect'. Generated UltraModern workspaces use this runtime as the only generated HTTP API path. The API contract lives at shared/api.ts, the server runtime lives at api/index.ts, clients live under src/api/*-client.ts, and generated checks reject api/effect, api/lambda, shared/effect, src/effect, Hono server imports, raw request handlers, manual request parsing, and manual Response construction in API modules. For Effect v4, TypeScript should use export-map aware module resolution.
|
|
114
|
+
- [effect](/configure/app/bff/effect.md): Type: Default: {} bff.effect is only effective when bff.runtimeFramework is set to 'effect'. Use bffPlugin from @modern-js/plugin-bff-build-extensions to register the Effect runtime. It composes the native BFF plugin. Install @modern-js/bff-effect and @modern-js/plugin-bff-extensions from the same framework cohort as application production dependencies, so the adapter remains available after development dependencies are removed. The build plugin can be a development dependency. See the runtime configuration example. Native @modern-js/plugin-bff/server exports Hono APIs. For Node Effect APIs, import framework helpers such as defineEffectBff from @modern-js/bff-effect/effect and namespaces from the corresponding effect/* modules. Worker handlers and worker request context use @modern-js/bff-effect/effect-edge. Generated UltraModern workspaces use this runtime as the only generated HTTP API path. The API contract lives at shared/api.ts, the server runtime lives at api/index.ts, clients live under src/api/*-client.ts, and generated checks reject api/effect, api/lambda, shared/effect, src/effect, Hono server imports, raw request handlers, manual request parsing, and manual Response construction in API modules. For Effect v4, TypeScript should use export-map aware module resolution.
|
|
115
115
|
- [prefix](/configure/app/bff/prefix.md): Type: stringDefault: /api By default, the prefix for accessing routes in the BFF API directory is /api, as shown in the following directory structure: The route corresponding to api/hello.ts when accessed is localhost:8080/api/hello. This configuration option can modify the default route prefix: The corresponding route for api/hello.ts when accessed is localhost:8080/api-demo/hello.
|
|
116
116
|
- [runtimeFramework](/configure/app/bff/runtime-framework.md): Type: 'hono' | 'effect'Default: 'effect' Controls which runtime framework Modern.js uses for BFF routing. Set to 'effect' to run BFF only from api/index (Effect HttpApi runtime).Set to 'hono' to run BFF only from file-convention handlers under api/lambda/**. There is no implicit fallback between runtimes. Choose one runtime mode per app. Generated UltraModern apps use strict Effect APIs by default and set bff.effect.strictEffectApproach: true; hono and api/lambda/** are not valid generated UltraModern HTTP API paths.
|
|
117
117
|
- [appIcon](/configure/app/html/app-icon.md): Type: Default: undefined Set the web application icons to display when added to the home screen of a mobile device: Generate the web app manifest file and its icons field.Generate the apple-touch-icon and manifest tags in the HTML file.
|
|
@@ -156,7 +156,7 @@
|
|
|
156
156
|
- [include](/configure/app/source/include.md): Type: RuleSetCondition[]Default value: source.include is used to specify additional JavaScript files that need to be compiled. By default, the following files will be compiled: TypeScript and JSX files in any directory, with file extensions matching .ts, .tsx, .jsx, .mts, .cts.JavaScript files not in the node_modules directory, with file extensions matching .js, .mjs, .cjs.
|
|
157
157
|
- [mainEntryName](/configure/app/source/main-entry-name.md): Type: stringDefault: 'index' This option is used to configure the main entry name of Modern.js. By default, the default main entry name of Modern.js is index. When using a single entry or the entry name is the same as the name field in package.json, the corresponding entry will be used as the main entry. This configuration can be used to modify the name of the main entry. For example, change the main entry name to main: After building, the corresponding HTML output path will be changed to dist/html/index/index.html.
|
|
158
158
|
- [preEntry](/configure/app/source/pre-entry.md): Type: string | string[]Default: [] Add a script before the entry file of each page. This script will be executed before the page code. It can be used to execute global logics, such as injecting polyfills, setting global styles, etc.
|
|
159
|
-
- [reactCompiler](/configure/app/source/react-compiler.md): Type: boolean | ReactCompilerOptionsDefault: undefined (disabled) Whether to enable React Compiler. React Compiler is a build-time tool that optimizes re-rendering performance of React applications through automatic memoization. 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.
|
|
159
|
+
- [reactCompiler](/configure/app/source/react-compiler.md): Type: boolean | ReactCompilerOptionsDefault: undefined (disabled) Whether to enable React Compiler. React Compiler is a build-time tool that optimizes re-rendering performance of React applications through automatic memoization. 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. 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.
|
|
160
160
|
- [transformImport](/configure/app/source/transform-import.md): Transform the import path, which can be used to modularly import the subpath of third-party packages. The functionality is similar to babel-plugin-import。 Type: Default: undefined
|
|
161
161
|
- [aliasStrategy](/configure/app/resolve/alias-strategy.md): Type: 'prefer-tsconfig' | 'prefer-alias'Default: 'prefer-tsconfig' Set the strategy for path alias resolution, to control the priority relationship between the paths option in tsconfig.json and the resolve.alias option of Rsbuild.
|
|
162
162
|
- [alias](/configure/app/resolve/alias.md): Type: string[] Create aliases for module paths to simplify import paths or redirect module references.
|
|
@@ -191,6 +191,7 @@ Adds additional logic when the server resets.
|
|
|
191
191
|
- `'file-change'`: File change event
|
|
192
192
|
- `event.payload`: When `type` is `'file-change'`, contains an array of file change information.
|
|
193
193
|
- **Execution Phase:** When files change or repack is needed.
|
|
194
|
+
- **Repack Order:** On `'repack'` the dev server awaits the handlers in registration order before it purges the previous server bundle from the require cache. A rejecting handler skips the handlers after it. New requests wait until the handlers settle; requests already running keep the modules they loaded. A repack handler must not await a request to the dev server, because that request waits for the handler.
|
|
194
195
|
- **Example:**
|
|
195
196
|
|
|
196
197
|
```typescript
|
package/package.json
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"modern",
|
|
18
18
|
"modern.js"
|
|
19
19
|
],
|
|
20
|
-
"version": "3.9.0-ultramodern.
|
|
20
|
+
"version": "3.9.0-ultramodern.21",
|
|
21
21
|
"types": "./dist/types/index.d.ts",
|
|
22
22
|
"main": "./dist/cjs/index.js",
|
|
23
23
|
"exports": {
|
|
@@ -37,12 +37,6 @@
|
|
|
37
37
|
},
|
|
38
38
|
"default": "./dist/cjs/builder/index.js"
|
|
39
39
|
},
|
|
40
|
-
"./config": {
|
|
41
|
-
"types": "./dist/types/config/public.d.ts",
|
|
42
|
-
"import": "./dist/esm-node/config/public.mjs",
|
|
43
|
-
"require": "./dist/cjs/config/public.js",
|
|
44
|
-
"default": "./dist/cjs/config/public.js"
|
|
45
|
-
},
|
|
46
40
|
"./cli": {
|
|
47
41
|
"types": "./dist/types/index.d.ts",
|
|
48
42
|
"node": {
|
|
@@ -59,11 +53,10 @@
|
|
|
59
53
|
},
|
|
60
54
|
"default": "./dist/cjs/run/index.js"
|
|
61
55
|
},
|
|
62
|
-
"./
|
|
63
|
-
"types": "./dist/types/
|
|
64
|
-
"import": "./dist/esm-node/
|
|
65
|
-
"require": "./dist/cjs/
|
|
66
|
-
"default": "./dist/cjs/plugins/deploy/platforms/cloudflare-output-verifier/index.js"
|
|
56
|
+
"./server-plugin": {
|
|
57
|
+
"types": "./dist/types/server-plugin.d.ts",
|
|
58
|
+
"import": "./dist/esm-node/server-plugin.mjs",
|
|
59
|
+
"require": "./dist/cjs/server-plugin.js"
|
|
67
60
|
},
|
|
68
61
|
"./types": {
|
|
69
62
|
"types": "./lib/types.d.ts",
|
|
@@ -85,15 +78,15 @@
|
|
|
85
78
|
"cli/run": [
|
|
86
79
|
"./dist/types/run/index.d.ts"
|
|
87
80
|
],
|
|
81
|
+
"server-plugin": [
|
|
82
|
+
"./dist/types/server-plugin.d.ts"
|
|
83
|
+
],
|
|
88
84
|
"types": [
|
|
89
85
|
"./lib/types.d.ts"
|
|
90
86
|
],
|
|
91
87
|
"builder": [
|
|
92
88
|
"./dist/types/builder/index.d.ts"
|
|
93
89
|
],
|
|
94
|
-
"config": [
|
|
95
|
-
"./dist/types/config/public.d.ts"
|
|
96
|
-
],
|
|
97
90
|
"bundle-docs": [
|
|
98
91
|
"./dist/types/bundleDocs.d.ts"
|
|
99
92
|
]
|
|
@@ -130,23 +123,23 @@
|
|
|
130
123
|
}
|
|
131
124
|
},
|
|
132
125
|
"dependencies": {
|
|
133
|
-
"@babel/parser": "^8.0.
|
|
134
|
-
"@babel/traverse": "^8.0.
|
|
135
|
-
"@babel/types": "^8.0.
|
|
126
|
+
"@babel/parser": "^8.0.6",
|
|
127
|
+
"@babel/traverse": "^8.0.6",
|
|
128
|
+
"@babel/types": "^8.0.6",
|
|
136
129
|
"@loadable/component": "5.16.7",
|
|
137
|
-
"@modern-js/app-tools-extensions": "npm:@bleedingdev/modern-js-app-tools-extensions@3.9.0-ultramodern.
|
|
138
|
-
"@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.
|
|
139
|
-
"@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.9.0-ultramodern.
|
|
140
|
-
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.0-ultramodern.
|
|
141
|
-
"@modern-js/plugin-data-loader": "npm:@bleedingdev/modern-js-plugin-data-loader@3.9.0-ultramodern.
|
|
142
|
-
"@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.0-ultramodern.
|
|
143
|
-
"@modern-js/server": "npm:@bleedingdev/modern-js-server@3.9.0-ultramodern.
|
|
144
|
-
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.
|
|
145
|
-
"@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.0-ultramodern.
|
|
146
|
-
"@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.9.0-ultramodern.
|
|
147
|
-
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.
|
|
148
|
-
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.
|
|
149
|
-
"@rsbuild/core": "2.2.
|
|
130
|
+
"@modern-js/app-tools-extensions": "npm:@bleedingdev/modern-js-app-tools-extensions@3.9.0-ultramodern.21",
|
|
131
|
+
"@modern-js/builder": "npm:@bleedingdev/modern-js-builder@3.9.0-ultramodern.21",
|
|
132
|
+
"@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.9.0-ultramodern.21",
|
|
133
|
+
"@modern-js/plugin": "npm:@bleedingdev/modern-js-plugin@3.9.0-ultramodern.21",
|
|
134
|
+
"@modern-js/plugin-data-loader": "npm:@bleedingdev/modern-js-plugin-data-loader@3.9.0-ultramodern.21",
|
|
135
|
+
"@modern-js/prod-server": "npm:@bleedingdev/modern-js-prod-server@3.9.0-ultramodern.21",
|
|
136
|
+
"@modern-js/server": "npm:@bleedingdev/modern-js-server@3.9.0-ultramodern.21",
|
|
137
|
+
"@modern-js/server-core": "npm:@bleedingdev/modern-js-server-core@3.9.0-ultramodern.21",
|
|
138
|
+
"@modern-js/server-runtime-extensions": "npm:@bleedingdev/modern-js-server-runtime-extensions@3.9.0-ultramodern.21",
|
|
139
|
+
"@modern-js/server-utils": "npm:@bleedingdev/modern-js-server-utils@3.9.0-ultramodern.21",
|
|
140
|
+
"@modern-js/types": "npm:@bleedingdev/modern-js-types@3.9.0-ultramodern.21",
|
|
141
|
+
"@modern-js/utils": "npm:@bleedingdev/modern-js-utils@3.9.0-ultramodern.21",
|
|
142
|
+
"@rsbuild/core": "2.2.10",
|
|
150
143
|
"@swc/core": "1.16.2",
|
|
151
144
|
"@swc/helpers": "^0.5.23",
|
|
152
145
|
"compression-webpack-plugin": "^12.0.0",
|
|
@@ -156,25 +149,34 @@
|
|
|
156
149
|
"import-meta-resolve": "^4.2.0",
|
|
157
150
|
"mlly": "^1.8.2",
|
|
158
151
|
"ndepe": "^0.1.13",
|
|
159
|
-
"pkg-types": "^2.3.
|
|
152
|
+
"pkg-types": "^2.3.3",
|
|
160
153
|
"std-env": "4.2.0"
|
|
161
154
|
},
|
|
162
155
|
"devDependencies": {
|
|
163
|
-
"@rslib/core": "1.0.
|
|
156
|
+
"@rslib/core": "1.0.2",
|
|
164
157
|
"@scripts/rstest-config": "2.66.0",
|
|
165
158
|
"@types/babel__traverse": "7.28.0",
|
|
166
|
-
"@types/node": "^26.
|
|
159
|
+
"@types/node": "^26.6.2",
|
|
167
160
|
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
161
|
+
"react": "^19.3.0",
|
|
162
|
+
"react-dom": "^19.3.0",
|
|
168
163
|
"typescript": "^7.0.2"
|
|
169
164
|
},
|
|
165
|
+
"peerDependencies": {
|
|
166
|
+
"react": "^19.2.8"
|
|
167
|
+
},
|
|
168
|
+
"peerDependenciesMeta": {
|
|
169
|
+
"react": {
|
|
170
|
+
"optional": true
|
|
171
|
+
}
|
|
172
|
+
},
|
|
170
173
|
"sideEffects": false,
|
|
171
174
|
"publishConfig": {
|
|
172
175
|
"access": "public"
|
|
173
176
|
},
|
|
174
177
|
"scripts": {
|
|
175
178
|
"dev": "rslib build --watch",
|
|
176
|
-
"build": "rslib build &&
|
|
177
|
-
"verify:public-surface": "node ./tests/config/verify-public-surface.mjs",
|
|
179
|
+
"build": "rslib build && node ./bin/modern-bundle-docs.js",
|
|
178
180
|
"test": "rstest"
|
|
179
181
|
}
|
|
180
182
|
}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __webpack_require__ = {};
|
|
3
|
-
(()=>{
|
|
4
|
-
__webpack_require__.n = (module)=>{
|
|
5
|
-
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
6
|
-
__webpack_require__.d(getter, {
|
|
7
|
-
a: getter
|
|
8
|
-
});
|
|
9
|
-
return getter;
|
|
10
|
-
};
|
|
11
|
-
})();
|
|
12
|
-
(()=>{
|
|
13
|
-
__webpack_require__.d = (exports1, getters, values)=>{
|
|
14
|
-
var define = (defs, kind)=>{
|
|
15
|
-
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
16
|
-
enumerable: true,
|
|
17
|
-
[kind]: defs[key]
|
|
18
|
-
});
|
|
19
|
-
};
|
|
20
|
-
define(getters, "get");
|
|
21
|
-
define(values, "value");
|
|
22
|
-
};
|
|
23
|
-
})();
|
|
24
|
-
(()=>{
|
|
25
|
-
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
26
|
-
})();
|
|
27
|
-
(()=>{
|
|
28
|
-
__webpack_require__.r = (exports1)=>{
|
|
29
|
-
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
30
|
-
value: 'Module'
|
|
31
|
-
});
|
|
32
|
-
Object.defineProperty(exports1, '__esModule', {
|
|
33
|
-
value: true
|
|
34
|
-
});
|
|
35
|
-
};
|
|
36
|
-
})();
|
|
37
|
-
var __webpack_exports__ = {};
|
|
38
|
-
__webpack_require__.r(__webpack_exports__);
|
|
39
|
-
__webpack_require__.d(__webpack_exports__, {
|
|
40
|
-
builderPluginAdapterPrecompress: ()=>builderPluginAdapterPrecompress
|
|
41
|
-
});
|
|
42
|
-
const external_node_zlib_namespaceObject = require("node:zlib");
|
|
43
|
-
const external_compression_webpack_plugin_namespaceObject = require("compression-webpack-plugin");
|
|
44
|
-
var external_compression_webpack_plugin_default = /*#__PURE__*/ __webpack_require__.n(external_compression_webpack_plugin_namespaceObject);
|
|
45
|
-
const DEFAULT_PRECOMPRESS_TEST = /\.(js|mjs|cjs|css|html|svg|json|map)$/i;
|
|
46
|
-
const DEFAULT_PRECOMPRESS_THRESHOLD = 10240;
|
|
47
|
-
const DEFAULT_PRECOMPRESS_MIN_RATIO = 0.8;
|
|
48
|
-
const createDefaultGzipOptions = ()=>({
|
|
49
|
-
algorithm: 'gzip',
|
|
50
|
-
filename: '[path][base].gz',
|
|
51
|
-
test: DEFAULT_PRECOMPRESS_TEST,
|
|
52
|
-
threshold: DEFAULT_PRECOMPRESS_THRESHOLD,
|
|
53
|
-
minRatio: DEFAULT_PRECOMPRESS_MIN_RATIO,
|
|
54
|
-
compressionOptions: {
|
|
55
|
-
level: 6
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
const createDefaultBrotliOptions = ()=>({
|
|
59
|
-
algorithm: 'brotliCompress',
|
|
60
|
-
filename: '[path][base].br',
|
|
61
|
-
test: DEFAULT_PRECOMPRESS_TEST,
|
|
62
|
-
threshold: DEFAULT_PRECOMPRESS_THRESHOLD,
|
|
63
|
-
minRatio: DEFAULT_PRECOMPRESS_MIN_RATIO,
|
|
64
|
-
compressionOptions: {
|
|
65
|
-
params: {
|
|
66
|
-
[external_node_zlib_namespaceObject.constants.BROTLI_PARAM_QUALITY]: 9
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
const mergeCompressionOptions = (base, next)=>{
|
|
71
|
-
const merged = {
|
|
72
|
-
...base,
|
|
73
|
-
...next
|
|
74
|
-
};
|
|
75
|
-
if (base.compressionOptions || next.compressionOptions) {
|
|
76
|
-
const baseCompressionOptions = base.compressionOptions;
|
|
77
|
-
const nextCompressionOptions = next.compressionOptions;
|
|
78
|
-
const mergedCompressionOptions = {
|
|
79
|
-
...baseCompressionOptions,
|
|
80
|
-
...nextCompressionOptions
|
|
81
|
-
};
|
|
82
|
-
if (baseCompressionOptions?.params || nextCompressionOptions?.params) mergedCompressionOptions.params = {
|
|
83
|
-
...baseCompressionOptions?.params,
|
|
84
|
-
...nextCompressionOptions?.params
|
|
85
|
-
};
|
|
86
|
-
merged.compressionOptions = mergedCompressionOptions;
|
|
87
|
-
}
|
|
88
|
-
return merged;
|
|
89
|
-
};
|
|
90
|
-
const resolveCodecOptions = (codecConfig, createDefaultOptions)=>{
|
|
91
|
-
if (false === codecConfig) return null;
|
|
92
|
-
if (void 0 === codecConfig || true === codecConfig) return createDefaultOptions();
|
|
93
|
-
return mergeCompressionOptions(createDefaultOptions(), codecConfig);
|
|
94
|
-
};
|
|
95
|
-
const resolvePrecompressConfig = (normalizedConfig)=>{
|
|
96
|
-
const precompress = normalizedConfig.output.precompress;
|
|
97
|
-
if (false === precompress || void 0 === precompress) return false;
|
|
98
|
-
if (true === precompress) return {};
|
|
99
|
-
return precompress;
|
|
100
|
-
};
|
|
101
|
-
const builderPluginAdapterPrecompress = (options)=>({
|
|
102
|
-
name: 'builder-plugin-adapter-modern-precompress',
|
|
103
|
-
setup (api) {
|
|
104
|
-
api.modifyBundlerChain((chain, { isProd, target })=>{
|
|
105
|
-
if (!isProd || 'web' !== target) return;
|
|
106
|
-
const precompressConfig = resolvePrecompressConfig(options.normalizedConfig);
|
|
107
|
-
if (false === precompressConfig) return;
|
|
108
|
-
const gzipOptions = resolveCodecOptions(precompressConfig.gzip, createDefaultGzipOptions);
|
|
109
|
-
if (gzipOptions) chain.plugin('modern-precompress-gzip').use(external_compression_webpack_plugin_default(), [
|
|
110
|
-
gzipOptions
|
|
111
|
-
]);
|
|
112
|
-
const brotliOptions = resolveCodecOptions(precompressConfig.brotli, createDefaultBrotliOptions);
|
|
113
|
-
if (brotliOptions) chain.plugin('modern-precompress-brotli').use(external_compression_webpack_plugin_default(), [
|
|
114
|
-
brotliOptions
|
|
115
|
-
]);
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
exports.builderPluginAdapterPrecompress = __webpack_exports__.builderPluginAdapterPrecompress;
|
|
120
|
-
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
121
|
-
"builderPluginAdapterPrecompress"
|
|
122
|
-
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
123
|
-
Object.defineProperty(exports, '__esModule', {
|
|
124
|
-
value: true
|
|
125
|
-
});
|