UNPKG

@storybook/react-native

Version:

A better way to develop React Native Components for your app

171 lines (170 loc) 7.95 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const require_chunk = require("../chunk-Ble4zEEl.js"); const require_env_tools = require("../env-tools-HukDb0eg.js"); const require_channelServer = require("../channelServer-MfmENTPk.js"); let path = require("path"); path = require_chunk.__toESM(path); let storybook_internal_common = require("storybook/internal/common"); let storybook_internal_telemetry = require("storybook/internal/telemetry"); //#region src/metro/withStorybook.ts var import_generate = require_env_tools.require_generate(); /** * Configures Metro bundler to work with Storybook in React Native. * This function wraps a Metro configuration to enable Storybook usage. * This is intended to replace the withStorybook function in the future. * * @param config - The Metro bundler configuration to be modified. This should be a valid Metro config object * that includes resolver, transformer, and other Metro-specific options. * @param options - Options to customize the Storybook configuration. * @param options.configPath - The path to the Storybook config folder. Defaults to './.rnstorybook'. * This is where your main.js/ts and preview.js/ts files are located. * @param options.websockets - WebSocket configuration for syncing storybook instances or sending events. * When provided, creates a WebSocket server for real-time communication. * @param options.websockets.port - The port WebSocket server will listen on. Defaults to 7007. * @param options.websockets.host - The host WebSocket server will bind to. Defaults to 'localhost'. * @param options.websockets.secured - Whether to use WSS/HTTPS for the channel server. * @param options.websockets.key - TLS private key used when `secured` is true. * @param options.websockets.cert - TLS certificate used when `secured` is true. * @param options.useJs - Whether to use JavaScript files for Storybook configuration instead of TypeScript. * When true, generates storybook.requires.js instead of storybook.requires.ts. * Defaults to false. * @param options.enabled - If false, attempts to remove storybook modules from the JavaScript * bundle to reduce bundle size. Defaults to true. * @param options.docTools - Whether to include doc tools in the storybook.requires file. * Doc tools provide additional documentation features. Defaults to true. * @param options.liteMode - Whether to use lite mode for the storybook. In lite mode, the default * storybook UI is mocked out so you don't need to install all its dependencies * like reanimated etc. This is useful for reducing bundle size and dependencies. * Defaults to false. * @returns The modified Metro configuration with Storybook support enabled. * * @example * ```javascript * const { getDefaultConfig } = require('expo/metro-config'); * const {withStorybook} = require('@storybook/react-native/metro/withStorybook'); * const path = require('path'); * * const projectRoot = __dirname; * const config = getDefaultConfig(projectRoot); * * module.exports = withStorybook(config, { * configPath: path.resolve(projectRoot, './.rnstorybook'), * websockets: { port: 7007, host: 'localhost' }, * useJs: false, * docTools: true, * liteMode: false, * }); * ``` * * @example * ```javascript * // Minimal configuration * const { getDefaultConfig } = require('expo/metro-config'); * const {withStorybook} = require('@storybook/react-native/metro/withStorybook'); * * const config = getDefaultConfig(__dirname); * module.exports = withStorybook(config); * ``` * * @example * ```javascript * // Disable Storybook in production * const { getDefaultConfig } = require('expo/metro-config'); * const {withStorybook} = require('@storybook/react-native/metro/withStorybook'); * * const config = getDefaultConfig(__dirname); * module.exports = withStorybook(config, { * enabled: process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === "true", * }); * ``` */ function withStorybook(config, options = { useJs: false, enabled: true, docTools: true, liteMode: false, configPath: path.resolve(process.cwd(), "./.rnstorybook") }) { const { configPath = path.resolve(process.cwd(), "./.rnstorybook"), websockets, useJs = false, enabled = true, docTools = true, liteMode = false, experimental_mcp = false } = options; if (!(0, storybook_internal_common.optionalEnvToBoolean)(process.env.STORYBOOK_DISABLE_TELEMETRY) && enabled) (0, storybook_internal_telemetry.telemetry)(process.env.NODE_ENV === "production" ? "build" : "dev", {}).catch((e) => {}); if (!enabled) return { ...config, resolver: { ...config.resolver, resolveRequest: (context, moduleName, platform) => { const resolveFunction = config?.resolver?.resolveRequest ? config.resolver.resolveRequest : context.resolveRequest; if (moduleName.startsWith("storybook") || moduleName.startsWith("@storybook")) return { type: "empty" }; if (platform !== "web" && (moduleName === "tty" || moduleName === "os")) return { type: "empty" }; const resolved = resolveFunction(context, moduleName, platform); const configIndexRegex = new RegExp(`${configPath}/index\\.(tsx?|jsx?)$`); if (resolved.filePath && configIndexRegex.test(resolved.filePath)) return { filePath: path.resolve(__dirname, "../stub.js"), type: "sourceFile" }; if (resolved.filePath?.includes?.(configPath)) return { type: "empty" }; return resolved; } } }; if (experimental_mcp || websockets != null || process.env.STORYBOOK_WS_HOST) { const resolvedWs = require_env_tools.loadWebsocketEnvOverrides(websockets); const bindHost = websockets === "auto" && !process.env.STORYBOOK_WS_HOST ? void 0 : resolvedWs.host; const generateHost = resolvedWs.host ?? (websockets === "auto" && !process.env.STORYBOOK_WS_HOST ? "auto" : void 0); const port = resolvedWs.port ?? 7007; const secured = resolvedWs.secured; require_channelServer.createChannelServer({ port, host: bindHost, configPath, experimental_mcp, websockets: Boolean(websockets) || Boolean(process.env.STORYBOOK_WS_HOST) || Boolean(resolvedWs.host), secured, ssl: websockets && websockets !== "auto" ? { key: websockets.key, cert: websockets.cert, ca: websockets.ca, passphrase: websockets.passphrase } : void 0 }); if (websockets != null || process.env.STORYBOOK_WS_HOST) (0, import_generate.generate)({ configPath, useJs, docTools, host: generateHost, port, secured }); else (0, import_generate.generate)({ configPath, useJs, docTools }); } else (0, import_generate.generate)({ configPath, useJs, docTools }); return { ...config, transformer: { ...config.transformer, unstable_allowRequireContext: true }, resolver: { ...config.resolver, resolveRequest: (context, moduleName, platform) => { const resolveResult = (config?.resolver?.resolveRequest ? config.resolver.resolveRequest : context.resolveRequest)(moduleName.startsWith("storybook") || moduleName.startsWith("@storybook") || moduleName.startsWith("uuid") ? { ...context, unstable_enablePackageExports: true, unstable_conditionNames: ["import"] } : context, moduleName, platform); if (resolveResult?.filePath?.includes?.("@storybook/react/template/cli")) return { type: "empty" }; if (platform !== "web" && (moduleName === "tty" || moduleName === "os")) return { type: "empty" }; if (liteMode && resolveResult?.filePath?.includes?.("@storybook/react-native-ui") && !resolveResult?.filePath?.includes?.("@storybook/react-native-ui-lite") && !resolveResult?.filePath?.includes?.("@storybook/react-native-ui-common")) return { type: "empty" }; return resolveResult; } } }; } //#endregion exports.withStorybook = withStorybook;