@framework-m/vite-plugin 0.9.6 → 0.11.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.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Plugin } from 'vite';
1
+ import { Plugin, UserConfig } from 'vite';
2
2
  export declare const ENV_VITE_DEBUG = "FRAMEWORK_M_VITE_PLUGIN_DEBUG";
3
3
  export declare const ENV_DEBUG = "FRAMEWORK_M_DEBUG";
4
4
  /**
@@ -17,21 +17,39 @@ export interface FrameworkMPluginOptions {
17
17
  * List of plugin names to exclude from bundling.
18
18
  */
19
19
  exclude?: string[];
20
+ /**
21
+ * App-specific Vite config overrides.
22
+ * Deep-merged on top of the shared defaults provided by this plugin.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * frameworkMPlugin({
27
+ * server: { port: 5173 },
28
+ * build: { outDir: "./dist" },
29
+ * })
30
+ * ```
31
+ */
32
+ server?: UserConfig["server"];
33
+ build?: UserConfig["build"];
34
+ define?: UserConfig["define"];
35
+ resolve?: UserConfig["resolve"];
36
+ optimizeDeps?: UserConfig["optimizeDeps"];
20
37
  }
21
38
  /**
22
39
  * Create the Framework M Vite plugin.
23
40
  *
24
41
  * This plugin:
25
- * 1. Scans the workspace at build time for packages with "framework-m"
42
+ * 1. Provides shared Vite config defaults (resolve extensions, dedupe,
43
+ * react-native-web alias, vendor chunk splitting) — eliminating
44
+ * boilerplate duplication across apps
45
+ * 2. Scans the workspace at build time for packages with "framework-m"
26
46
  * metadata in their package.json
27
- * 2. Generates a virtual module `virtual:framework-m-plugins` that imports
47
+ * 3. Generates a virtual module `virtual:framework-m-plugins` that imports
28
48
  * all discovered plugin configs
29
- * 3. The shell app imports this virtual module to auto-register all plugins
49
+ * 4. The shell app imports this virtual module to auto-register all plugins
30
50
  */
31
51
  export declare function frameworkMPlugin(options?: FrameworkMPluginOptions): Plugin;
32
52
  export type { DiscoveredPlugin } from './scanner';
33
53
  export { scanWorkspacePlugins } from './scanner';
34
54
  export { generateVirtualModule } from './codegen';
