@kb-labs/studio-plugin-tools 2.43.0 → 2.45.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
@@ -39,6 +39,12 @@ interface KbStudioRemoteOptions {
39
39
  filename?: string;
40
40
  /** Output directory (default: 'dist/widgets') */
41
41
  outputDir?: string;
42
+ /**
43
+ * Generate TypeScript types for exposed modules (MF v2 dts feature).
44
+ * Studio host picks them up automatically in dev via @mf-types/.
45
+ * Default: true in development, false in production.
46
+ */
47
+ dts?: boolean;
42
48
  }
43
49
  declare function createStudioRemoteConfig(options: KbStudioRemoteOptions): Promise<Record<string, unknown>>;
44
50
 
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/index.ts
2
2
  var STUDIO_SHARED_DEPS = {
3
- react: { singleton: true, requiredVersion: "^18.3.0" },
4
- "react-dom": { singleton: true, requiredVersion: "^18.3.0" },
3
+ react: { singleton: true, requiredVersion: "^19.0.0" },
4
+ "react-dom": { singleton: true, requiredVersion: "^19.0.0" },
5
5
  "react-router-dom": { singleton: true, requiredVersion: "^7.0.0" },
6
6
  antd: { singleton: true, requiredVersion: "^5.21.0" },
7
7
  "@ant-design/icons": { singleton: true, requiredVersion: "^5.4.0" },
@@ -29,21 +29,21 @@ async function validateReactVersion(resolve) {
29
29
  }
30
30
  const majorStr = reactVersion.split(".").at(0) ?? "0";
31
31
  const major = parseInt(majorStr, 10);
32
- if (major >= 19) {
32
+ if (major >= 20) {
33
33
  throw new Error(
34
34
  `
35
35
 
36
36
  \u274C Studio plugin build failed: React ${reactVersion} detected.
37
37
 
38
- Studio host runs React 18. When a plugin bundles React 19, elements use
39
- Symbol.for('react.transitional.element') which React 18 cannot reconcile,
38
+ Studio host runs React 19. When a plugin bundles React 20+, elements may
39
+ use a different internal symbol which React 19 cannot reconcile,
40
40
  causing "Objects are not valid as a React child" crash at runtime.
41
41
 
42
- Fix: pin React 18 in your plugin's devDependencies:
42
+ Fix: pin React 19 in your plugin's devDependencies:
43
43
 
44
44
  "devDependencies": {
45
- "react": "^18.3.1",
46
- "react-dom": "^18.3.1"
45
+ "react": "^19.0.0",
46
+ "react-dom": "^19.0.0"
47
47
  }
48
48
 
49
49
  Then reinstall and rebuild:
@@ -60,7 +60,9 @@ async function createStudioRemoteConfig(options) {
60
60
  const { createRequire } = await import('module');
61
61
  const require2 = createRequire(import.meta.url);
62
62
  await validateReactVersion(require2.resolve);
63
+ const isDev = process.env.NODE_ENV !== "production";
63
64
  const outputDir = options.outputDir ?? "dist/widgets";
65
+ const enableDts = options.dts ?? isDev;
64
66
  return {
65
67
  entry: {},
66
68
  output: {
@@ -104,6 +106,8 @@ async function createStudioRemoteConfig(options) {
104
106
  new ModuleFederationPlugin({
105
107
  name: options.name,
106
108
  filename: options.filename ?? "remoteEntry.js",
109
+ manifest: true,
110
+ dts: enableDts ? { generateTypes: true } : false,
107
111
  exposes: options.exposes,
108
112
  shared: {
109
113
  ...STUDIO_SHARED_DEPS,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"names":["require"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @kb-labs/studio-plugin-tools\n *\n * Build tooling for plugin Studio pages (Module Federation remotes).\n * Uses Rspack with @module-federation/enhanced for native MF support.\n *\n * @example\n * ```typescript\n * // rspack.studio.config.ts\n * const { createStudioRemoteConfig } = require('@kb-labs/studio-plugin-tools');\n *\n * module.exports = createStudioRemoteConfig({\n * name: 'commitPlugin',\n * exposes: {\n * './CommitOverview': './src/studio/pages/CommitOverview.tsx',\n * },\n * });\n * ```\n */\n\n/**\n * Shared dependencies that match the Studio host.\n * Loaded once by the host — remotes reuse them via MF shared scope.\n */\nexport const STUDIO_SHARED_DEPS: Record<string, { singleton: boolean; requiredVersion: string }> = {\n react: { singleton: true, requiredVersion: '^18.3.0' },\n 'react-dom': { singleton: true, requiredVersion: '^18.3.0' },\n 'react-router-dom': { singleton: true, requiredVersion: '^7.0.0' },\n antd: { singleton: true, requiredVersion: '^5.21.0' },\n '@ant-design/icons': { singleton: true, requiredVersion: '^5.4.0' },\n '@tanstack/react-query': { singleton: true, requiredVersion: '^5.0.0' },\n zustand: { singleton: true, requiredVersion: '^5.0.0' },\n '@kb-labs/studio-hooks': { singleton: true, requiredVersion: '^0.1.0' },\n '@kb-labs/studio-event-bus': { singleton: true, requiredVersion: '^0.1.0' },\n '@kb-labs/studio-ui-kit': { singleton: true, requiredVersion: '^0.1.0' },\n '@kb-labs/studio-ui-core': { singleton: true, requiredVersion: '^0.1.0' },\n '@kb-labs/sdk': { singleton: true, requiredVersion: '^0.1.0' },\n};\n\nexport interface KbStudioRemoteOptions {\n /** Module Federation remote name (must match manifest remoteName) */\n name: string;\n /** Exposed modules: { './PageName': './src/studio/pages/PageName.tsx' } */\n exposes: Record<string, string>;\n /** Override or extend shared deps */\n shared?: Record<string, { singleton?: boolean; requiredVersion?: string }>;\n /** Remote entry filename (default: 'remoteEntry.js') */\n filename?: string;\n /** Output directory (default: 'dist/widgets') */\n outputDir?: string;\n}\n\n/**\n * Create a complete Rspack config for building a plugin as an MF remote.\n *\n * Returns a full rspack config object — use as default export in rspack.config.mjs.\n * Uses dynamic import internally to avoid CJS/ESM issues.\n */\n/**\n * Validate React version in the calling plugin's node_modules.\n * Studio host uses React 18 — React 19 causes MF element type mismatch at runtime.\n */\nasync function validateReactVersion(resolve: (id: string) => string): Promise<void> {\n const fs = await import('fs');\n\n const reactVersion = await (async (): Promise<string | null> => {\n try {\n const reactPkgPath = resolve('react/package.json');\n const reactPkg = JSON.parse(fs.readFileSync(reactPkgPath, 'utf8')) as { version: string };\n return reactPkg.version ?? null;\n } catch {\n return null;\n }\n })();\n\n if (!reactVersion) {return;}\n\n const majorStr = reactVersion.split('.').at(0) ?? '0';\n const major = parseInt(majorStr, 10);\n if (major >= 19) {\n throw new Error(\n `\\n\\n❌ Studio plugin build failed: React ${reactVersion} detected.\\n\\n` +\n `Studio host runs React 18. When a plugin bundles React 19, elements use\\n` +\n `Symbol.for('react.transitional.element') which React 18 cannot reconcile,\\n` +\n `causing \"Objects are not valid as a React child\" crash at runtime.\\n\\n` +\n `Fix: pin React 18 in your plugin's devDependencies:\\n\\n` +\n ` \"devDependencies\": {\\n` +\n ` \"react\": \"^18.3.1\",\\n` +\n ` \"react-dom\": \"^18.3.1\"\\n` +\n ` }\\n\\n` +\n `Then reinstall and rebuild:\\n\\n` +\n ` pnpm install\\n` +\n ` pnpm build:studio\\n`,\n );\n }\n}\n\nexport async function createStudioRemoteConfig(options: KbStudioRemoteOptions): Promise<Record<string, unknown>> {\n const { ModuleFederationPlugin } = await import('@module-federation/enhanced/rspack');\n const path = await import('path');\n const { createRequire } = await import('module');\n const require = createRequire(import.meta.url);\n\n await validateReactVersion(require.resolve);\n\n const outputDir = options.outputDir ?? 'dist/widgets';\n\n return {\n entry: {},\n output: {\n path: path.resolve(process.cwd(), outputDir),\n publicPath: 'auto',\n clean: true,\n },\n resolve: {\n extensions: ['.tsx', '.ts', '.jsx', '.js'],\n },\n module: {\n rules: [\n {\n test: /\\.tsx?$/,\n exclude: /node_modules/,\n use: {\n loader: 'builtin:swc-loader',\n options: {\n jsc: {\n parser: { syntax: 'typescript', tsx: true },\n transform: { react: { runtime: 'automatic' } },\n },\n },\n },\n },\n {\n test: /\\.module\\.css$/,\n use: [\n require.resolve('style-loader'),\n { loader: require.resolve('css-loader'), options: { modules: true } },\n ],\n },\n {\n test: /\\.css$/,\n exclude: /\\.module\\.css$/,\n use: [require.resolve('style-loader'), require.resolve('css-loader')],\n },\n ],\n },\n plugins: [\n new ModuleFederationPlugin({\n name: options.name,\n filename: options.filename ?? 'remoteEntry.js',\n exposes: options.exposes,\n shared: {\n ...STUDIO_SHARED_DEPS,\n ...options.shared,\n },\n }),\n ],\n optimization: {\n minimize: true,\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/index.ts"],"names":["require"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @kb-labs/studio-plugin-tools\n *\n * Build tooling for plugin Studio pages (Module Federation remotes).\n * Uses Rspack with @module-federation/enhanced for native MF support.\n *\n * @example\n * ```typescript\n * // rspack.studio.config.ts\n * const { createStudioRemoteConfig } = require('@kb-labs/studio-plugin-tools');\n *\n * module.exports = createStudioRemoteConfig({\n * name: 'commitPlugin',\n * exposes: {\n * './CommitOverview': './src/studio/pages/CommitOverview.tsx',\n * },\n * });\n * ```\n */\n\n/**\n * Shared dependencies that match the Studio host.\n * Loaded once by the host — remotes reuse them via MF shared scope.\n */\nexport const STUDIO_SHARED_DEPS: Record<string, { singleton: boolean; requiredVersion: string }> = {\n react: { singleton: true, requiredVersion: '^19.0.0' },\n 'react-dom': { singleton: true, requiredVersion: '^19.0.0' },\n 'react-router-dom': { singleton: true, requiredVersion: '^7.0.0' },\n antd: { singleton: true, requiredVersion: '^5.21.0' },\n '@ant-design/icons': { singleton: true, requiredVersion: '^5.4.0' },\n '@tanstack/react-query': { singleton: true, requiredVersion: '^5.0.0' },\n zustand: { singleton: true, requiredVersion: '^5.0.0' },\n '@kb-labs/studio-hooks': { singleton: true, requiredVersion: '^0.1.0' },\n '@kb-labs/studio-event-bus': { singleton: true, requiredVersion: '^0.1.0' },\n '@kb-labs/studio-ui-kit': { singleton: true, requiredVersion: '^0.1.0' },\n '@kb-labs/studio-ui-core': { singleton: true, requiredVersion: '^0.1.0' },\n '@kb-labs/sdk': { singleton: true, requiredVersion: '^0.1.0' },\n};\n\nexport interface KbStudioRemoteOptions {\n /** Module Federation remote name (must match manifest remoteName) */\n name: string;\n /** Exposed modules: { './PageName': './src/studio/pages/PageName.tsx' } */\n exposes: Record<string, string>;\n /** Override or extend shared deps */\n shared?: Record<string, { singleton?: boolean; requiredVersion?: string }>;\n /** Remote entry filename (default: 'remoteEntry.js') */\n filename?: string;\n /** Output directory (default: 'dist/widgets') */\n outputDir?: string;\n /**\n * Generate TypeScript types for exposed modules (MF v2 dts feature).\n * Studio host picks them up automatically in dev via @mf-types/.\n * Default: true in development, false in production.\n */\n dts?: boolean;\n}\n\n/**\n * Create a complete Rspack config for building a plugin as an MF remote.\n *\n * Returns a full rspack config object — use as default export in rspack.config.mjs.\n * Uses dynamic import internally to avoid CJS/ESM issues.\n */\n/**\n * Validate React version in the calling plugin's node_modules.\n * Studio host uses React 18 — React 19 causes MF element type mismatch at runtime.\n */\nasync function validateReactVersion(resolve: (id: string) => string): Promise<void> {\n const fs = await import('fs');\n\n const reactVersion = await (async (): Promise<string | null> => {\n try {\n const reactPkgPath = resolve('react/package.json');\n const reactPkg = JSON.parse(fs.readFileSync(reactPkgPath, 'utf8')) as { version: string };\n return reactPkg.version ?? null;\n } catch {\n return null;\n }\n })();\n\n if (!reactVersion) {return;}\n\n const majorStr = reactVersion.split('.').at(0) ?? '0';\n const major = parseInt(majorStr, 10);\n if (major >= 20) {\n throw new Error(\n `\\n\\n❌ Studio plugin build failed: React ${reactVersion} detected.\\n\\n` +\n `Studio host runs React 19. When a plugin bundles React 20+, elements may\\n` +\n `use a different internal symbol which React 19 cannot reconcile,\\n` +\n `causing \"Objects are not valid as a React child\" crash at runtime.\\n\\n` +\n `Fix: pin React 19 in your plugin's devDependencies:\\n\\n` +\n ` \"devDependencies\": {\\n` +\n ` \"react\": \"^19.0.0\",\\n` +\n ` \"react-dom\": \"^19.0.0\"\\n` +\n ` }\\n\\n` +\n `Then reinstall and rebuild:\\n\\n` +\n ` pnpm install\\n` +\n ` pnpm build:studio\\n`,\n );\n }\n}\n\nexport async function createStudioRemoteConfig(options: KbStudioRemoteOptions): Promise<Record<string, unknown>> {\n const { ModuleFederationPlugin } = await import('@module-federation/enhanced/rspack');\n const path = await import('path');\n const { createRequire } = await import('module');\n const require = createRequire(import.meta.url);\n\n await validateReactVersion(require.resolve);\n\n const isDev = process.env.NODE_ENV !== 'production';\n const outputDir = options.outputDir ?? 'dist/widgets';\n const enableDts = options.dts ?? isDev;\n\n return {\n entry: {},\n output: {\n path: path.resolve(process.cwd(), outputDir),\n publicPath: 'auto',\n clean: true,\n },\n resolve: {\n extensions: ['.tsx', '.ts', '.jsx', '.js'],\n },\n module: {\n rules: [\n {\n test: /\\.tsx?$/,\n exclude: /node_modules/,\n use: {\n loader: 'builtin:swc-loader',\n options: {\n jsc: {\n parser: { syntax: 'typescript', tsx: true },\n transform: { react: { runtime: 'automatic' } },\n },\n },\n },\n },\n {\n test: /\\.module\\.css$/,\n use: [\n require.resolve('style-loader'),\n { loader: require.resolve('css-loader'), options: { modules: true } },\n ],\n },\n {\n test: /\\.css$/,\n exclude: /\\.module\\.css$/,\n use: [require.resolve('style-loader'), require.resolve('css-loader')],\n },\n ],\n },\n plugins: [\n new ModuleFederationPlugin({\n name: options.name,\n filename: options.filename ?? 'remoteEntry.js',\n manifest: true,\n dts: enableDts ? { generateTypes: true } : false,\n exposes: options.exposes,\n shared: {\n ...STUDIO_SHARED_DEPS,\n ...options.shared,\n },\n }),\n ],\n optimization: {\n minimize: true,\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kb-labs/studio-plugin-tools",
3
3
  "description": "Build tooling for plugin Studio pages — Rspack config for Module Federation remotes",
4
- "version": "2.43.0",
4
+ "version": "2.45.0",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -15,7 +15,7 @@
15
15
  "dist"
16
16
  ],
17
17
  "dependencies": {
18
- "@module-federation/enhanced": "^0.8.0",
18
+ "@module-federation/enhanced": "^2.3.3",
19
19
  "css-loader": "^7.0.0",
20
20
  "style-loader": "^4.0.0"
21
21
  },
@@ -26,14 +26,16 @@
26
26
  "tsup": "^8.5.0",
27
27
  "typescript": "^5.6.3",
28
28
  "vitest": "^3.2.4",
29
- "@kb-labs/devkit": "2.43.0"
29
+ "@kb-labs/devkit": "2.45.0"
30
30
  },
31
31
  "engines": {
32
32
  "node": ">=20.0.0",
33
33
  "pnpm": ">=9.0.0"
34
34
  },
35
35
  "peerDependencies": {
36
- "@rspack/core": ">=1.0.0"
36
+ "@rspack/core": ">=1.0.0",
37
+ "react": "^19.0.0",
38
+ "react-dom": "^19.0.0"
37
39
  },
38
40
  "sideEffects": false,
39
41
  "scripts": {