UNPKG

@module-federation/storybook-addon

Version:

Storybook addon to consume remote module federated apps/components

78 lines (74 loc) 2.77 kB
import fs from "node:fs"; import path from "node:path"; import { ModuleFederationPlugin } from "@module-federation/enhanced/rspack"; import { TEMP_DIR } from "@module-federation/sdk"; //#region src/utils/correctImportPath.ts const correctImportPath = (context, entryFile) => { if (typeof process !== "undefined") { if (process?.platform !== "win32") return entryFile; if (entryFile.match(/^\.?\.\\/) || !entryFile.match(/^[A-Z]:\\\\/i)) return entryFile.replace(/\\/g, "/"); const relative = path.win32.relative(context, entryFile).replace(/\\/g, "/"); if (relative.includes("node_modules/")) return relative.split("node_modules/")[1]; return `./${relative}`; } return null; }; //#endregion //#region src/utils/with-module-federation-enhanced-rsbuild.ts const tempDirPath = path.resolve(process.cwd(), `node_modules/${TEMP_DIR}`); const PLUGIN_NAME = "module-federation-storybook-addon"; const bootstrapPath = path.resolve(process.cwd(), `node_modules/${TEMP_DIR}/storybook-bootstrap.js`); const generateBootstrap = (context, entryPath) => { return `import('${correctImportPath(context, entryPath)}');`; }; const writeBootstrap = (context, entryPath) => { if (!fs.existsSync(tempDirPath)) fs.mkdirSync(tempDirPath); if (fs.existsSync(bootstrapPath)) fs.unlinkSync(bootstrapPath); fs.writeFileSync(bootstrapPath, generateBootstrap(context, entryPath)); }; const withModuleFederation = (rsbuildConfig, options) => { rsbuildConfig.plugins ??= []; rsbuildConfig.source ??= {}; rsbuildConfig.source.entry ??= {}; const entry = rsbuildConfig.source.entry; const context = rsbuildConfig.root || process.cwd(); for (const entryName in entry) if (Array.isArray(entry[entryName])) { writeBootstrap(context, entry[entryName][0]); entry[entryName] = [bootstrapPath]; } rsbuildConfig.plugins.push({ name: "module-federation-storybook-plugin", setup: function(api) { api.modifyRsbuildConfig((config, { mergeRsbuildConfig }) => { return mergeRsbuildConfig(config, { dev: { hmr: false } }); }); api.modifyBundlerChain(async (chain) => { chain.plugin(PLUGIN_NAME).use(ModuleFederationPlugin, [{ name: options.name || PLUGIN_NAME, shared: { react: { singleton: true }, "react-dom": { singleton: true }, ...options.shared }, remotes: { ...options.remotes }, shareStrategy: options.shareStrategy }]); }); } }); return rsbuildConfig; }; //#endregion //#region preset.ts var preset_default = { rsbuildFinal: (config, options) => { const { remotes, shared, name, shareStrategy } = options; return withModuleFederation(config, { name, remotes, shared, shareStrategy }); } }; //#endregion export { PLUGIN_NAME, preset_default as default }; //# sourceMappingURL=preset.js.map