35
- export { generateMfeConfig } from './mfe-config';
36
- export type { MfeOptions } from './mfe-config';
37
55
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAYnC,eAAO,MAAM,cAAc,kCAAkC,CAAC;AAC9D,eAAO,MAAM,SAAS,sBAAsB,CAAC;AAwB7C;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,MAAM,CAqN9E;AA4ED,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAW/C,eAAO,MAAM,cAAc,kCAAkC,CAAC;AAC9D,eAAO,MAAM,SAAS,sBAAsB,CAAC;AAyD7C;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC9B,KAAK,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IAC5B,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;IAChC,YAAY,CAAC,EAAE,UAAU,CAAC,cAAc,CAAC,CAAC;CAC3C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,MAAM,CA+S9E;AA4ED,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js CHANGED
@@ -1,346 +1,387 @@
1
- import e from "node:fs";
2
- import t from "node:path";
3
- import { globSync as n } from "glob";
4
- import r from "fast-glob";
5
- import { searchForWorkspaceRoot as i } from "vite";
6
- import { federation as a } from "@module-federation/vite";
7
- //#region src/scanner.ts
8
- async function o(n) {
9
- let i = n || s(process.cwd()), a = await r(["**/package.json"], {
10
- cwd: i,
11
- ignore: [
12
- "**/node_modules/**",
13
- "**/dist/**",
14
- "**/temp/**",
15
- "**/venv/**",
16
- "**/.venv/**",
17
- "**/.m/**",
18
- "**/__pycache__/**"
19
- ],
20
- absolute: !0
21
- }), o = [];
22
- for (let n of a) try {
23
- let r = e.readFileSync(n, "utf-8"), a = JSON.parse(r), s = a["framework-m"];
24
- if (s?.plugin) {
25
- let e = t.dirname(n), r = t.resolve(e, s.plugin), c = a.name || t.basename(e), l = s.name;
26
- if (!l) {
27
- let n = t.relative(i, e).split(t.sep);
28
- l = n.length > 1 && [
29
- "apps",
30
- "libs",
31
- "packages"
32
- ].includes(n[0]) ? n[1] : n[0] || t.basename(e);
33
- }
34
- o.push({
35
- name: c,
36
- shortName: l,
37
- pluginConfigPath: r
38
- });
39
- }
40
- } catch {
41
- continue;
42
- }
43
- return o.sort((e, t) => e.name === t.name ? e.pluginConfigPath.localeCompare(t.pluginConfigPath) : e.name.localeCompare(t.name));
1
+ import h from "node:fs";
2
+ import l from "node:path";
3
+ import { globSync as N } from "glob";
4
+ import S from "fast-glob";
5
+ async function j(e) {
6
+ const t = e || F(process.cwd()), d = await S(["**/package.json"], {
7
+ cwd: t,
8
+ ignore: [
9
+ "**/node_modules/**",
10
+ "**/dist/**",
11
+ "**/temp/**",
12
+ "**/venv/**",
13
+ "**/.venv/**",
14
+ "**/.m/**",
15
+ "**/__pycache__/**"
16
+ ],
17
+ absolute: !0
18
+ }), p = [];
19
+ for (const n of d)
20
+ try {
21
+ const o = h.readFileSync(n, "utf-8"), c = JSON.parse(o), i = c["framework-m"];
22
+ if (i?.plugin) {
23
+ const s = l.dirname(n), f = l.resolve(s, i.plugin), g = c.name || l.basename(s);
24
+ let u = i.name;
25
+ if (!u) {
26
+ const a = l.relative(t, s).split(l.sep);
27
+ a.length > 1 && ["apps", "libs", "packages"].includes(a[0]) ? u = a[1] : u = a[0] || l.basename(s);
28
+ }
29
+ p.push({
30
+ name: g,
31
+ shortName: u,
32
+ pluginConfigPath: f
33
+ });
34
+ }
35
+ } catch {
36
+ continue;
37
+ }
38
+ return p.sort((n, o) => n.name === o.name ? n.pluginConfigPath.localeCompare(o.pluginConfigPath) : n.name.localeCompare(o.name));
44
39
  }
45
- function s(n) {
46
- let r = n;
47
- for (;;) {
48
- if (e.existsSync(t.join(r, "pnpm-workspace.yaml"))) return r;
49
- let n = t.dirname(r);
50
- if (n === r) break;
51
- r = n;
52
- }
53
- return n;
40
+ function F(e) {
41
+ let t = e;
42
+ for (; ; ) {
43
+ if (h.existsSync(l.join(t, "pnpm-workspace.yaml")))
44
+ return t;
45
+ const r = l.dirname(t);
46
+ if (r === t) break;
47
+ t = r;
48
+ }
49
+ return e;
54
50
  }
55
- //#endregion
56
- //#region src/codegen.ts
57
- function c(e) {
58
- return e.split(t.sep).join("/");
51
+ function $(e) {
52
+ return e.split(l.sep).join("/");
59
53
  }
60
- function l(n) {
61
- if (n.length === 0) return "export default [];\n";
62
- let i = "", a = "", o = [];
63
- n.forEach((n, s) => {
64
- let l = c(n.pluginConfigPath);
65
- i += `import plugin${s} from '${l}';\n`;
66
- let u = t.dirname(n.pluginConfigPath), d = t.join(u, "overrides"), f = !1, p = `const enhancedPlugin${s} = {\n ...plugin${s},\n`, m = {}, h = [], g = "";
67
- if (e.existsSync(d)) {
68
- let n = t.join(d, "traversals.ts");
69
- e.existsSync(n) && (f = !0, g = `traversals_${s}`, i += `import ${g} from '${c(n)}';\n`);
70
- let a = d.replace(/\\/g, "/"), o = r.sync("**/*.tsx", {
71
- cwd: a,
72
- absolute: !0
73
- });
74
- o.length > 0 && (f = !0, o.forEach((e) => {
75
- let t = c(e), n = t.replace(c(d) + "/", "").split("/");
76
- if (n.length === 2) {
77
- let e = n[0], r = n[1].replace(".tsx", ""), a = `${e}_${r}_${s}`;
78
- i += `import ${a} from '${t}';\n`, e === "Core" ? h.push(`{ name: '${r}', component: ${a} }`) : (m[e] || (m[e] = []), m[e].push(`${r}: ${a}`));
79
- }
80
- }));
81
- }
82
- if (f) {
83
- if (Object.keys(m).length > 0) {
84
- p += ` doctypes: [\n ...(plugin${s}.doctypes || []),\n`;
85
- for (let [e, t] of Object.entries(m)) p += ` {\n doctype: '${e}',\n components: {\n ${t.join(",\n ")}\n }\n },\n`;
86
- p += " ],\n";
87
- }
88
- h.length > 0 && (p += ` pages: [\n ...(plugin${s}.pages || []),\n ${h.join(",\n ")}\n ],\n`), g && (p += ` traversals: ${g},\n`), p += "};\n", a += p, o.push(`enhancedPlugin${s}`);
89
- } else o.push(`plugin${s}`);
90
- });
91
- let s = `[${o.join(", ")}]`;
92
- return `${i}\n${a}\nexport const discoveredPlugins = ${s};\nexport default ${s};\n`;
54
+ function I(e) {
55
+ if (e.length === 0)
56
+ return `export default [];
57
+ `;
58
+ let t = "", r = "";
59
+ const d = [];
60
+ e.forEach((n, o) => {
61
+ const c = $(n.pluginConfigPath);
62
+ t += `import plugin${o} from '${c}';
63
+ `;
64
+ const i = l.dirname(n.pluginConfigPath), s = l.join(i, "overrides");
65
+ let f = !1, g = `const enhancedPlugin${o} = {
66
+ ...plugin${o},
67
+ `;
68
+ const u = {}, m = [];
69
+ let a = "";
70
+ if (h.existsSync(s)) {
71
+ const v = l.join(s, "traversals.ts");
72
+ h.existsSync(v) && (f = !0, a = `traversals_${o}`, t += `import ${a} from '${$(v)}';
73
+ `);
74
+ const w = s.replace(/\\/g, "/"), k = S.sync("**/*.tsx", {
75
+ cwd: w,
76
+ absolute: !0
77
+ });
78
+ k.length > 0 && (f = !0, k.forEach((A) => {
79
+ const M = $(A), C = M.replace($(s) + "/", "").split("/");
80
+ if (C.length === 2) {
81
+ const y = C[0], b = C[1].replace(".tsx", ""), _ = `${y}_${b}_${o}`;
82
+ t += `import ${_} from '${M}';
83
+ `, y === "Core" ? m.push(`{ name: '${b}', component: ${_} }`) : (u[y] || (u[y] = []), u[y].push(`${b}: ${_}`));
84
+ }
85
+ }));
86
+ }
87
+ if (f) {
88
+ if (Object.keys(u).length > 0) {
89
+ g += ` doctypes: [
90
+ ...(plugin${o}.doctypes || []),
91
+ `;
92
+ for (const [v, w] of Object.entries(u))
93
+ g += ` {
94
+ doctype: '${v}',
95
+ components: {
96
+ ${w.join(`,
97
+ `)}
98
+ }
99
+ },
100
+ `;
101
+ g += ` ],
102
+ `;
103
+ }
104
+ m.length > 0 && (g += ` pages: [
105
+ ...(plugin${o}.pages || []),
106
+ ${m.join(`,
107
+ `)}
108
+ ],
109
+ `), a && (g += ` traversals: ${a},
110
+ `), g += `};
111
+ `, r += g, d.push(`enhancedPlugin${o}`);
112
+ } else
113
+ d.push(`plugin${o}`);
114
+ });
115
+ const p = `[${d.join(", ")}]`;
116
+ return `${t}
117
+ ${r}
118
+ export const discoveredPlugins = ${p};
119
+ export default ${p};
120
+ `;
93
121
  }
94
- //#endregion
95
- //#region src/mfe-config.ts
96
- function u(n) {
97
- return {
98
- resolve: {
99
- extensions: [
100
- ".web.mjs",
101
- ".web.js",
102
- ".web.jsx",
103
- ".web.ts",
104
- ".web.tsx",
105
- ".mjs",
106
- ".js",
107
- ".mts",
108
- ".ts",
109
- ".jsx",
110
- ".tsx",
111
- ".json"
112
- ],
113
- alias: { "react-native": "react-native-web" },
114
- dedupe: [
115
- "react",
116
- "react-dom",
117
- "react-router",
118
- "react-router-dom",
119
- "@refinedev/core",
120
- "@framework-m/plugin-sdk",
121
- "@framework-m/ui",
122
- "@tanstack/react-query"
123
- ]
124
- },
125
- optimizeDeps: {
126
- exclude: ["@module-federation/dts-plugin", "@module-federation/sdk"],
127
- esbuildOptions: {
128
- target: "esnext",
129
- resolveExtensions: [
130
- ".web.js",
131
- ".web.ts",
132
- ".web.tsx",
133
- ".js",
134
- ".jsx",
135
- ".ts",
136
- ".tsx"
137
- ]
138
- }
139
- },
140
- build: {
141
- target: "esnext",
142
- minify: !0,
143
- cssCodeSplit: !1,
144
- chunkSizeWarningLimit: 1e3
145
- },
146
- plugins: [_(), a({
147
- name: n.name,
148
- filename: "remoteEntry.js",
149
- dev: !0,
150
- dts: !1,
151
- exposes: { "./plugin": n.entry },
152
- shared: (() => {
153
- let r = [
154
- "react",
155
- "react-dom",
156
- "react-router",
157
- "@tanstack/react-query",
158
- "@refinedev/core",
159
- "@framework-m/ui",
160
- "@framework-m/plugin-sdk"
161
- ], i = n.serviceName;
162
- try {
163
- let n = t.join(process.cwd(), "package.json");
164
- if (e.existsSync(n)) {
165
- let t = JSON.parse(e.readFileSync(n, "utf-8"));
166
- !i && t["framework-m"]?.service_name && (i = t["framework-m"].service_name);
167
- let a = {
168
- ...t.dependencies || {},
169
- ...t.devDependencies || {},
170
- ...t.peerDependencies || {}
171
- };
172
- for (let e of [
173
- "react-router-dom",
174
- "tamagui",
175
- "@tamagui/core",
176
- "@tamagui/web"
177
- ]) a[e] && r.push(e);
178
- }
179
- } catch {}
180
- let a = {};
181
- for (let e of r) a[e] = e === "@framework-m/plugin-sdk" || e === "@framework-m/ui" ? {
182
- singleton: !0,
183
- import: `${e}/dist/index.js`
184
- } : { singleton: !0 };
185
- n._resolvedServiceName = i;
186
- let o = Array.isArray(n.shared) ? n.shared : typeof n.shared == "object" && n.shared !== null ? Object.entries(n.shared) : [];
187
- for (let e of o) if (Array.isArray(e)) {
188
- let [t, n] = e;
189
- a[t] = n;
190
- }
191
- return a;
192
- })()
193
- })],
194
- server: {
195
- proxy: { "/api": {
196
- target: process.env.VITE_DEV_BACKEND_URL || "http://localhost:8080",
197
- changeOrigin: !0,
198
- secure: !1,
199
- ws: !0
200
- } },
201
- fs: { allow: [i(process.cwd()), ...process.env.FRAMEWORK_M_ACTIVE_SHELL_ROOT ? [process.env.FRAMEWORK_M_ACTIVE_SHELL_ROOT] : []] }
202
- },
203
- define: {
204
- "process.env.FRAMEWORK_M_SERVICE_NAME": JSON.stringify(n._resolvedServiceName ?? process.env.FRAMEWORK_M_SERVICE_NAME),
205
- "process.env.VITE_DEV_BACKEND_URL": JSON.stringify(process.env.VITE_DEV_BACKEND_URL || "http://localhost:8080"),
206
- "process.env.INSTALLED_APPS": JSON.stringify(process.env.INSTALLED_APPS || "")
207
- }
208
- };
122
+ const L = "virtual:framework-m-plugins", D = "\0virtual:framework-m-plugins", J = "FRAMEWORK_M_VITE_PLUGIN_DEBUG", U = "FRAMEWORK_M_DEBUG";
123
+ function x() {
124
+ const e = typeof process < "u" ? process.env : {}, t = e[J] ?? e[U];
125
+ return typeof t == "string" ? ["1", "true", "yes", "on"].includes(t.toLowerCase()) : !1;
209
126
  }
210
- //#endregion
211
- //#region src/index.ts
212
- var d = "virtual:framework-m-plugins", f = "\0virtual:framework-m-plugins", p = "FRAMEWORK_M_VITE_PLUGIN_DEBUG", m = "FRAMEWORK_M_DEBUG";
213
- function h() {
214
- let e = typeof process < "u" ? process.env : {}, t = e.FRAMEWORK_M_VITE_PLUGIN_DEBUG ?? e.FRAMEWORK_M_DEBUG;
215
- return typeof t == "string" && [
216
- "1",
217
- "true",
218
- "yes",
219
- "on"
220
- ].includes(t.toLowerCase());
127
+ const P = {
128
+ info(e) {
129
+ console.info(`[framework-m/vite-plugin] ${e}`);
130
+ },
131
+ debug(e) {
132
+ x() && console.info(`[framework-m/vite-plugin] ${e}`);
133
+ }
134
+ }, V = [
135
+ ".web.mjs",
136
+ ".web.js",
137
+ ".web.jsx",
138
+ ".web.ts",
139
+ ".web.tsx",
140
+ ".mjs",
141
+ ".js",
142
+ ".mts",
143
+ ".ts",
144
+ ".jsx",
145
+ ".tsx",
146
+ ".json"
147
+ ], z = [
148
+ "react",
149
+ "react-dom",
150
+ "@tanstack/react-query",
151
+ "@refinedev/core",
152
+ "react-router",
153
+ "react-router-dom",
154
+ "react-i18next",
155
+ "i18next"
156
+ ];
157
+ function Z(e = {}) {
158
+ let t = [], r = [], d = [];
159
+ const p = (n) => {
160
+ let o = n;
161
+ if (e.include && e.include.length > 0)
162
+ x() && console.info(
163
+ `[framework-m/vite-plugin] Applying explicit include filter: [${e.include.join(", ")}]`
164
+ ), o = n.filter((c) => e.include.includes(c.name));
165
+ else {
166
+ const c = e.root || process.cwd(), i = l.join(c, "package.json");
167
+ if (h.existsSync(i))
168
+ try {
169
+ const s = JSON.parse(h.readFileSync(i, "utf8"));
170
+ if (s["framework-m"]?.plugin) {
171
+ const f = s.name;
172
+ x() && console.info(
173
+ `[framework-m/vite-plugin] Local package.json is a plugin (${f}). Selective bundling enabled.`
174
+ ), o = n.filter((g) => g.name === f);
175
+ } else
176
+ x() && console.info(
177
+ `[framework-m/vite-plugin] Local package.json is NOT a plugin (shell mode). Bundling all ${n.length} plugins.`
178
+ ), o = n;
179
+ } catch {
180
+ o = n;
181
+ }
182
+ else
183
+ o = n;
184
+ }
185
+ return e.exclude && e.exclude.length > 0 && (o = o.filter((c) => !e.exclude.includes(c.name))), o;
186
+ };
187
+ return {
188
+ name: "framework-m-plugin",
189
+ async config(n) {
190
+ const o = e.root || process.cwd();
191
+ console.info(`[framework-m/vite-plugin] Config phase: root=${o}, cwd=${process.cwd()}`), t = O(e.root);
192
+ const c = await j(e.root);
193
+ console.info(
194
+ `[framework-m/vite-plugin] Scanner found ${c.length} plugins in workspace`
195
+ ), r = p(c), console.info(
196
+ `[framework-m/vite-plugin] After filtering: ${r.length} plugins`
197
+ ), d = E(r);
198
+ const i = n.build?.rollupOptions?.output, f = (Array.isArray(i) ? i : [i ?? {}]).map((u) => {
199
+ const m = u.manualChunks;
200
+ return {
201
+ ...u,
202
+ manualChunks(a, v) {
203
+ const w = W(a, d);
204
+ if (w)
205
+ return w;
206
+ if (typeof m == "function") {
207
+ const k = m(a, v);
208
+ if (k) return k;
209
+ }
210
+ if (a.includes("node_modules")) {
211
+ if (a.includes("node_modules/react/") || a.includes("node_modules/react-dom/") || a.includes("node_modules/scheduler/"))
212
+ return "vendor-react";
213
+ if (a.includes("@refinedev"))
214
+ return "vendor-refine";
215
+ if (a.includes("@tamagui/lucide-icons") || a.includes("lucide-icons"))
216
+ return "vendor-icons";
217
+ if (a.includes("@tamagui") || a.includes("tamagui"))
218
+ return "vendor-tamagui";
219
+ if (a.includes("@tanstack") || a.includes("i18next") || a.includes("react-router"))
220
+ return "vendor-utils";
221
+ }
222
+ }
223
+ };
224
+ });
225
+ return {
226
+ define: {
227
+ "process.env": {},
228
+ ...e.define
229
+ },
230
+ resolve: {
231
+ extensions: e.resolve?.extensions ?? V,
232
+ dedupe: e.resolve?.dedupe ?? z,
233
+ alias: [
234
+ {
235
+ find: "@react-native/assets-registry/registry",
236
+ replacement: "react-native-web/dist/modules/AssetRegistry/index.js"
237
+ },
238
+ { find: /^react-native$/, replacement: "react-native-web" },
239
+ // Spread any additional aliases from user config or options
240
+ ...Array.isArray(n.resolve?.alias) ? n.resolve.alias : [],
241
+ ...Array.isArray(e.resolve?.alias) ? e.resolve.alias : []
242
+ ]
243
+ },
244
+ optimizeDeps: e.optimizeDeps ?? {},
245
+ build: {
246
+ ...e.build,
247
+ rollupOptions: {
248
+ ...e.build?.rollupOptions,
249
+ output: Array.isArray(i) ? f : f[0]
250
+ }
251
+ },
252
+ server: e.server
253
+ };
254
+ },
255
+ /**
256
+ * Discover plugins at build start.
257
+ */
258
+ async buildStart() {
259
+ const n = e.root;
260
+ t = O(n);
261
+ const o = await j(n);
262
+ r = p(o), d = E(r);
263
+ const c = r.map((s) => s.name).join(", "), i = r.length > 0 ? "" : " (shell app / runtime discovery)";
264
+ if (P.info(
265
+ r.length > 0 ? `Discovered ${r.length} Framework M plugin(s): ${c}${i}` : `Discovered 0 Framework M plugins${i}`
266
+ ), r.length > 0) {
267
+ P.debug(`✓ Discovered ${r.length} Framework M plugin(s):`);
268
+ for (const s of r)
269
+ P.debug(` - ${s.name}`);
270
+ } else
271
+ P.debug("ℹ No Framework M plugins found in workspace");
272
+ },
273
+ /**
274
+ * Resolve the virtual module ID.
275
+ */
276
+ resolveId(n) {
277
+ if (n === L)
278
+ return D;
279
+ },
280
+ /**
281
+ * Load the virtual module — generate code with all plugin imports.
282
+ */
283
+ load(n) {
284
+ if (n === D)
285
+ return I(r);
286
+ },
287
+ /**
288
+ * HMR: Watch plugin config files for changes.
289
+ */
290
+ configureServer(n) {
291
+ for (const i of r) {
292
+ n.watcher.add(i.pluginConfigPath);
293
+ const s = l.join(l.dirname(i.pluginConfigPath), "overrides");
294
+ n.watcher.add(s);
295
+ }
296
+ for (const i of t)
297
+ n.watcher.add(i);
298
+ const o = async () => {
299
+ t = O(e.root);
300
+ const i = await j(e.root);
301
+ r = p(i), d = E(r);
302
+ for (const u of r)
303
+ n.watcher.add(u.pluginConfigPath);
304
+ for (const u of t)
305
+ n.watcher.add(u);
306
+ const s = n.moduleGraph.getModuleById(D);
307
+ s && n.moduleGraph.invalidateModule(s), P.info("Plugin configuration changed, triggering reload");
308
+ const f = n, g = f.hot ?? f.ws;
309
+ g && typeof g.send == "function" && g.send({ type: "full-reload" });
310
+ }, c = (i) => {
311
+ const s = i.includes("plugin.config."), f = i.includes("/overrides/") && (i.endsWith(".tsx") || i.endsWith(".ts"));
312
+ (s || f) && o();
313
+ };
314
+ n.watcher.on("change", c), n.watcher.on("add", c), n.watcher.on("unlink", c);
315
+ },
316
+ /**
317
+ * Inject runtime compatibility shims (e.g. CommonJS require fallback for Vite 8/Rolldown).
318
+ */
319
+ transformIndexHtml() {
320
+ return [
321
+ {
322
+ tag: "script",
323
+ attrs: { type: "module" },
324
+ children: `import * as React from 'react';
325
+ import * as ReactDOM from 'react-dom';
326
+ if (typeof window !== 'undefined') {
327
+ window.require = (id) => {
328
+ if (id === 'react') return React;
329
+ if (id === 'react-dom') return ReactDOM;
330
+ if (id === 'react-dom/client') return ReactDOM;
331
+ console.warn('[CJS Shim] Dynamic require called for: ' + id);
332
+ return {};
333
+ };
334
+ }`,
335
+ injectTo: "head-prepend"
336
+ }
337
+ ];
338
+ }
339
+ };
221
340
  }
222
- var g = {
223
- info(e) {
224
- console.info(`[framework-m/vite-plugin] ${e}`);
225
- },
226
- debug(e) {
227
- h() && console.info(`[framework-m/vite-plugin] ${e}`);
228
- }
229
- };
230
- function _(n = {}) {
231
- let r = [], i = [], a = [], s = (r) => {
232
- let i = r;
233
- if (n.include && n.include.length > 0) h() && console.info(`[framework-m/vite-plugin] Applying explicit include filter: [${n.include.join(", ")}]`), i = r.filter((e) => n.include.includes(e.name));
234
- else {
235
- let a = n.root || process.cwd(), o = t.join(a, "package.json");
236
- if (e.existsSync(o)) try {
237
- let t = JSON.parse(e.readFileSync(o, "utf8"));
238
- if (t["framework-m"]?.plugin) {
239
- let e = t.name;
240
- h() && console.info(`[framework-m/vite-plugin] Local package.json is a plugin (${e}). Selective bundling enabled.`), i = r.filter((t) => t.name === e);
241
- } else h() && console.info(`[framework-m/vite-plugin] Local package.json is NOT a plugin (shell mode). Bundling all ${r.length} plugins.`), i = r;
242
- } catch {
243
- i = r;
244
- }
245
- else i = r;
246
- }
247
- return n.exclude && n.exclude.length > 0 && (i = i.filter((e) => !n.exclude.includes(e.name))), i;
248
- };
249
- return {
250
- name: "framework-m-plugin",
251
- async config(e) {
252
- let t = n.root || process.cwd();
253
- console.info(`[framework-m/vite-plugin] Config phase: root=${t}, cwd=${process.cwd()}`), r = v(n.root);
254
- let c = await o(n.root);
255
- console.info(`[framework-m/vite-plugin] Scanner found ${c.length} plugins in workspace`), i = s(c), console.info(`[framework-m/vite-plugin] After filtering: ${i.length} plugins`), a = S(i);
256
- let l = e.build?.rollupOptions?.output, u = (Array.isArray(l) ? l : [l ?? {}]).map((e) => {
257
- let t = e.manualChunks;
258
- return {
259
- ...e,
260
- manualChunks(e, n) {
261
- let r = C(e, a);
262
- if (r) return r;
263
- if (typeof t == "function") return t(e, n);
264
- }
265
- };
266
- });
267
- return { build: { rollupOptions: { output: Array.isArray(l) ? u : u[0] } } };
268
- },
269
- async buildStart() {
270
- let e = n.root;
271
- r = v(e);
272
- let t = await o(e);
273
- i = s(t), a = S(i);
274
- let c = i.map((e) => e.name).join(", "), l = i.length > 0 ? "" : " (shell app / runtime discovery)";
275
- if (g.info(i.length > 0 ? `Discovered ${i.length} Framework M plugin(s): ${c}${l}` : `Discovered 0 Framework M plugins${l}`), i.length > 0) {
276
- g.debug(`✓ Discovered ${i.length} Framework M plugin(s):`);
277
- for (let e of i) g.debug(` - ${e.name}`);
278
- } else g.debug("ℹ No Framework M plugins found in workspace");
279
- },
280
- resolveId(e) {
281
- if (e === d) return f;
282
- },
283
- load(e) {
284
- if (e === f) return l(i);
285
- },
286
- configureServer(e) {
287
- for (let n of i) {
288
- e.watcher.add(n.pluginConfigPath);
289
- let r = t.join(t.dirname(n.pluginConfigPath), "overrides");
290
- e.watcher.add(r);
291
- }
292
- for (let t of r) e.watcher.add(t);
293
- let c = async () => {
294
- r = v(n.root);
295
- let t = await o(n.root);
296
- i = s(t), a = S(i);
297
- for (let t of i) e.watcher.add(t.pluginConfigPath);
298
- for (let t of r) e.watcher.add(t);
299
- let c = e.moduleGraph.getModuleById(f);
300
- c && e.moduleGraph.invalidateModule(c), g.info("Plugin configuration changed, triggering reload"), e.ws.send({ type: "full-reload" });
301
- }, l = (e) => {
302
- let t = e.includes("plugin.config."), n = e.includes("/overrides/") && (e.endsWith(".tsx") || e.endsWith(".ts"));
303
- (t || n) && c();
304
- };
305
- e.watcher.on("change", l), e.watcher.on("add", l), e.watcher.on("unlink", l);
306
- }
307
- };
308
- }
309
- function v(r) {
310
- let i = r ?? process.cwd(), a = n("**/package.json", {
311
- cwd: i,
312
- absolute: !0,
313
- nodir: !0,
314
- ignore: ["**/node_modules/**", "**/dist/**"]
315
- }), o = [];
316
- for (let n of a) try {
317
- let r = e.readFileSync(n, "utf8"), i = JSON.parse(r)["framework-m"]?.plugin;
318
- if (typeof i != "string") continue;
319
- o.push(t.resolve(t.dirname(n), i));
320
- } catch {}
321
- return o.sort((e, t) => e.localeCompare(t));
341
+ function O(e) {
342
+ const t = e ?? process.cwd(), r = N("**/package.json", {
343
+ cwd: t,
344
+ absolute: !0,
345
+ nodir: !0,
346
+ ignore: ["**/node_modules/**", "**/dist/**"]
347
+ }), d = [];
348
+ for (const p of r)
349
+ try {
350
+ const n = h.readFileSync(p, "utf8"), c = JSON.parse(n)["framework-m"]?.plugin;
351
+ if (typeof c != "string")
352
+ continue;
353
+ d.push(l.resolve(l.dirname(p), c));
354
+ } catch {
355
+ }
356
+ return d.sort((p, n) => p.localeCompare(n));
322
357
  }
323
- function y(e) {
324
- return e.split("?")[0].split(t.sep).join("/");
358
+ function R(e) {
359
+ return e.split("?")[0].split(l.sep).join("/");
325
360
  }
326
- function b(e) {
327
- let n = t.dirname(e), r = t.basename(n);
328
- return r === "src" || r === "dist" ? t.dirname(n) : n;
361
+ function G(e) {
362
+ const t = l.dirname(e), r = l.basename(t);
363
+ return r === "src" || r === "dist" ? l.dirname(t) : t;
329
364
  }
330
- function x(e) {
331
- return (e.split("/").pop() || e).replaceAll(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
365
+ function T(e) {
366
+ return (e.split("/").pop() || e).replaceAll(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
332
367
  }
333
- function S(e) {
334
- return e.map((e) => ({
335
- prefix: y(b(e.pluginConfigPath)) + "/",
336
- chunkName: x(e.name)
337
- })).sort((e, t) => t.prefix.length - e.prefix.length);
368
+ function E(e) {
369
+ return e.map((t) => ({
370
+ prefix: R(G(t.pluginConfigPath)) + "/",
371
+ chunkName: T(t.name)
372
+ })).sort((t, r) => r.prefix.length - t.prefix.length);
338
373
  }
339
- function C(e, t) {
340
- let n = y(e);
341
- for (let e of t) if (n.startsWith(e.prefix)) return e.chunkName;
374
+ function W(e, t) {
375
+ const r = R(e);
376
+ for (const d of t)
377
+ if (r.startsWith(d.prefix))
378
+ return d.chunkName;
342
379
  }
343
- //#endregion
344
- export { m as ENV_DEBUG, p as ENV_VITE_DEBUG, _ as frameworkMPlugin, u as generateMfeConfig, l as generateVirtualModule, o as scanWorkspacePlugins };
345
-
346
- //# sourceMappingURL=index.js.map
380
+ export {
381
+ U as ENV_DEBUG,
382
+ J as ENV_VITE_DEBUG,
383
+ Z as frameworkMPlugin,
384
+ I as generateVirtualModule,
385
+ j as scanWorkspacePlugins
386
+ };
387
+ //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/scanner.ts","../src/codegen.ts","../src/mfe-config.ts","../src/index.ts"],"sourcesContent":["/**\n * Workspace Scanner\n *\n * Scans the monorepo workspace for packages that have \"framework-m\"\n * metadata in their package.json, indicating they are frontend plugins.\n *\n * A plugin package.json looks like:\n * ```json\n * {\n * \"name\": \"@my-company/wms\",\n * \"framework-m\": {\n * \"plugin\": \"./src/plugin.config.ts\",\n * \"type\": \"frontend-module\"\n * }\n * }\n * ```\n */\n\nimport fg from \"fast-glob\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\n/**\n * Represents a discovered Framework M plugin in the workspace.\n */\nexport interface DiscoveredPlugin {\n /** Package name from package.json (e.g., @finance/frontend) */\n name: string;\n /** Short name for easier filtering (e.g., finance) */\n shortName: string;\n /** Absolute path to the plugin config file */\n pluginConfigPath: string;\n}\n\n/**\n * Scan the workspace for packages with \"framework-m\" plugin metadata.\n *\n * @param root — workspace root directory to scan\n * @returns Array of discovered plugins with their config paths\n */\nexport async function scanWorkspacePlugins(root?: string): Promise<DiscoveredPlugin[]> {\n // Find workspace root by looking for pnpm-workspace.yaml\n const scanRoot = root || findWorkspaceRoot(process.cwd());\n\n // Find all package.json files in likely locations to avoid \"blackhole\" scanning\n // We prioritize patterns that match the monorepo structure\n const patterns = [\"**/package.json\"];\n const packageJsonPaths = await fg(patterns, {\n cwd: scanRoot,\n ignore: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/temp/**\",\n \"**/venv/**\",\n \"**/.venv/**\",\n \"**/.m/**\",\n \"**/__pycache__/**\",\n ],\n absolute: true,\n });\n\n const plugins: DiscoveredPlugin[] = [];\n\n for (const pkgPath of packageJsonPaths) {\n try {\n const content = fs.readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content) as Record<string, unknown>;\n\n // Check for framework-m plugin metadata\n const frameworkM = pkg[\"framework-m\"] as\n { plugin?: string; type?: string; name?: string } | undefined;\n\n if (frameworkM?.plugin) {\n const packageDir = path.dirname(pkgPath);\n const pluginConfigPath = path.resolve(packageDir, frameworkM.plugin);\n const packageName = (pkg.name as string) || path.basename(packageDir);\n\n let shortName = frameworkM.name;\n if (!shortName) {\n const relativePath = path.relative(scanRoot, packageDir);\n const parts = relativePath.split(path.sep);\n // If in apps/libs/packages, the next part is usually the app name\n if (parts.length > 1 && [\"apps\", \"libs\", \"packages\"].includes(parts[0])) {\n shortName = parts[1];\n } else {\n shortName = parts[0] || path.basename(packageDir);\n }\n }\n\n plugins.push({\n name: packageName,\n shortName,\n pluginConfigPath,\n });\n }\n } catch {\n // Skip unreadable or malformed package.json files\n continue;\n }\n }\n\n return plugins.sort((a, b) => {\n if (a.name === b.name) {\n return a.pluginConfigPath.localeCompare(b.pluginConfigPath);\n }\n return a.name.localeCompare(b.name);\n });\n}\n\n/**\n * Walk up from startDir to find the workspace root (directory containing pnpm-workspace.yaml).\n * Falls back to startDir if not found.\n */\nfunction findWorkspaceRoot(startDir: string): string {\n let dir = startDir;\n while (true) {\n if (fs.existsSync(path.join(dir, \"pnpm-workspace.yaml\"))) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break; // reached filesystem root\n dir = parent;\n }\n return startDir; // fallback\n}\n","/**\n * Virtual Module Code Generator\n *\n * Generates the code for the `virtual:framework-m-plugins` virtual module.\n * This module imports all discovered plugin configs and exports them as an array.\n *\n * Generated output looks like:\n * ```js\n * import plugin0 from '/workspace/apps/wms/frontend/src/plugin.config.ts';\n * import plugin1 from '/workspace/apps/hr/frontend/src/plugin.config.ts';\n * export default [plugin0, plugin1];\n * ```\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport fg from \"fast-glob\";\nimport type { DiscoveredPlugin } from \"./scanner\";\n\nfunction normalizePath(p: string): string {\n return p.split(path.sep).join(\"/\");\n}\n\n/**\n * Generate the virtual module source code for all discovered plugins.\n *\n * @param plugins — discovered plugins from workspace scanning\n * @returns JavaScript/TypeScript source code string\n */\nexport function generateVirtualModule(plugins: DiscoveredPlugin[]): string {\n if (plugins.length === 0) {\n return \"export default [];\\n\";\n }\n\n let imports = \"\";\n let enhancedPluginsCode = \"\";\n const exportNames: string[] = [];\n\n plugins.forEach((p, i) => {\n const pluginConfigPath = normalizePath(p.pluginConfigPath);\n imports += `import plugin${i} from '${pluginConfigPath}';\\n`;\n\n const srcDir = path.dirname(p.pluginConfigPath);\n const overridesDir = path.join(srcDir, \"overrides\");\n\n let hasOverrides = false;\n let pluginOverridesCode = `const enhancedPlugin${i} = {\\n ...plugin${i},\\n`;\n const doctypes: Record<string, string[]> = {};\n const globalPages: string[] = [];\n let traversalsImportName = \"\";\n\n if (fs.existsSync(overridesDir)) {\n const traversalsPath = path.join(overridesDir, \"traversals.ts\");\n if (fs.existsSync(traversalsPath)) {\n hasOverrides = true;\n traversalsImportName = `traversals_${i}`;\n imports += `import ${traversalsImportName} from '${normalizePath(traversalsPath)}';\\n`;\n }\n\n // Use forward slashes for fast-glob cwd to support Windows\n const globCwd = overridesDir.replace(/\\\\/g, \"/\");\n const overrideFiles = fg.sync(\"**/*.tsx\", {\n cwd: globCwd,\n absolute: true,\n });\n\n if (overrideFiles.length > 0) {\n hasOverrides = true;\n\n overrideFiles.forEach((file) => {\n const normalizedFile = normalizePath(file);\n const relativePath = normalizedFile.replace(normalizePath(overridesDir) + \"/\", \"\");\n const parts = relativePath.split(\"/\"); // e.g. ['Todo', 'FormView.tsx']\n\n if (parts.length === 2) {\n const folderName = parts[0];\n const fileName = parts[1].replace(\".tsx\", \"\");\n const importName = `${folderName}_${fileName}_${i}`;\n\n imports += `import ${importName} from '${normalizedFile}';\\n`;\n\n if (folderName === \"Core\") {\n globalPages.push(`{ name: '${fileName}', component: ${importName} }`);\n } else {\n if (!doctypes[folderName]) doctypes[folderName] = [];\n doctypes[folderName].push(`${fileName}: ${importName}`);\n }\n }\n });\n }\n }\n\n if (hasOverrides) {\n if (Object.keys(doctypes).length > 0) {\n pluginOverridesCode += ` doctypes: [\\n ...(plugin${i}.doctypes || []),\\n`;\n for (const [doctype, components] of Object.entries(doctypes)) {\n pluginOverridesCode += ` {\\n doctype: '${doctype}',\\n components: {\\n ${components.join(\",\\n \")}\\n }\\n },\\n`;\n }\n pluginOverridesCode += ` ],\\n`;\n }\n\n if (globalPages.length > 0) {\n pluginOverridesCode += ` pages: [\\n ...(plugin${i}.pages || []),\\n ${globalPages.join(\",\\n \")}\\n ],\\n`;\n }\n\n if (traversalsImportName) {\n pluginOverridesCode += ` traversals: ${traversalsImportName},\\n`;\n }\n\n pluginOverridesCode += `};\\n`;\n enhancedPluginsCode += pluginOverridesCode;\n exportNames.push(`enhancedPlugin${i}`);\n } else {\n exportNames.push(`plugin${i}`);\n }\n });\n\n const pluginsArray = `[${exportNames.join(\", \")}]`;\n return `${imports}\\n${enhancedPluginsCode}\\nexport const discoveredPlugins = ${pluginsArray};\\nexport default ${pluginsArray};\\n`;\n}\n","import { searchForWorkspaceRoot, type UserConfig } from \"vite\";\nimport { federation } from \"@module-federation/vite\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { frameworkMPlugin } from \"./index\";\n\ntype FederationOptions = Parameters<typeof federation>[0];\n\nexport interface MfeOptions {\n name: string;\n entry: string;\n shared?: FederationOptions[\"shared\"];\n serviceName?: string;\n}\n\nexport function generateMfeConfig(options: MfeOptions): UserConfig {\n return {\n resolve: {\n extensions: [\n \".web.mjs\",\n \".web.js\",\n \".web.jsx\",\n \".web.ts\",\n \".web.tsx\",\n \".mjs\",\n \".js\",\n \".mts\",\n \".ts\",\n \".jsx\",\n \".tsx\",\n \".json\",\n ],\n alias: {\n \"react-native\": \"react-native-web\",\n },\n dedupe: [\n \"react\",\n \"react-dom\",\n \"react-router\",\n \"react-router-dom\",\n \"@refinedev/core\",\n \"@framework-m/plugin-sdk\",\n \"@framework-m/ui\",\n \"@tanstack/react-query\",\n ],\n },\n optimizeDeps: {\n exclude: [\"@module-federation/dts-plugin\", \"@module-federation/sdk\"],\n esbuildOptions: {\n target: \"esnext\",\n resolveExtensions: [\".web.js\", \".web.ts\", \".web.tsx\", \".js\", \".jsx\", \".ts\", \".tsx\"],\n },\n },\n build: {\n target: \"esnext\",\n minify: true,\n cssCodeSplit: false,\n chunkSizeWarningLimit: 1000,\n },\n plugins: [\n frameworkMPlugin(),\n federation({\n name: options.name,\n filename: \"remoteEntry.js\",\n dev: true,\n dts: false,\n exposes: {\n \"./plugin\": options.entry,\n },\n shared: (() => {\n const mandatory = [\n \"react\",\n \"react-dom\",\n \"react-router\",\n \"@tanstack/react-query\",\n \"@refinedev/core\",\n \"@framework-m/ui\",\n \"@framework-m/plugin-sdk\",\n ];\n\n let inferredServiceName = options.serviceName;\n\n // Check for optional/transitive dependencies and service identity\n try {\n const pkgPath = path.join(process.cwd(), \"package.json\");\n if (fs.existsSync(pkgPath)) {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n\n if (!inferredServiceName && pkg[\"framework-m\"]?.service_name) {\n inferredServiceName = pkg[\"framework-m\"].service_name;\n }\n\n const deps = {\n ...(pkg.dependencies || {}),\n ...(pkg.devDependencies || {}),\n ...(pkg.peerDependencies || {}),\n };\n\n const optional = [\"react-router-dom\", \"tamagui\", \"@tamagui/core\", \"@tamagui/web\"];\n\n for (const opt of optional) {\n if (deps[opt]) {\n mandatory.push(opt);\n }\n }\n }\n } catch {\n // Skip extra checks\n }\n\n const sharedConfig: Record<string, Record<string, unknown>> = {};\n for (const pkg of mandatory) {\n if (pkg === \"@framework-m/plugin-sdk\" || pkg === \"@framework-m/ui\") {\n sharedConfig[pkg] = {\n singleton: true,\n import: `${pkg}/dist/index.js`,\n };\n } else {\n sharedConfig[pkg] = {\n singleton: true,\n };\n }\n }\n\n // Store inferred service name for use in define block\n (options as MfeOptions & { _resolvedServiceName?: string })._resolvedServiceName =\n inferredServiceName;\n\n const userShared = Array.isArray(options.shared)\n ? options.shared\n : typeof options.shared === \"object\" && options.shared !== null\n ? Object.entries(options.shared)\n : [];\n\n for (const item of userShared) {\n if (Array.isArray(item)) {\n const [pkg, config] = item as [string, Record<string, unknown>];\n sharedConfig[pkg] = config;\n }\n }\n\n return sharedConfig;\n })(),\n }),\n ],\n server: {\n proxy: {\n \"/api\": {\n target: process.env.VITE_DEV_BACKEND_URL || \"http://localhost:8080\",\n changeOrigin: true,\n secure: false,\n ws: true,\n },\n },\n fs: {\n allow: [\n searchForWorkspaceRoot(process.cwd()),\n ...(process.env.FRAMEWORK_M_ACTIVE_SHELL_ROOT\n ? [process.env.FRAMEWORK_M_ACTIVE_SHELL_ROOT]\n : []),\n ],\n },\n },\n define: {\n \"process.env.FRAMEWORK_M_SERVICE_NAME\": JSON.stringify(\n (options as MfeOptions & { _resolvedServiceName?: string })._resolvedServiceName ??\n process.env.FRAMEWORK_M_SERVICE_NAME\n ),\n \"process.env.VITE_DEV_BACKEND_URL\": JSON.stringify(\n process.env.VITE_DEV_BACKEND_URL || \"http://localhost:8080\"\n ),\n \"process.env.INSTALLED_APPS\": JSON.stringify(process.env.INSTALLED_APPS || \"\"),\n },\n };\n}\n","/**\n * @framework-m/vite-plugin\n *\n * Vite plugin for Framework M plugin auto-discovery and bundling.\n *\n * Scans the workspace for packages with \"framework-m\" metadata in their\n * package.json and generates a virtual module that imports all plugin\n * configs. The shell app can then import this virtual module to\n * bootstrap all plugins automatically.\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { frameworkMPlugin } from \"@framework-m/vite-plugin\";\n *\n * export default defineConfig({\n * plugins: [frameworkMPlugin()],\n * });\n * ```\n *\n * @example\n * ```ts\n * // In shell app:\n * // @ts-ignore - Virtual module generated by Vite plugin\n * import discoveredPlugins from \"virtual:framework-m-plugins\";\n *\n * for (const plugin of discoveredPlugins) {\n * await registry.register(plugin);\n * }\n * ```\n */\n\nimport type { Plugin } from \"vite\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { globSync } from \"glob\";\nimport { scanWorkspacePlugins } from \"./scanner\";\nimport { generateVirtualModule } from \"./codegen\";\nimport type { DiscoveredPlugin } from \"./scanner\";\n\nconst VIRTUAL_MODULE_ID = \"virtual:framework-m-plugins\";\nconst RESOLVED_VIRTUAL_MODULE_ID = \"\\0virtual:framework-m-plugins\";\n\n// Environment Variable Constants\nexport const ENV_VITE_DEBUG = \"FRAMEWORK_M_VITE_PLUGIN_DEBUG\";\nexport const ENV_DEBUG = \"FRAMEWORK_M_DEBUG\";\n\nfunction isDebugEnabled(): boolean {\n const env = typeof process !== \"undefined\" ? process.env : {};\n const envFlag = env[ENV_VITE_DEBUG] ?? env[ENV_DEBUG];\n\n if (typeof envFlag === \"string\") {\n return [\"1\", \"true\", \"yes\", \"on\"].includes(envFlag.toLowerCase());\n }\n\n return false;\n}\n\nconst pluginLogger = {\n info(message: string): void {\n console.info(`[framework-m/vite-plugin] ${message}`);\n },\n debug(message: string): void {\n if (isDebugEnabled()) {\n console.info(`[framework-m/vite-plugin] ${message}`);\n }\n },\n};\n\n/**\n * Options for the Framework M Vite plugin.\n */\nexport interface FrameworkMPluginOptions {\n /**\n * Root directory to scan for plugins. Defaults to process.cwd().\n */\n root?: string;\n\n /**\n * List of plugin names to include. If specified, only these plugins will be bundled.\n */\n include?: string[];\n\n /**\n * List of plugin names to exclude from bundling.\n */\n exclude?: string[];\n}\n\n/**\n * Create the Framework M Vite plugin.\n *\n * This plugin:\n * 1. Scans the workspace at build time for packages with \"framework-m\"\n * metadata in their package.json\n * 2. Generates a virtual module `virtual:framework-m-plugins` that imports\n * all discovered plugin configs\n * 3. The shell app imports this virtual module to auto-register all plugins\n */\nexport function frameworkMPlugin(options: FrameworkMPluginOptions = {}): Plugin {\n let pluginPaths: string[] = [];\n let discoveredPlugins: DiscoveredPlugin[] = [];\n let pluginChunkMatchers: Array<{ prefix: string; chunkName: string }> = [];\n\n const filterPlugins = (plugins: DiscoveredPlugin[]): DiscoveredPlugin[] => {\n let filtered = plugins;\n\n // 1. Filter discovered plugins based on include/exclude options\n\n if (options.include && options.include.length > 0) {\n if (isDebugEnabled()) {\n console.info(\n `[framework-m/vite-plugin] Applying explicit include filter: [${options.include.join(\", \")}]`\n );\n }\n filtered = plugins.filter((p) => options.include!.includes(p.name));\n } else {\n // Default behavior: if local package.json is a plugin, only bundle that plugin.\n // Otherwise (shell app), bundle all discovered plugins.\n const root = options.root || process.cwd();\n const localPackageJsonPath = path.join(root, \"package.json\");\n\n if (fs.existsSync(localPackageJsonPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(localPackageJsonPath, \"utf8\"));\n if (pkg[\"framework-m\"]?.plugin) {\n const localPluginName = pkg.name;\n if (isDebugEnabled()) {\n console.info(\n `[framework-m/vite-plugin] Local package.json is a plugin (${localPluginName}). Selective bundling enabled.`\n );\n }\n filtered = plugins.filter((p) => p.name === localPluginName);\n } else {\n if (isDebugEnabled()) {\n console.info(\n `[framework-m/vite-plugin] Local package.json is NOT a plugin (shell mode). Bundling all ${plugins.length} plugins.`\n );\n }\n filtered = plugins;\n }\n } catch {\n filtered = plugins;\n }\n } else {\n filtered = plugins;\n }\n }\n\n // 2. Apply explicit exclude list\n if (options.exclude && options.exclude.length > 0) {\n filtered = filtered.filter((p) => !options.exclude!.includes(p.name));\n }\n\n return filtered;\n };\n\n return {\n name: \"framework-m-plugin\",\n\n async config(userConfig) {\n const root = options.root || process.cwd();\n console.info(`[framework-m/vite-plugin] Config phase: root=${root}, cwd=${process.cwd()}`);\n pluginPaths = discoverPluginConfigPaths(options.root);\n const allPlugins = await scanWorkspacePlugins(options.root);\n console.info(\n `[framework-m/vite-plugin] Scanner found ${allPlugins.length} plugins in workspace`\n );\n discoveredPlugins = filterPlugins(allPlugins);\n console.info(\n `[framework-m/vite-plugin] After filtering: ${discoveredPlugins.length} plugins`\n );\n pluginChunkMatchers = createPluginChunkMatchers(discoveredPlugins);\n\n const existingOutput = userConfig.build?.rollupOptions?.output;\n const existingOutputs = Array.isArray(existingOutput)\n ? existingOutput\n : [existingOutput ?? {}];\n\n const mergedOutputs = existingOutputs.map((output) => {\n const existingManualChunks = output.manualChunks;\n\n return {\n ...output,\n manualChunks(id: string, meta: unknown) {\n const pluginChunk = findPluginChunkForModule(id, pluginChunkMatchers);\n if (pluginChunk) {\n return pluginChunk;\n }\n\n if (typeof existingManualChunks === \"function\") {\n return (existingManualChunks as (id: string, meta: unknown) => string | undefined)(\n id,\n meta\n );\n }\n\n return undefined;\n },\n };\n });\n\n return {\n build: {\n rollupOptions: {\n output: Array.isArray(existingOutput) ? mergedOutputs : mergedOutputs[0],\n },\n },\n };\n },\n\n /**\n * Discover plugins at build start.\n */\n async buildStart() {\n const root = options.root;\n pluginPaths = discoverPluginConfigPaths(root);\n const allPlugins = await scanWorkspacePlugins(root);\n discoveredPlugins = filterPlugins(allPlugins);\n pluginChunkMatchers = createPluginChunkMatchers(discoveredPlugins);\n\n const pluginNames = discoveredPlugins.map((p) => p.name).join(\", \");\n const filteringMsg = discoveredPlugins.length > 0 ? \"\" : \" (shell app / runtime discovery)\";\n\n pluginLogger.info(\n discoveredPlugins.length > 0\n ? `Discovered ${discoveredPlugins.length} Framework M plugin(s): ${pluginNames}${filteringMsg}`\n : `Discovered 0 Framework M plugins${filteringMsg}`\n );\n\n if (discoveredPlugins.length > 0) {\n pluginLogger.debug(`✓ Discovered ${discoveredPlugins.length} Framework M plugin(s):`);\n for (const p of discoveredPlugins) {\n pluginLogger.debug(` - ${p.name}`);\n }\n } else {\n pluginLogger.debug(\"ℹ No Framework M plugins found in workspace\");\n }\n },\n\n /**\n * Resolve the virtual module ID.\n */\n resolveId(id: string) {\n if (id === VIRTUAL_MODULE_ID) {\n return RESOLVED_VIRTUAL_MODULE_ID;\n }\n return undefined;\n },\n\n /**\n * Load the virtual module — generate code with all plugin imports.\n */\n load(id: string) {\n if (id === RESOLVED_VIRTUAL_MODULE_ID) {\n return generateVirtualModule(discoveredPlugins);\n }\n return undefined;\n },\n\n /**\n * HMR: Watch plugin config files for changes.\n */\n configureServer(server) {\n // Watch all discovered plugin config files\n for (const plugin of discoveredPlugins) {\n server.watcher.add(plugin.pluginConfigPath);\n // Watch the overrides directory for new files\n const overridesDir = path.join(path.dirname(plugin.pluginConfigPath), \"overrides\");\n server.watcher.add(overridesDir);\n }\n for (const pluginConfigPath of pluginPaths) {\n server.watcher.add(pluginConfigPath);\n }\n\n const refreshPlugins = async () => {\n pluginPaths = discoverPluginConfigPaths(options.root);\n const allPlugins = await scanWorkspacePlugins(options.root);\n discoveredPlugins = filterPlugins(allPlugins);\n pluginChunkMatchers = createPluginChunkMatchers(discoveredPlugins);\n for (const plugin of discoveredPlugins) {\n server.watcher.add(plugin.pluginConfigPath);\n }\n for (const pluginConfigPath of pluginPaths) {\n server.watcher.add(pluginConfigPath);\n }\n\n const virtualModule = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_MODULE_ID);\n if (virtualModule) {\n server.moduleGraph.invalidateModule(virtualModule);\n }\n\n pluginLogger.info(\"Plugin configuration changed, triggering reload\");\n server.ws.send({ type: \"full-reload\" });\n };\n\n const handleFileChange = (filePath: string) => {\n const isPluginConfig = filePath.includes(\"plugin.config.\");\n const isOverride =\n filePath.includes(\"/overrides/\") &&\n (filePath.endsWith(\".tsx\") || filePath.endsWith(\".ts\"));\n\n if (isPluginConfig || isOverride) {\n void refreshPlugins();\n }\n };\n\n server.watcher.on(\"change\", handleFileChange);\n server.watcher.on(\"add\", handleFileChange);\n server.watcher.on(\"unlink\", handleFileChange);\n },\n };\n}\n\nfunction discoverPluginConfigPaths(root?: string): string[] {\n const workspaceRoot = root ?? process.cwd();\n const packageJsonPaths = globSync(\"**/package.json\", {\n cwd: workspaceRoot,\n absolute: true,\n nodir: true,\n ignore: [\"**/node_modules/**\", \"**/dist/**\"],\n });\n\n const pluginPaths: string[] = [];\n for (const packageJsonPath of packageJsonPaths) {\n try {\n const packageRaw = fs.readFileSync(packageJsonPath, \"utf8\");\n const packageJson = JSON.parse(packageRaw) as {\n \"framework-m\"?: { plugin?: unknown };\n };\n\n const pluginConfig = packageJson[\"framework-m\"]?.plugin;\n if (typeof pluginConfig !== \"string\") {\n continue;\n }\n\n pluginPaths.push(path.resolve(path.dirname(packageJsonPath), pluginConfig));\n } catch {\n // Ignore invalid package.json files and continue scanning.\n }\n }\n\n return pluginPaths.sort((a, b) => a.localeCompare(b));\n}\n\nfunction normalizeModuleId(id: string): string {\n return id.split(\"?\")[0].split(path.sep).join(\"/\");\n}\n\nfunction inferPluginRoot(pluginConfigPath: string): string {\n const configDir = path.dirname(pluginConfigPath);\n const base = path.basename(configDir);\n if (base === \"src\" || base === \"dist\") {\n return path.dirname(configDir);\n }\n return configDir;\n}\n\nfunction toChunkName(pluginName: string): string {\n const tail = pluginName.split(\"/\").pop() || pluginName;\n return tail.replaceAll(/[^a-zA-Z0-9_-]/g, \"-\").toLowerCase();\n}\n\nfunction createPluginChunkMatchers(\n plugins: DiscoveredPlugin[]\n): Array<{ prefix: string; chunkName: string }> {\n return plugins\n .map((plugin) => ({\n prefix: normalizeModuleId(inferPluginRoot(plugin.pluginConfigPath)) + \"/\",\n chunkName: toChunkName(plugin.name),\n }))\n .sort((a, b) => b.prefix.length - a.prefix.length);\n}\n\nfunction findPluginChunkForModule(\n id: string,\n matchers: Array<{ prefix: string; chunkName: string }>\n): string | undefined {\n const normalizedId = normalizeModuleId(id);\n for (const matcher of matchers) {\n if (normalizedId.startsWith(matcher.prefix)) {\n return matcher.chunkName;\n }\n }\n return undefined;\n}\n\n// Re-export types and utilities\nexport type { DiscoveredPlugin } from \"./scanner\";\nexport { scanWorkspacePlugins } from \"./scanner\";\nexport { generateVirtualModule } from \"./codegen\";\nexport { generateMfeConfig } from \"./mfe-config\";\nexport type { MfeOptions } from \"./mfe-config\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/scanner.ts","../src/codegen.ts","../src/index.ts"],"sourcesContent":["/**\n * Workspace Scanner\n *\n * Scans the monorepo workspace for packages that have \"framework-m\"\n * metadata in their package.json, indicating they are frontend plugins.\n *\n * A plugin package.json looks like:\n * ```json\n * {\n * \"name\": \"@my-company/wms\",\n * \"framework-m\": {\n * \"plugin\": \"./src/plugin.config.ts\",\n * \"type\": \"frontend-module\"\n * }\n * }\n * ```\n */\n\nimport fg from \"fast-glob\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\n/**\n * Represents a discovered Framework M plugin in the workspace.\n */\nexport interface DiscoveredPlugin {\n /** Package name from package.json (e.g., @finance/frontend) */\n name: string;\n /** Short name for easier filtering (e.g., finance) */\n shortName: string;\n /** Absolute path to the plugin config file */\n pluginConfigPath: string;\n}\n\n/**\n * Scan the workspace for packages with \"framework-m\" plugin metadata.\n *\n * @param root — workspace root directory to scan\n * @returns Array of discovered plugins with their config paths\n */\nexport async function scanWorkspacePlugins(root?: string): Promise<DiscoveredPlugin[]> {\n // Find workspace root by looking for pnpm-workspace.yaml\n const scanRoot = root || findWorkspaceRoot(process.cwd());\n\n // Find all package.json files in likely locations to avoid \"blackhole\" scanning\n // We prioritize patterns that match the monorepo structure\n const patterns = [\"**/package.json\"];\n const packageJsonPaths = await fg(patterns, {\n cwd: scanRoot,\n ignore: [\n \"**/node_modules/**\",\n \"**/dist/**\",\n \"**/temp/**\",\n \"**/venv/**\",\n \"**/.venv/**\",\n \"**/.m/**\",\n \"**/__pycache__/**\",\n ],\n absolute: true,\n });\n\n const plugins: DiscoveredPlugin[] = [];\n\n for (const pkgPath of packageJsonPaths) {\n try {\n const content = fs.readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(content) as Record<string, unknown>;\n\n // Check for framework-m plugin metadata\n const frameworkM = pkg[\"framework-m\"] as\n { plugin?: string; type?: string; name?: string } | undefined;\n\n if (frameworkM?.plugin) {\n const packageDir = path.dirname(pkgPath);\n const pluginConfigPath = path.resolve(packageDir, frameworkM.plugin);\n const packageName = (pkg.name as string) || path.basename(packageDir);\n\n let shortName = frameworkM.name;\n if (!shortName) {\n const relativePath = path.relative(scanRoot, packageDir);\n const parts = relativePath.split(path.sep);\n // If in apps/libs/packages, the next part is usually the app name\n if (parts.length > 1 && [\"apps\", \"libs\", \"packages\"].includes(parts[0])) {\n shortName = parts[1];\n } else {\n shortName = parts[0] || path.basename(packageDir);\n }\n }\n\n plugins.push({\n name: packageName,\n shortName,\n pluginConfigPath,\n });\n }\n } catch {\n // Skip unreadable or malformed package.json files\n continue;\n }\n }\n\n return plugins.sort((a, b) => {\n if (a.name === b.name) {\n return a.pluginConfigPath.localeCompare(b.pluginConfigPath);\n }\n return a.name.localeCompare(b.name);\n });\n}\n\n/**\n * Walk up from startDir to find the workspace root (directory containing pnpm-workspace.yaml).\n * Falls back to startDir if not found.\n */\nfunction findWorkspaceRoot(startDir: string): string {\n let dir = startDir;\n while (true) {\n if (fs.existsSync(path.join(dir, \"pnpm-workspace.yaml\"))) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) break; // reached filesystem root\n dir = parent;\n }\n return startDir; // fallback\n}\n","/**\n * Virtual Module Code Generator\n *\n * Generates the code for the `virtual:framework-m-plugins` virtual module.\n * This module imports all discovered plugin configs and exports them as an array.\n *\n * Generated output looks like:\n * ```js\n * import plugin0 from '/workspace/apps/wms/frontend/src/plugin.config.ts';\n * import plugin1 from '/workspace/apps/hr/frontend/src/plugin.config.ts';\n * export default [plugin0, plugin1];\n * ```\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport fg from \"fast-glob\";\nimport type { DiscoveredPlugin } from \"./scanner\";\n\nfunction normalizePath(p: string): string {\n return p.split(path.sep).join(\"/\");\n}\n\n/**\n * Generate the virtual module source code for all discovered plugins.\n *\n * @param plugins — discovered plugins from workspace scanning\n * @returns JavaScript/TypeScript source code string\n */\nexport function generateVirtualModule(plugins: DiscoveredPlugin[]): string {\n if (plugins.length === 0) {\n return \"export default [];\\n\";\n }\n\n let imports = \"\";\n let enhancedPluginsCode = \"\";\n const exportNames: string[] = [];\n\n plugins.forEach((p, i) => {\n const pluginConfigPath = normalizePath(p.pluginConfigPath);\n imports += `import plugin${i} from '${pluginConfigPath}';\\n`;\n\n const srcDir = path.dirname(p.pluginConfigPath);\n const overridesDir = path.join(srcDir, \"overrides\");\n\n let hasOverrides = false;\n let pluginOverridesCode = `const enhancedPlugin${i} = {\\n ...plugin${i},\\n`;\n const doctypes: Record<string, string[]> = {};\n const globalPages: string[] = [];\n let traversalsImportName = \"\";\n\n if (fs.existsSync(overridesDir)) {\n const traversalsPath = path.join(overridesDir, \"traversals.ts\");\n if (fs.existsSync(traversalsPath)) {\n hasOverrides = true;\n traversalsImportName = `traversals_${i}`;\n imports += `import ${traversalsImportName} from '${normalizePath(traversalsPath)}';\\n`;\n }\n\n // Use forward slashes for fast-glob cwd to support Windows\n const globCwd = overridesDir.replace(/\\\\/g, \"/\");\n const overrideFiles = fg.sync(\"**/*.tsx\", {\n cwd: globCwd,\n absolute: true,\n });\n\n if (overrideFiles.length > 0) {\n hasOverrides = true;\n\n overrideFiles.forEach((file) => {\n const normalizedFile = normalizePath(file);\n const relativePath = normalizedFile.replace(normalizePath(overridesDir) + \"/\", \"\");\n const parts = relativePath.split(\"/\"); // e.g. ['Todo', 'FormView.tsx']\n\n if (parts.length === 2) {\n const folderName = parts[0];\n const fileName = parts[1].replace(\".tsx\", \"\");\n const importName = `${folderName}_${fileName}_${i}`;\n\n imports += `import ${importName} from '${normalizedFile}';\\n`;\n\n if (folderName === \"Core\") {\n globalPages.push(`{ name: '${fileName}', component: ${importName} }`);\n } else {\n if (!doctypes[folderName]) doctypes[folderName] = [];\n doctypes[folderName].push(`${fileName}: ${importName}`);\n }\n }\n });\n }\n }\n\n if (hasOverrides) {\n if (Object.keys(doctypes).length > 0) {\n pluginOverridesCode += ` doctypes: [\\n ...(plugin${i}.doctypes || []),\\n`;\n for (const [doctype, components] of Object.entries(doctypes)) {\n pluginOverridesCode += ` {\\n doctype: '${doctype}',\\n components: {\\n ${components.join(\",\\n \")}\\n }\\n },\\n`;\n }\n pluginOverridesCode += ` ],\\n`;\n }\n\n if (globalPages.length > 0) {\n pluginOverridesCode += ` pages: [\\n ...(plugin${i}.pages || []),\\n ${globalPages.join(\",\\n \")}\\n ],\\n`;\n }\n\n if (traversalsImportName) {\n pluginOverridesCode += ` traversals: ${traversalsImportName},\\n`;\n }\n\n pluginOverridesCode += `};\\n`;\n enhancedPluginsCode += pluginOverridesCode;\n exportNames.push(`enhancedPlugin${i}`);\n } else {\n exportNames.push(`plugin${i}`);\n }\n });\n\n const pluginsArray = `[${exportNames.join(\", \")}]`;\n return `${imports}\\n${enhancedPluginsCode}\\nexport const discoveredPlugins = ${pluginsArray};\\nexport default ${pluginsArray};\\n`;\n}\n","/**\n * @framework-m/vite-plugin\n *\n * Vite plugin for Framework M plugin auto-discovery and bundling.\n *\n * Scans the workspace for packages with \"framework-m\" metadata in their\n * package.json and generates a virtual module that imports all plugin\n * configs. The shell app can then import this virtual module to\n * bootstrap all plugins automatically.\n *\n * Also provides shared Vite config defaults (resolve extensions, dedupe,\n * aliases, vendor chunk splitting) so apps don't duplicate boilerplate.\n *\n * @example\n * ```ts\n * // vite.config.ts — minimal setup, shared defaults applied automatically\n * import { frameworkMPlugin } from \"@framework-m/vite-plugin\";\n *\n * export default defineConfig({\n * plugins: [react(), frameworkMPlugin()],\n * });\n * ```\n *\n * @example\n * ```ts\n * // vite.config.ts — with app-specific overrides\n * import { frameworkMPlugin } from \"@framework-m/vite-plugin\";\n *\n * export default defineConfig({\n * plugins: [react(), frameworkMPlugin({\n * server: { port: 5173 },\n * build: { outDir: \"./dist\" },\n * })],\n * });\n * ```\n *\n * @example\n * ```ts\n * // In shell app:\n * // @ts-ignore - Virtual module generated by Vite plugin\n * import discoveredPlugins from \"virtual:framework-m-plugins\";\n *\n * for (const plugin of discoveredPlugins) {\n * await registry.register(plugin);\n * }\n * ```\n */\n\nimport type { Plugin, UserConfig } from \"vite\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { globSync } from \"glob\";\nimport { scanWorkspacePlugins } from \"./scanner\";\nimport { generateVirtualModule } from \"./codegen\";\nimport type { DiscoveredPlugin } from \"./scanner\";\nconst VIRTUAL_MODULE_ID = \"virtual:framework-m-plugins\";\nconst RESOLVED_VIRTUAL_MODULE_ID = \"\\0virtual:framework-m-plugins\";\n\n// Environment Variable Constants\nexport const ENV_VITE_DEBUG = \"FRAMEWORK_M_VITE_PLUGIN_DEBUG\";\nexport const ENV_DEBUG = \"FRAMEWORK_M_DEBUG\";\n\nfunction isDebugEnabled(): boolean {\n const env = typeof process !== \"undefined\" ? process.env : {};\n const envFlag = env[ENV_VITE_DEBUG] ?? env[ENV_DEBUG];\n\n if (typeof envFlag === \"string\") {\n return [\"1\", \"true\", \"yes\", \"on\"].includes(envFlag.toLowerCase());\n }\n\n return false;\n}\n\nconst pluginLogger = {\n info(message: string): void {\n console.info(`[framework-m/vite-plugin] ${message}`);\n },\n debug(message: string): void {\n if (isDebugEnabled()) {\n console.info(`[framework-m/vite-plugin] ${message}`);\n }\n },\n};\n\n/**\n * Shared resolve extensions for react-native-web compat.\n * Applied as defaults by frameworkMPlugin(); apps can override.\n */\nconst SHARED_RESOLVE_EXTENSIONS = [\n \".web.mjs\",\n \".web.js\",\n \".web.jsx\",\n \".web.ts\",\n \".web.tsx\",\n \".mjs\",\n \".js\",\n \".mts\",\n \".ts\",\n \".jsx\",\n \".tsx\",\n \".json\",\n];\n\n/**\n * Shared dedupe list — singleton libraries that must only have one copy.\n */\nconst SHARED_DEDUPE = [\n \"react\",\n \"react-dom\",\n \"@tanstack/react-query\",\n \"@refinedev/core\",\n \"react-router\",\n \"react-router-dom\",\n \"react-i18next\",\n \"i18next\",\n];\n\n/**\n * Options for the Framework M Vite plugin.\n */\nexport interface FrameworkMPluginOptions {\n /**\n * Root directory to scan for plugins. Defaults to process.cwd().\n */\n root?: string;\n\n /**\n * List of plugin names to include. If specified, only these plugins will be bundled.\n */\n include?: string[];\n\n /**\n * List of plugin names to exclude from bundling.\n */\n exclude?: string[];\n\n /**\n * App-specific Vite config overrides.\n * Deep-merged on top of the shared defaults provided by this plugin.\n *\n * @example\n * ```ts\n * frameworkMPlugin({\n * server: { port: 5173 },\n * build: { outDir: \"./dist\" },\n * })\n * ```\n */\n server?: UserConfig[\"server\"];\n build?: UserConfig[\"build\"];\n define?: UserConfig[\"define\"];\n resolve?: UserConfig[\"resolve\"];\n optimizeDeps?: UserConfig[\"optimizeDeps\"];\n}\n\n/**\n * Create the Framework M Vite plugin.\n *\n * This plugin:\n * 1. Provides shared Vite config defaults (resolve extensions, dedupe,\n * react-native-web alias, vendor chunk splitting) — eliminating\n * boilerplate duplication across apps\n * 2. Scans the workspace at build time for packages with \"framework-m\"\n * metadata in their package.json\n * 3. Generates a virtual module `virtual:framework-m-plugins` that imports\n * all discovered plugin configs\n * 4. The shell app imports this virtual module to auto-register all plugins\n */\nexport function frameworkMPlugin(options: FrameworkMPluginOptions = {}): Plugin {\n let pluginPaths: string[] = [];\n let discoveredPlugins: DiscoveredPlugin[] = [];\n let pluginChunkMatchers: Array<{ prefix: string; chunkName: string }> = [];\n\n const filterPlugins = (plugins: DiscoveredPlugin[]): DiscoveredPlugin[] => {\n let filtered = plugins;\n\n // 1. Filter discovered plugins based on include/exclude options\n\n if (options.include && options.include.length > 0) {\n if (isDebugEnabled()) {\n console.info(\n `[framework-m/vite-plugin] Applying explicit include filter: [${options.include.join(\", \")}]`\n );\n }\n filtered = plugins.filter((p) => options.include!.includes(p.name));\n } else {\n // Default behavior: if local package.json is a plugin, only bundle that plugin.\n // Otherwise (shell app), bundle all discovered plugins.\n const root = options.root || process.cwd();\n const localPackageJsonPath = path.join(root, \"package.json\");\n\n if (fs.existsSync(localPackageJsonPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(localPackageJsonPath, \"utf8\"));\n if (pkg[\"framework-m\"]?.plugin) {\n const localPluginName = pkg.name;\n if (isDebugEnabled()) {\n console.info(\n `[framework-m/vite-plugin] Local package.json is a plugin (${localPluginName}). Selective bundling enabled.`\n );\n }\n filtered = plugins.filter((p) => p.name === localPluginName);\n } else {\n if (isDebugEnabled()) {\n console.info(\n `[framework-m/vite-plugin] Local package.json is NOT a plugin (shell mode). Bundling all ${plugins.length} plugins.`\n );\n }\n filtered = plugins;\n }\n } catch {\n filtered = plugins;\n }\n } else {\n filtered = plugins;\n }\n }\n\n // 2. Apply explicit exclude list\n if (options.exclude && options.exclude.length > 0) {\n filtered = filtered.filter((p) => !options.exclude!.includes(p.name));\n }\n\n return filtered;\n };\n\n return {\n name: \"framework-m-plugin\",\n\n async config(userConfig) {\n const root = options.root || process.cwd();\n console.info(`[framework-m/vite-plugin] Config phase: root=${root}, cwd=${process.cwd()}`);\n pluginPaths = discoverPluginConfigPaths(options.root);\n const allPlugins = await scanWorkspacePlugins(options.root);\n console.info(\n `[framework-m/vite-plugin] Scanner found ${allPlugins.length} plugins in workspace`\n );\n discoveredPlugins = filterPlugins(allPlugins);\n console.info(\n `[framework-m/vite-plugin] After filtering: ${discoveredPlugins.length} plugins`\n );\n pluginChunkMatchers = createPluginChunkMatchers(discoveredPlugins);\n\n // --- Shared defaults ---\n // Build the manualChunks function that combines:\n // 1. Per-plugin chunk splitting (discovered plugins)\n // 2. Vendor chunk splitting (shared defaults)\n // 3. Any existing manualChunks from user config (preserved)\n const existingOutput = userConfig.build?.rollupOptions?.output;\n const existingOutputs = Array.isArray(existingOutput)\n ? existingOutput\n : [existingOutput ?? {}];\n\n const mergedOutputs = existingOutputs.map((output) => {\n const existingManualChunks = output.manualChunks;\n\n return {\n ...output,\n manualChunks(id: string, meta: unknown) {\n // 1. Per-plugin chunks (discovery)\n const pluginChunk = findPluginChunkForModule(id, pluginChunkMatchers);\n if (pluginChunk) {\n return pluginChunk;\n }\n\n // 2. User's existing manualChunks (if any)\n if (typeof existingManualChunks === \"function\") {\n const userResult = (\n existingManualChunks as (id: string, meta: unknown) => string | undefined\n )(id, meta);\n if (userResult) return userResult;\n }\n\n // 3. Shared vendor chunk splitting defaults\n if (id.includes(\"node_modules\")) {\n if (\n id.includes(\"node_modules/react/\") ||\n id.includes(\"node_modules/react-dom/\") ||\n id.includes(\"node_modules/scheduler/\")\n ) {\n return \"vendor-react\";\n }\n if (id.includes(\"@refinedev\")) {\n return \"vendor-refine\";\n }\n if (id.includes(\"@tamagui/lucide-icons\") || id.includes(\"lucide-icons\")) {\n return \"vendor-icons\";\n }\n if (id.includes(\"@tamagui\") || id.includes(\"tamagui\")) {\n return \"vendor-tamagui\";\n }\n if (\n id.includes(\"@tanstack\") ||\n id.includes(\"i18next\") ||\n id.includes(\"react-router\")\n ) {\n return \"vendor-utils\";\n }\n }\n\n return undefined;\n },\n };\n });\n\n // Merge shared defaults + user overrides from options\n const sharedConfig: UserConfig = {\n define: {\n \"process.env\": {},\n ...options.define,\n },\n resolve: {\n extensions: options.resolve?.extensions ?? SHARED_RESOLVE_EXTENSIONS,\n dedupe: options.resolve?.dedupe ?? SHARED_DEDUPE,\n alias: [\n {\n find: \"@react-native/assets-registry/registry\",\n replacement: \"react-native-web/dist/modules/AssetRegistry/index.js\",\n },\n { find: /^react-native$/, replacement: \"react-native-web\" },\n // Spread any additional aliases from user config or options\n ...(Array.isArray(userConfig.resolve?.alias) ? userConfig.resolve.alias : []),\n ...(Array.isArray(options.resolve?.alias) ? options.resolve.alias : []),\n ],\n },\n optimizeDeps: options.optimizeDeps ?? {},\n build: {\n ...options.build,\n rollupOptions: {\n ...options.build?.rollupOptions,\n output: Array.isArray(existingOutput) ? mergedOutputs : mergedOutputs[0],\n },\n },\n server: options.server,\n };\n\n return sharedConfig;\n },\n\n /**\n * Discover plugins at build start.\n */\n async buildStart() {\n const root = options.root;\n pluginPaths = discoverPluginConfigPaths(root);\n const allPlugins = await scanWorkspacePlugins(root);\n discoveredPlugins = filterPlugins(allPlugins);\n pluginChunkMatchers = createPluginChunkMatchers(discoveredPlugins);\n\n const pluginNames = discoveredPlugins.map((p) => p.name).join(\", \");\n const filteringMsg = discoveredPlugins.length > 0 ? \"\" : \" (shell app / runtime discovery)\";\n\n pluginLogger.info(\n discoveredPlugins.length > 0\n ? `Discovered ${discoveredPlugins.length} Framework M plugin(s): ${pluginNames}${filteringMsg}`\n : `Discovered 0 Framework M plugins${filteringMsg}`\n );\n\n if (discoveredPlugins.length > 0) {\n pluginLogger.debug(`✓ Discovered ${discoveredPlugins.length} Framework M plugin(s):`);\n for (const p of discoveredPlugins) {\n pluginLogger.debug(` - ${p.name}`);\n }\n } else {\n pluginLogger.debug(\"ℹ No Framework M plugins found in workspace\");\n }\n },\n\n /**\n * Resolve the virtual module ID.\n */\n resolveId(id: string) {\n if (id === VIRTUAL_MODULE_ID) {\n return RESOLVED_VIRTUAL_MODULE_ID;\n }\n return undefined;\n },\n\n /**\n * Load the virtual module — generate code with all plugin imports.\n */\n load(id: string) {\n if (id === RESOLVED_VIRTUAL_MODULE_ID) {\n return generateVirtualModule(discoveredPlugins);\n }\n return undefined;\n },\n\n /**\n * HMR: Watch plugin config files for changes.\n */\n configureServer(server) {\n // Watch all discovered plugin config files\n for (const plugin of discoveredPlugins) {\n server.watcher.add(plugin.pluginConfigPath);\n // Watch the overrides directory for new files\n const overridesDir = path.join(path.dirname(plugin.pluginConfigPath), \"overrides\");\n server.watcher.add(overridesDir);\n }\n for (const pluginConfigPath of pluginPaths) {\n server.watcher.add(pluginConfigPath);\n }\n\n const refreshPlugins = async () => {\n pluginPaths = discoverPluginConfigPaths(options.root);\n const allPlugins = await scanWorkspacePlugins(options.root);\n discoveredPlugins = filterPlugins(allPlugins);\n pluginChunkMatchers = createPluginChunkMatchers(discoveredPlugins);\n for (const plugin of discoveredPlugins) {\n server.watcher.add(plugin.pluginConfigPath);\n }\n for (const pluginConfigPath of pluginPaths) {\n server.watcher.add(pluginConfigPath);\n }\n\n const virtualModule = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_MODULE_ID);\n if (virtualModule) {\n server.moduleGraph.invalidateModule(virtualModule);\n }\n\n pluginLogger.info(\"Plugin configuration changed, triggering reload\");\n\n // Vite 7+: server.ws was replaced by server.hot\n // Support both for backward compat with Vite 5/6\n const serverAny = server as unknown as Record<string, unknown>;\n const hot = serverAny.hot ?? serverAny.ws;\n if (hot && typeof (hot as Record<string, unknown>).send === \"function\") {\n (hot as { send: (data: unknown) => void }).send({ type: \"full-reload\" });\n }\n };\n\n const handleFileChange = (filePath: string) => {\n const isPluginConfig = filePath.includes(\"plugin.config.\");\n const isOverride =\n filePath.includes(\"/overrides/\") &&\n (filePath.endsWith(\".tsx\") || filePath.endsWith(\".ts\"));\n\n if (isPluginConfig || isOverride) {\n void refreshPlugins();\n }\n };\n\n server.watcher.on(\"change\", handleFileChange);\n server.watcher.on(\"add\", handleFileChange);\n server.watcher.on(\"unlink\", handleFileChange);\n },\n\n /**\n * Inject runtime compatibility shims (e.g. CommonJS require fallback for Vite 8/Rolldown).\n */\n transformIndexHtml() {\n return [\n {\n tag: \"script\",\n attrs: { type: \"module\" },\n children: `import * as React from 'react';\nimport * as ReactDOM from 'react-dom';\nif (typeof window !== 'undefined') {\n window.require = (id) => {\n if (id === 'react') return React;\n if (id === 'react-dom') return ReactDOM;\n if (id === 'react-dom/client') return ReactDOM;\n console.warn('[CJS Shim] Dynamic require called for: ' + id);\n return {};\n };\n}`,\n injectTo: \"head-prepend\",\n },\n ];\n },\n };\n}\n\nfunction discoverPluginConfigPaths(root?: string): string[] {\n const workspaceRoot = root ?? process.cwd();\n const packageJsonPaths = globSync(\"**/package.json\", {\n cwd: workspaceRoot,\n absolute: true,\n nodir: true,\n ignore: [\"**/node_modules/**\", \"**/dist/**\"],\n });\n\n const pluginPaths: string[] = [];\n for (const packageJsonPath of packageJsonPaths) {\n try {\n const packageRaw = fs.readFileSync(packageJsonPath, \"utf8\");\n const packageJson = JSON.parse(packageRaw) as {\n \"framework-m\"?: { plugin?: unknown };\n };\n\n const pluginConfig = packageJson[\"framework-m\"]?.plugin;\n if (typeof pluginConfig !== \"string\") {\n continue;\n }\n\n pluginPaths.push(path.resolve(path.dirname(packageJsonPath), pluginConfig));\n } catch {\n // Ignore invalid package.json files and continue scanning.\n }\n }\n\n return pluginPaths.sort((a, b) => a.localeCompare(b));\n}\n\nfunction normalizeModuleId(id: string): string {\n return id.split(\"?\")[0].split(path.sep).join(\"/\");\n}\n\nfunction inferPluginRoot(pluginConfigPath: string): string {\n const configDir = path.dirname(pluginConfigPath);\n const base = path.basename(configDir);\n if (base === \"src\" || base === \"dist\") {\n return path.dirname(configDir);\n }\n return configDir;\n}\n\nfunction toChunkName(pluginName: string): string {\n const tail = pluginName.split(\"/\").pop() || pluginName;\n return tail.replaceAll(/[^a-zA-Z0-9_-]/g, \"-\").toLowerCase();\n}\n\nfunction createPluginChunkMatchers(\n plugins: DiscoveredPlugin[]\n): Array<{ prefix: string; chunkName: string }> {\n return plugins\n .map((plugin) => ({\n prefix: normalizeModuleId(inferPluginRoot(plugin.pluginConfigPath)) + \"/\",\n chunkName: toChunkName(plugin.name),\n }))\n .sort((a, b) => b.prefix.length - a.prefix.length);\n}\n\nfunction findPluginChunkForModule(\n id: string,\n matchers: Array<{ prefix: string; chunkName: string }>\n): string | undefined {\n const normalizedId = normalizeModuleId(id);\n for (const matcher of matchers) {\n if (normalizedId.startsWith(matcher.prefix)) {\n return matcher.chunkName;\n }\n }\n return undefined;\n}\n\n// Re-export types and utilities\nexport type { DiscoveredPlugin } from \"./scanner\";\nexport { scanWorkspacePlugins } from \"./scanner\";\nexport { generateVirtualModule } from \"./codegen\";\n"],"names":["scanWorkspacePlugins","root","scanRoot","findWorkspaceRoot","packageJsonPaths","fg","plugins","pkgPath","content","fs","pkg","frameworkM","packageDir","path","pluginConfigPath","packageName","shortName","parts","a","b","startDir","dir","parent","normalizePath","p","generateVirtualModule","imports","enhancedPluginsCode","exportNames","i","srcDir","overridesDir","hasOverrides","pluginOverridesCode","doctypes","globalPages","traversalsImportName","traversalsPath","globCwd","overrideFiles","file","normalizedFile","folderName","fileName","importName","doctype","components","pluginsArray","VIRTUAL_MODULE_ID","RESOLVED_VIRTUAL_MODULE_ID","ENV_VITE_DEBUG","ENV_DEBUG","isDebugEnabled","env","envFlag","pluginLogger","message","SHARED_RESOLVE_EXTENSIONS","SHARED_DEDUPE","frameworkMPlugin","options","pluginPaths","discoveredPlugins","pluginChunkMatchers","filterPlugins","filtered","localPackageJsonPath","localPluginName","userConfig","discoverPluginConfigPaths","allPlugins","createPluginChunkMatchers","existingOutput","mergedOutputs","output","existingManualChunks","id","meta","pluginChunk","findPluginChunkForModule","userResult","pluginNames","filteringMsg","server","plugin","refreshPlugins","virtualModule","serverAny","hot","handleFileChange","filePath","isPluginConfig","isOverride","workspaceRoot","globSync","packageJsonPath","packageRaw","pluginConfig","normalizeModuleId","inferPluginRoot","configDir","base","toChunkName","pluginName","matchers","normalizedId","matcher"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@framework-m/vite-plugin",
3
- "version": "0.9.6",
3
+ "version": "0.11.0",
4
4
  "description": "Vite plugin for Framework M plugin auto-discovery and bundling",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -30,15 +30,13 @@
30
30
  "directory": "libs/framework-m-vite-plugin"
31
31
  },
32
32
  "peerDependencies": {
33
- "vite": "^5.0.0 || ^6.0.0"
33
+ "vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
34
34
  },
35
35
  "dependencies": {
36
- "@framework-m/plugin-sdk": "^0.8.6",
37
- "@module-federation/vite": "^1.20.7",
36
+ "@framework-m/plugin-sdk": "^0.9.0",
38
37
  "fast-glob": "^3.3.3",
39
38
  "glob": "^13.0.6",
40
- "smol-toml": "^1.8.0",
41
- "vite": "^8.2.1"
39
+ "smol-toml": "^1.8.0"
42
40
  },
43
41
  "devDependencies": {
44
42
  "@types/node": "^26.2.0",
@@ -1,12 +0,0 @@
1
- import { UserConfig } from 'vite';
2
- import { federation } from '@module-federation/vite';
3
- type FederationOptions = Parameters<typeof federation>[0];
4
- export interface MfeOptions {
5
- name: string;
6
- entry: string;
7
- shared?: FederationOptions["shared"];
8
- serviceName?: string;
9
- }
10
- export declare function generateMfeConfig(options: MfeOptions): UserConfig;
11
- export {};
12
- //# sourceMappingURL=mfe-config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mfe-config.d.ts","sourceRoot":"","sources":["../src/mfe-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAKrD,KAAK,iBAAiB,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAE1D,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,CA+JjE"}