mfeflow 0.0.0-stage → 0.2.0

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 (137) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +126 -2
  3. package/assets/features/analytics-gtm/feature.json +117 -0
  4. package/assets/features/analytics-gtm/files/Analytics.tsx +13 -0
  5. package/assets/features/analytics-gtm/files/ConsentBanner.tsx +47 -0
  6. package/assets/features/analytics-gtm/files/consent-banner-test.tsx +36 -0
  7. package/assets/features/analytics-gtm/files/init.ts +26 -0
  8. package/assets/features/analytics-gtm/files/remote-analytics-test.ts.eta +18 -0
  9. package/assets/features/analytics-gtm/files/remote-analytics.ts.eta +13 -0
  10. package/assets/features/analytics-gtm/files/shell-init-test.ts +42 -0
  11. package/assets/features/ci-github/feature.json +26 -0
  12. package/assets/features/ci-github/files/ci.md +41 -0
  13. package/assets/features/ci-github/files/ci.yml +63 -0
  14. package/assets/features/env-t3/feature.json +399 -0
  15. package/assets/features/env-t3/files/check-runtime-config.ts +105 -0
  16. package/assets/features/env-t3/files/env.arktype.ts +12 -0
  17. package/assets/features/env-t3/files/env.example +1 -0
  18. package/assets/features/env-t3/files/env.valibot.ts +12 -0
  19. package/assets/features/env-t3/files/env.zod.ts +12 -0
  20. package/assets/features/env-t3/files/runtime.ts.eta +30 -0
  21. package/assets/features/env-t3/files/schema.arktype.ts +8 -0
  22. package/assets/features/env-t3/files/schema.valibot.ts +8 -0
  23. package/assets/features/env-t3/files/schema.zod.ts +8 -0
  24. package/assets/features/event-bus/feature.json +100 -0
  25. package/assets/features/event-bus/files/announce.tsx.eta +10 -0
  26. package/assets/features/event-bus/files/contracts-events.ts +11 -0
  27. package/assets/features/event-bus/files/contracts-package.json.eta +10 -0
  28. package/assets/features/event-bus/files/contracts-readme.md +10 -0
  29. package/assets/features/event-bus/files/events-test.ts.eta +18 -0
  30. package/assets/features/event-bus/files/events.ts.eta +20 -0
  31. package/assets/features/event-bus/files/shell-events-test.ts.eta +22 -0
  32. package/assets/features/event-bus/files/shell-events.ts.eta +19 -0
  33. package/assets/features/git-hooks/feature.json +42 -0
  34. package/assets/features/git-hooks/files/commitlint.config.js +1 -0
  35. package/assets/features/git-hooks/files/lefthook.yml +9 -0
  36. package/assets/features/http/feature.json +81 -0
  37. package/assets/features/http/files/client-test.ts +19 -0
  38. package/assets/features/http/files/client.ts +20 -0
  39. package/assets/features/lint-oxlint/feature.json +60 -0
  40. package/assets/features/lint-oxlint/files/oxlintrc.json +5 -0
  41. package/assets/features/lint-oxlint/files/prettierignore +5 -0
  42. package/assets/features/lint-oxlint/files/prettierrc.json +5 -0
  43. package/assets/features/route-factory/feature.json +60 -0
  44. package/assets/features/route-factory/files/contract.ts.eta +7 -0
  45. package/assets/features/route-factory/files/routes-contract.ts.eta +11 -0
  46. package/assets/features/route-factory/files/routes-test.ts.eta +9 -0
  47. package/assets/features/route-factory/files/routes.ts.eta +11 -0
  48. package/assets/features/telemetry-otel/feature.json +159 -0
  49. package/assets/features/telemetry-otel/files/init.ts.eta +53 -0
  50. package/assets/features/telemetry-otel/files/remote-telemetry-test.ts.eta +13 -0
  51. package/assets/features/telemetry-otel/files/remote-telemetry.ts.eta +11 -0
  52. package/assets/features/telemetry-otel/files/shell-init-test.ts.eta +36 -0
  53. package/assets/features/testing/feature.json +202 -0
  54. package/assets/features/testing/files/handlers.ts +5 -0
  55. package/assets/features/testing/files/playwright.config.ts +30 -0
  56. package/assets/features/testing/files/root-vitest.config.ts +6 -0
  57. package/assets/features/testing/files/sample-handlers-test.ts +16 -0
  58. package/assets/features/testing/files/sample-remote-test.tsx +12 -0
  59. package/assets/features/testing/files/sample-shell-test.tsx +11 -0
  60. package/assets/features/testing/files/sample-smoke-e2e.ts +53 -0
  61. package/assets/features/testing/files/server.ts +4 -0
  62. package/assets/features/testing/files/setup.ts +18 -0
  63. package/assets/features/testing/files/vitest.config.ts +11 -0
  64. package/assets/features/tsconfig/feature.json +78 -0
  65. package/assets/features/tsconfig/files/root.tsconfig.json +4 -0
  66. package/assets/features/tsconfig/files/tsconfig.json +5 -0
  67. package/assets/features/url-factory/feature.json +30 -0
  68. package/assets/features/url-factory/files/endpoints.ts +23 -0
  69. package/assets/templates/monorepo/feature.json +321 -0
  70. package/assets/templates/monorepo/files/remote/mfe.json.eta +7 -0
  71. package/assets/templates/monorepo/files/remote/package.json.eta +6 -0
  72. package/assets/templates/monorepo/files/remote/rsbuild.config.ts.eta +7 -0
  73. package/assets/templates/monorepo/files/remote/src/bootstrap.tsx.eta +6 -0
  74. package/assets/templates/monorepo/files/remote/src/env.d.ts.eta +1 -0
  75. package/assets/templates/monorepo/files/remote/src/exposed/App.tsx.eta +18 -0
  76. package/assets/templates/monorepo/files/remote/src/index.ts.eta +2 -0
  77. package/assets/templates/monorepo/files/root/AGENTS.md.eta +17 -0
  78. package/assets/templates/monorepo/files/root/README.md.eta +52 -0
  79. package/assets/templates/monorepo/files/root/gitignore.eta +11 -0
  80. package/assets/templates/monorepo/files/root/nvmrc.eta +1 -0
  81. package/assets/templates/monorepo/files/root/package.json.eta +9 -0
  82. package/assets/templates/monorepo/files/root/pnpm-workspace.yaml.eta +7 -0
  83. package/assets/templates/monorepo/files/root/turbo.json.eta +16 -0
  84. package/assets/templates/monorepo/files/shell/mfe.json.eta +7 -0
  85. package/assets/templates/monorepo/files/shell/package.json.eta +6 -0
  86. package/assets/templates/monorepo/files/shell/rsbuild.config.ts.eta +74 -0
  87. package/assets/templates/monorepo/files/shell/src/App.tsx.eta +46 -0
  88. package/assets/templates/monorepo/files/shell/src/bootstrap.tsx.eta +24 -0
  89. package/assets/templates/monorepo/files/shell/src/env.d.ts.eta +1 -0
  90. package/assets/templates/monorepo/files/shell/src/index.ts.eta +4 -0
  91. package/assets/templates/monorepo/files/shell/src/pages/Home.tsx.eta +14 -0
  92. package/assets/templates/monorepo/files/shell/src/remotes/route-table.tsx.eta +12 -0
  93. package/assets/templates/monorepo/glue/registry-entry.json.eta +5 -0
  94. package/assets/templates/monorepo/glue/route.tsx.eta +5 -0
  95. package/bin/mfeflow.js +4 -0
  96. package/dist/args.d.ts +68 -0
  97. package/dist/assets.d.ts +13 -0
  98. package/dist/catalog.d.ts +24 -0
  99. package/dist/checks/compat.d.ts +2 -0
  100. package/dist/checks/config.d.ts +8 -0
  101. package/dist/checks/env.d.ts +6 -0
  102. package/dist/checks/index.d.ts +6 -0
  103. package/dist/checks/plugins.d.ts +4 -0
  104. package/dist/checks/singletons.d.ts +9 -0
  105. package/dist/checks/workspace.d.ts +2 -0
  106. package/dist/cli.d.ts +11 -0
  107. package/dist/commands/add.d.ts +84 -0
  108. package/dist/commands/budget.d.ts +56 -0
  109. package/dist/commands/dev.d.ts +62 -0
  110. package/dist/commands/doctor.d.ts +141 -0
  111. package/dist/commands/env-key.d.ts +4 -0
  112. package/dist/commands/features.d.ts +53 -0
  113. package/dist/commands/init.d.ts +102 -0
  114. package/dist/devregistry.d.ts +19 -0
  115. package/dist/exit.d.ts +31 -0
  116. package/dist/findings.d.ts +35 -0
  117. package/dist/glue.d.ts +41 -0
  118. package/dist/help.d.ts +12 -0
  119. package/dist/index.d.ts +8 -0
  120. package/dist/index.js +4171 -0
  121. package/dist/inspect.d.ts +57 -0
  122. package/dist/io.d.ts +10 -0
  123. package/dist/local.d.ts +28 -0
  124. package/dist/options.d.ts +7 -0
  125. package/dist/output.d.ts +157 -0
  126. package/dist/pipeline.d.ts +7 -0
  127. package/dist/preset.d.ts +19 -0
  128. package/dist/proc.d.ts +79 -0
  129. package/dist/prompter.d.ts +28 -0
  130. package/dist/report.d.ts +26 -0
  131. package/dist/runtime.d.ts +17 -0
  132. package/dist/singletons.d.ts +11 -0
  133. package/dist/sizes.d.ts +17 -0
  134. package/dist/system.d.ts +20 -0
  135. package/dist/version.d.ts +8 -0
  136. package/dist/write.d.ts +26 -0
  137. package/package.json +66 -3
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "tsconfig",
3
+ "version": "0.1.0",
4
+ "description": "Strict TypeScript 7 presets from @mfeflow/tsconfig, and a typecheck script.",
5
+ "requires": ["core"],
6
+ "files": [
7
+ {
8
+ "to": "tsconfig.json",
9
+ "target": "shell",
10
+ "from": "files/tsconfig.json"
11
+ },
12
+ {
13
+ "to": "tsconfig.json",
14
+ "target": "remotes",
15
+ "from": "files/tsconfig.json"
16
+ },
17
+ {
18
+ "to": "tsconfig.json",
19
+ "target": "root",
20
+ "from": "files/root.tsconfig.json"
21
+ }
22
+ ],
23
+ "dependencies": [
24
+ {
25
+ "name": "@mfeflow/tsconfig",
26
+ "range": "latest",
27
+ "target": "shell",
28
+ "dev": true
29
+ },
30
+ {
31
+ "name": "@mfeflow/tsconfig",
32
+ "range": "latest",
33
+ "target": "remotes",
34
+ "dev": true
35
+ },
36
+ {
37
+ "name": "@mfeflow/tsconfig",
38
+ "range": "latest",
39
+ "target": "root",
40
+ "dev": true
41
+ },
42
+ {
43
+ "name": "typescript",
44
+ "range": "7.0.2",
45
+ "target": "root",
46
+ "dev": true
47
+ },
48
+ {
49
+ "name": "typescript",
50
+ "range": "7.0.2",
51
+ "target": "shell",
52
+ "dev": true
53
+ },
54
+ {
55
+ "name": "typescript",
56
+ "range": "7.0.2",
57
+ "target": "remotes",
58
+ "dev": true
59
+ }
60
+ ],
61
+ "scripts": [
62
+ {
63
+ "name": "typecheck",
64
+ "command": "turbo run typecheck",
65
+ "target": "root"
66
+ },
67
+ {
68
+ "name": "typecheck",
69
+ "command": "tsc --noEmit",
70
+ "target": "shell"
71
+ },
72
+ {
73
+ "name": "typecheck",
74
+ "command": "tsc --noEmit",
75
+ "target": "remotes"
76
+ }
77
+ ]
78
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "@mfeflow/tsconfig/node.json",
3
+ "include": ["*.ts", "scripts", "e2e"]
4
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "extends": "@mfeflow/tsconfig/react-app.json",
3
+ "compilerOptions": { "types": ["node"] },
4
+ "include": ["src", "rsbuild.config.ts", "env.ts", "vitest.config.ts"]
5
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "url-factory",
3
+ "version": "0.1.0",
4
+ "description": "Typed endpoint definitions and URL building (@mfeflow/url-factory), src/api/endpoints.ts in every app.",
5
+ "requires": ["core"],
6
+ "files": [
7
+ {
8
+ "to": "src/api/endpoints.ts",
9
+ "target": "shell",
10
+ "from": "files/endpoints.ts"
11
+ },
12
+ {
13
+ "to": "src/api/endpoints.ts",
14
+ "target": "remotes",
15
+ "from": "files/endpoints.ts"
16
+ }
17
+ ],
18
+ "dependencies": [
19
+ {
20
+ "name": "@mfeflow/url-factory",
21
+ "range": "latest",
22
+ "target": "shell"
23
+ },
24
+ {
25
+ "name": "@mfeflow/url-factory",
26
+ "range": "latest",
27
+ "target": "remotes"
28
+ }
29
+ ]
30
+ }
@@ -0,0 +1,23 @@
1
+ import { createUrlFactory, defineEndpoints } from '@mfeflow/url-factory';
2
+
3
+ export const endpoints = defineEndpoints({
4
+ health: { service: 'api', path: '/health' },
5
+ });
6
+
7
+ const defaults: Record<string, string> = { api: '/api' };
8
+
9
+ // A service's base is `<service>Url` in the runtime config (apiUrl for api) when the shell loaded
10
+ // one, so a build runs in every environment; the default above is for tests and standalone runs.
11
+ function configured(service: string): string | undefined {
12
+ const config: unknown = Reflect.get(globalThis, '__MFE_RUNTIME_CONFIG__');
13
+ const value: unknown =
14
+ typeof config === 'object' && config !== null
15
+ ? Reflect.get(config, `${service}Url`)
16
+ : undefined;
17
+ return typeof value === 'string' && value !== '' ? value : undefined;
18
+ }
19
+
20
+ export const apiUrl = createUrlFactory(endpoints, (service) => {
21
+ const base = configured(service) ?? defaults[service];
22
+ return base === undefined ? undefined : new URL(base, location.origin).toString();
23
+ });
@@ -0,0 +1,321 @@
1
+ {
2
+ "name": "core",
3
+ "version": "0.1.0",
4
+ "description": "The shell, the remotes, the registry and the workspace around them.",
5
+ "files": [
6
+ {
7
+ "to": "package.json",
8
+ "target": "root",
9
+ "from": "files/root/package.json.eta",
10
+ "template": true
11
+ },
12
+ {
13
+ "to": "pnpm-workspace.yaml",
14
+ "target": "root",
15
+ "from": "files/root/pnpm-workspace.yaml.eta",
16
+ "template": true
17
+ },
18
+ {
19
+ "to": "turbo.json",
20
+ "target": "root",
21
+ "from": "files/root/turbo.json.eta",
22
+ "template": true
23
+ },
24
+ {
25
+ "to": ".gitignore",
26
+ "target": "root",
27
+ "from": "files/root/gitignore.eta",
28
+ "template": true
29
+ },
30
+ {
31
+ "to": ".nvmrc",
32
+ "target": "root",
33
+ "from": "files/root/nvmrc.eta",
34
+ "template": true
35
+ },
36
+ {
37
+ "to": "README.md",
38
+ "target": "root",
39
+ "from": "files/root/README.md.eta",
40
+ "template": true
41
+ },
42
+ {
43
+ "to": "AGENTS.md",
44
+ "target": "root",
45
+ "from": "files/root/AGENTS.md.eta",
46
+ "template": true
47
+ },
48
+ {
49
+ "to": "registry/envs/dev/.gitkeep",
50
+ "target": "root",
51
+ "content": ""
52
+ },
53
+ {
54
+ "to": "registry/envs/staging/.gitkeep",
55
+ "target": "root",
56
+ "content": ""
57
+ },
58
+ {
59
+ "to": "registry/envs/prod/.gitkeep",
60
+ "target": "root",
61
+ "content": ""
62
+ },
63
+ {
64
+ "to": "package.json",
65
+ "target": "shell",
66
+ "from": "files/shell/package.json.eta",
67
+ "template": true
68
+ },
69
+ {
70
+ "to": "mfe.json",
71
+ "target": "shell",
72
+ "from": "files/shell/mfe.json.eta",
73
+ "template": true
74
+ },
75
+ {
76
+ "to": "rsbuild.config.ts",
77
+ "target": "shell",
78
+ "from": "files/shell/rsbuild.config.ts.eta",
79
+ "template": true
80
+ },
81
+ {
82
+ "to": "src/env.d.ts",
83
+ "target": "shell",
84
+ "from": "files/shell/src/env.d.ts.eta",
85
+ "template": true
86
+ },
87
+ {
88
+ "to": "src/index.ts",
89
+ "target": "shell",
90
+ "from": "files/shell/src/index.ts.eta",
91
+ "template": true
92
+ },
93
+ {
94
+ "to": "src/bootstrap.tsx",
95
+ "target": "shell",
96
+ "from": "files/shell/src/bootstrap.tsx.eta",
97
+ "template": true
98
+ },
99
+ {
100
+ "to": "src/App.tsx",
101
+ "target": "shell",
102
+ "from": "files/shell/src/App.tsx.eta",
103
+ "template": true
104
+ },
105
+ {
106
+ "to": "src/remotes/route-table.tsx",
107
+ "target": "shell",
108
+ "from": "files/shell/src/remotes/route-table.tsx.eta",
109
+ "template": true
110
+ },
111
+ {
112
+ "to": "package.json",
113
+ "target": "remotes",
114
+ "from": "files/remote/package.json.eta",
115
+ "template": true
116
+ },
117
+ {
118
+ "to": "mfe.json",
119
+ "target": "remotes",
120
+ "from": "files/remote/mfe.json.eta",
121
+ "template": true
122
+ },
123
+ {
124
+ "to": "rsbuild.config.ts",
125
+ "target": "remotes",
126
+ "from": "files/remote/rsbuild.config.ts.eta",
127
+ "template": true
128
+ },
129
+ {
130
+ "to": "src/env.d.ts",
131
+ "target": "remotes",
132
+ "from": "files/remote/src/env.d.ts.eta",
133
+ "template": true
134
+ },
135
+ {
136
+ "to": "src/index.ts",
137
+ "target": "remotes",
138
+ "from": "files/remote/src/index.ts.eta",
139
+ "template": true
140
+ },
141
+ {
142
+ "to": "src/bootstrap.tsx",
143
+ "target": "remotes",
144
+ "from": "files/remote/src/bootstrap.tsx.eta",
145
+ "template": true
146
+ },
147
+ {
148
+ "to": "src/exposed/App.tsx",
149
+ "target": "remotes",
150
+ "from": "files/remote/src/exposed/App.tsx.eta",
151
+ "template": true
152
+ },
153
+ {
154
+ "to": "src/pages/Home.tsx",
155
+ "target": "shell",
156
+ "from": "files/shell/src/pages/Home.tsx.eta",
157
+ "template": true
158
+ }
159
+ ],
160
+ "dependencies": [
161
+ {
162
+ "name": "turbo",
163
+ "range": "2.11.10",
164
+ "target": "root",
165
+ "dev": true
166
+ },
167
+ {
168
+ "name": "mfeflow",
169
+ "range": "latest",
170
+ "target": "root",
171
+ "dev": true
172
+ },
173
+ {
174
+ "name": "@mfeflow/runtime",
175
+ "range": "latest",
176
+ "target": "shell"
177
+ },
178
+ {
179
+ "name": "@module-federation/enhanced",
180
+ "range": "2.9.2",
181
+ "target": "shell"
182
+ },
183
+ {
184
+ "name": "react",
185
+ "range": "19.3.1",
186
+ "target": "shell"
187
+ },
188
+ {
189
+ "name": "react-dom",
190
+ "range": "19.3.1",
191
+ "target": "shell"
192
+ },
193
+ {
194
+ "name": "@mfeflow/rsbuild",
195
+ "range": "latest",
196
+ "target": "shell",
197
+ "dev": true
198
+ },
199
+ {
200
+ "name": "@rsbuild/core",
201
+ "range": "2.3.0",
202
+ "target": "shell",
203
+ "dev": true
204
+ },
205
+ {
206
+ "name": "@types/node",
207
+ "range": "26.6.6",
208
+ "target": "shell",
209
+ "dev": true
210
+ },
211
+ {
212
+ "name": "@types/react",
213
+ "range": "19.3.0",
214
+ "target": "shell",
215
+ "dev": true
216
+ },
217
+ {
218
+ "name": "@types/react-dom",
219
+ "range": "19.3.0",
220
+ "target": "shell",
221
+ "dev": true
222
+ },
223
+ {
224
+ "name": "@module-federation/enhanced",
225
+ "range": "2.9.2",
226
+ "target": "remotes"
227
+ },
228
+ {
229
+ "name": "react",
230
+ "range": "19.3.1",
231
+ "target": "remotes"
232
+ },
233
+ {
234
+ "name": "react-dom",
235
+ "range": "19.3.1",
236
+ "target": "remotes"
237
+ },
238
+ {
239
+ "name": "@mfeflow/rsbuild",
240
+ "range": "latest",
241
+ "target": "remotes",
242
+ "dev": true
243
+ },
244
+ {
245
+ "name": "@rsbuild/core",
246
+ "range": "2.3.0",
247
+ "target": "remotes",
248
+ "dev": true
249
+ },
250
+ {
251
+ "name": "@types/node",
252
+ "range": "26.6.6",
253
+ "target": "remotes",
254
+ "dev": true
255
+ },
256
+ {
257
+ "name": "@types/react",
258
+ "range": "19.3.0",
259
+ "target": "remotes",
260
+ "dev": true
261
+ },
262
+ {
263
+ "name": "@types/react-dom",
264
+ "range": "19.3.0",
265
+ "target": "remotes",
266
+ "dev": true
267
+ }
268
+ ],
269
+ "scripts": [
270
+ {
271
+ "name": "dev",
272
+ "command": "turbo run dev",
273
+ "target": "root"
274
+ },
275
+ {
276
+ "name": "build",
277
+ "command": "turbo run build",
278
+ "target": "root"
279
+ },
280
+ {
281
+ "name": "doctor",
282
+ "command": "mfeflow doctor",
283
+ "target": "root"
284
+ },
285
+ {
286
+ "name": "validate",
287
+ "command": "mfeflow validate",
288
+ "target": "root"
289
+ },
290
+ {
291
+ "name": "check-compat",
292
+ "command": "mfeflow check-compat",
293
+ "target": "root"
294
+ },
295
+ {
296
+ "name": "budget",
297
+ "command": "mfeflow budget",
298
+ "target": "root"
299
+ },
300
+ {
301
+ "name": "dev",
302
+ "command": "rsbuild dev",
303
+ "target": "shell"
304
+ },
305
+ {
306
+ "name": "build",
307
+ "command": "rsbuild build",
308
+ "target": "shell"
309
+ },
310
+ {
311
+ "name": "dev",
312
+ "command": "rsbuild dev",
313
+ "target": "remotes"
314
+ },
315
+ {
316
+ "name": "build",
317
+ "command": "rsbuild build",
318
+ "target": "remotes"
319
+ }
320
+ ]
321
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "<%= it.app.name %>",
3
+ "owner": "team-<%= it.app.name %>",
4
+ "shells": ["shell"],
5
+ "routes": ["/<%= it.app.name %>"],
6
+ "exposes": ["./App"]
7
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "<%= it.scope %>/<%= it.app.name %>",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module"
6
+ }
@@ -0,0 +1,7 @@
1
+ import { createRemoteConfig } from '@mfeflow/rsbuild';
2
+
3
+ export default createRemoteConfig({
4
+ name: '<%= it.app.name %>',
5
+ port: <%= it.app.port %>,
6
+ exposes: { './App': './src/exposed/App.tsx' },
7
+ });
@@ -0,0 +1,6 @@
1
+ import { createRoot } from 'react-dom/client';
2
+ import App from './exposed/App';
3
+
4
+ // Standalone mode (`pnpm dev` in this folder). Inside the shell, only ./exposed/* is loaded.
5
+ const el = document.getElementById('root');
6
+ if (el) createRoot(el).render(<App />);
@@ -0,0 +1 @@
1
+ /// <reference types="@rsbuild/core/types" />
@@ -0,0 +1,18 @@
1
+ import { useState } from 'react';
2
+
3
+ export default function App() {
4
+ const [clicks, setClicks] = useState(0);
5
+ return (
6
+ <section data-testid="<%= it.app.name %>">
7
+ <h2><%= it.app.name %></h2>
8
+ <button
9
+ type="button"
10
+ onClick={() => {
11
+ setClicks(clicks + 1);
12
+ }}
13
+ >
14
+ Clicked {clicks} times
15
+ </button>
16
+ </section>
17
+ );
18
+ }
@@ -0,0 +1,2 @@
1
+ // The async boundary: shared singletons resolve before app code runs.
2
+ void import('./bootstrap');
@@ -0,0 +1,17 @@
1
+ # AGENTS.md
2
+
3
+ Guidance for coding agents working in this repo.
4
+
5
+ - Package manager: pnpm (via corepack). Never npm or yarn. Versions live in the `catalog` of
6
+ `pnpm-workspace.yaml`; add dependencies there and reference them as `catalog:`.
7
+ - `pnpm dev` runs the shell and every remote. `pnpm build` builds all of them. `pnpm mfeflow dev` does the same with
8
+ per-app logs and picks up new remotes without a restart.
9
+ - Before finishing: `pnpm doctor` (and `pnpm validate`, `pnpm check-compat`, `pnpm budget` after a build) must exit 0.
10
+ - TypeScript 7, strict. Relative imports have no file extension (`./plan`, not `./plan.js`).
11
+ - Each remote is deployed on its own. A remote must not import from another remote or from
12
+ the shell; talk through the registry, events or URLs.
13
+ - A remote's public surface is `src/exposed/`. Everything else is private to it.
14
+ - Add apps and features with the `mfeflow` CLI, installed as a root dev dependency (`pnpm mfeflow add remote <name>`, `pnpm mfeflow features`).
15
+ `mfeflow.json` is the CLI's record of the project; do not edit the file hashes by hand.
16
+ - Shared singletons (react, react-dom, `@mfeflow/runtime`) are provided by the shell. Do not
17
+ bundle your own copy.
@@ -0,0 +1,52 @@
1
+ # <%= it.scope.slice(1) %>-platform
2
+
3
+ A React micro-frontend platform made with [mfeflow](https://github.com/mfeflow/mfeflow):
4
+ one shell and independently deployable remotes, loaded at runtime through Module Federation.
5
+
6
+ ```
7
+ apps/shell the host: routes, layout, registry loading
8
+ apps/<remote> one micro-frontend each, exposing ./App
9
+ registry/envs which build of each remote every environment serves
10
+ mfeflow.json what the CLI generated; `pnpm mfeflow add` reads and updates it
11
+ ```
12
+
13
+ ## Run it
14
+
15
+ ```sh
16
+ pnpm install
17
+ pnpm dev
18
+ ```
19
+
20
+ `pnpm dev` starts the shell on http://localhost:4300 and every remote on its own port
21
+ (see `registry/envs/dev`). The shell reads that dev registry and renders the remotes.
22
+
23
+ `pnpm mfeflow dev` does the same with a prefixed, coloured log per app, and it follows the project:
24
+ add a remote with `pnpm mfeflow add remote checkout` and it starts, and the shell lists it, without a restart.
25
+ Use a remote you already run elsewhere with `pnpm mfeflow dev --remote checkout=http://localhost:3001`,
26
+ or run a few apps with `--only shell,catalog`. Ctrl+C stops everything.
27
+
28
+ ## Change it
29
+
30
+ ```sh
31
+ pnpm mfeflow add remote checkout # a new remote, its registry files and its shell route
32
+ pnpm mfeflow add <feature> # see `pnpm mfeflow features`
33
+ ```
34
+
35
+ ## Check it
36
+
37
+ ```sh
38
+ pnpm doctor # singletons, compatibility, config, drift; `pnpm doctor --fix` repairs the safe ones
39
+ pnpm validate # mfeflow.json, every mfe.json and every registry entry
40
+ pnpm check-compat # each remote's shared ranges against its shell
41
+ pnpm budget # after `pnpm build`: first-load JS per shell and remote
42
+ ```
43
+
44
+ Each is a root script for the `mfeflow` CLI in your devDependencies (`pnpm mfeflow <command>` runs it directly). All of them take `--json` and exit non-zero on errors, so they can run in CI. `pnpm budget` checks each remote's entry
45
+ against the 10 KB a remote may add; set `budget.baselineKb` in `mfeflow.json` (your pages built as one app) to check
46
+ the shell against baseline + 32 KB too.
47
+
48
+ ## Before you deploy
49
+
50
+ `registry/envs/staging` and `registry/envs/prod` point at `example.com`. Replace the hosts
51
+ with where you serve each remote (the shell expects `/mfe/<name>/` on its own origin).
52
+ The shell loads the registry from `/registry/index.json`, so serve one per environment.
@@ -0,0 +1,11 @@
1
+ node_modules/
2
+ dist/
3
+ .turbo/
4
+ coverage/
5
+ *.tsbuildinfo
6
+ .mfeflow/
7
+ *.log
8
+ .env
9
+ .env.*
10
+ !.env.example
11
+ .DS_Store
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "<%= it.scope.slice(1) %>-platform",
3
+ "private": true,
4
+ "type": "module",
5
+ "packageManager": "pnpm@12.16.1",
6
+ "engines": {
7
+ "node": ">=22.12"
8
+ }
9
+ }
@@ -0,0 +1,7 @@
1
+ packages:
2
+ - apps/*
3
+ - packages/*
4
+
5
+ # Dependencies allowed to run install scripts.
6
+ allowBuilds:
7
+ lefthook: true
@@ -0,0 +1,16 @@
1
+ {
2
+ "$schema": "https://turborepo.com/schema.json",
3
+ "tasks": {
4
+ "build": {
5
+ "dependsOn": ["^build"],
6
+ "outputs": ["dist/**"]
7
+ },
8
+ "typecheck": {
9
+ "dependsOn": ["^build"]
10
+ },
11
+ "dev": {
12
+ "cache": false,
13
+ "persistent": true
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "<%= it.app.name %>",
3
+ "owner": "team-<%= it.app.name %>",
4
+ "shells": [],
5
+ "routes": [],
6
+ "exposes": []
7
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "<%= it.scope %>/<%= it.app.name %>",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module"
6
+ }