UNPKG

storybook-builder-rsbuild

Version:
172 lines (165 loc) 6.96 kB
import CJS_COMPAT_NODE_URL_9822f21edcc46e85 from 'node:url'; import CJS_COMPAT_NODE_PATH_9822f21edcc46e85 from 'node:path'; import CJS_COMPAT_NODE_MODULE_9822f21edcc46e85 from "node:module"; var __filename = CJS_COMPAT_NODE_URL_9822f21edcc46e85.fileURLToPath(import.meta.url); var __dirname = CJS_COMPAT_NODE_PATH_9822f21edcc46e85.dirname(__filename); var require = CJS_COMPAT_NODE_MODULE_9822f21edcc46e85.createRequire(import.meta.url); // ------------------------------------------------------------ // end of CJS compatibility banner, injected by Storybook's esbuild configuration // ------------------------------------------------------------ import "./_node-chunks/chunk-L73IVHZJ.js"; // src/preview-preset.ts import { createRequire } from "node:module"; import { fileURLToPath as fileURLToPath2 } from "node:url"; import { findConfigFile } from "storybook/internal/common"; // src/plugins/rspack-inject-mocker-runtime-plugin.ts import { getMockerRuntime } from "storybook/internal/mocking-utils"; var PLUGIN_NAME = "RspackInjectMockerRuntimePlugin", RspackInjectMockerRuntimePlugin = class { getHtmlPlugin(compiler) { try { return compiler.options.plugins?.find((plugin) => { let name = plugin?.constructor?.name; return name === "HtmlRspackPlugin" || name === "HtmlWebpackPlugin"; })?.constructor; } catch (error) { return compiler.getInfrastructureLogger(PLUGIN_NAME).warn( `Unable to locate HTML plugin for mock runtime injection: ${error}` ), null; } } apply(compiler) { let HtmlPlugin = this.getHtmlPlugin(compiler); if (!HtmlPlugin || typeof HtmlPlugin.getHooks != "function") { compiler.getInfrastructureLogger(PLUGIN_NAME).warn("HTML plugin is not available. Cannot inject mocker runtime."); return; } compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => { HtmlPlugin.getHooks(compilation).beforeAssetTagGeneration.tapAsync( PLUGIN_NAME, (data, cb) => { try { let runtimeScriptContent = getMockerRuntime(), runtimeAssetName = "mocker-runtime-injected.js", Sources = compiler.webpack?.sources; if (!Sources?.RawSource) throw new Error( "rspack sources is not available on compiler.webpack" ); compilation.emitAsset( runtimeAssetName, new Sources.RawSource(runtimeScriptContent) ), data.assets.js.unshift(runtimeAssetName), cb(null, data); } catch (error) { cb(error); } } ); }); } }; // src/plugins/rspack-mock-plugin.ts import { dirname, isAbsolute } from "node:path"; import { fileURLToPath } from "node:url"; import { rspack } from "@rsbuild/core"; import { findMockRedirect } from "@vitest/mocker/redirect"; import { babelParser, extractMockCalls, getIsExternal, resolveExternalModule, resolveWithExtensions } from "storybook/internal/mocking-utils"; var PLUGIN_NAME2 = "RspackMockPlugin"; function normalizePath(filePath) { return filePath.replace(/\\/g, "/"); } var RspackMockPlugin = class { constructor(options) { this.mockMap = /* @__PURE__ */ new Map(); if (!options.previewConfigPath) throw new Error(`[${PLUGIN_NAME2}] \`previewConfigPath\` is required.`); this.options = options; } apply(compiler) { let logger = compiler.getInfrastructureLogger(PLUGIN_NAME2), updateMocks = () => { this.mockMap = new Map( this.extractAndResolveMocks(compiler).flatMap((mock) => [ [normalizePath(mock.absolutePath), mock], [normalizePath(mock.absolutePath.replace(/\.[^.]+$/, "")), mock] ]) ), logger.info(`Mock map updated with ${this.mockMap.size / 2} mocks.`); }; compiler.hooks.beforeRun.tap(PLUGIN_NAME2, updateMocks), compiler.hooks.watchRun.tap(PLUGIN_NAME2, updateMocks), new rspack.NormalModuleReplacementPlugin(/.*/, (resource) => { try { let path = resource.request, importer = resource.context, absolutePath = getIsExternal(path, importer) ? resolveExternalModule(path, importer) : resolveWithExtensions(path, importer), normalizedAbsolutePath = normalizePath(absolutePath); this.mockMap.has(normalizedAbsolutePath) && (resource.request = this.mockMap.get( normalizedAbsolutePath ).replacementResource); } catch { logger.debug(`Could not resolve mock for "${resource.request}".`); } }).apply(compiler), compiler.hooks.afterCompile.tap(PLUGIN_NAME2, (compilation) => { compilation.fileDependencies.add(this.options.previewConfigPath); for (let mock of this.mockMap.values()) isAbsolute(mock.replacementResource) && mock.replacementResource.includes("__mocks__") && compilation.contextDependencies.add(dirname(mock.replacementResource)); }); } extractAndResolveMocks(compiler) { let { previewConfigPath, configDir } = this.options, logger = compiler.getInfrastructureLogger(PLUGIN_NAME2), mocks = extractMockCalls( { previewConfigPath, configDir: configDir ?? dirname(previewConfigPath) }, babelParser, compiler.context, findMockRedirect ), resolvedMocks = []; for (let mock of mocks) try { let { absolutePath, redirectPath } = mock, replacementResource; redirectPath ? replacementResource = redirectPath : replacementResource = `${fileURLToPath( import.meta.resolve( "storybook-builder-rsbuild/loaders/rsbuild-automock-loader" ) )}?spy=${mock.spy}!${absolutePath}`, resolvedMocks.push({ ...mock, replacementResource }); } catch { logger.warn( `Could not resolve mock for "${mock.path}". It will be ignored.` ); } return resolvedMocks; } }; // src/preview-preset.ts var require2 = createRequire(import.meta.url), previewMainTemplate = () => require2.resolve("storybook-builder-rsbuild/templates/preview.ejs"); async function rsbuildFinal(config, options) { let previewConfigPath = findConfigFile("preview", options.configDir); if (!previewConfigPath) return config; let applyMocking = (rspackConfig, utils) => (utils.addRules({ test: /preview\.(t|j)sx?$/, use: [ { loader: fileURLToPath2( import.meta.resolve( "storybook-builder-rsbuild/loaders/storybook-mock-transform-loader" ) ) } ] }), rspackConfig.plugins ??= [], rspackConfig.plugins.push(new RspackMockPlugin({ previewConfigPath })), rspackConfig.plugins.push(new RspackInjectMockerRuntimePlugin()), rspackConfig); return { ...config, tools: { ...config.tools, rspack: Array.isArray(config.tools?.rspack) ? [...config.tools.rspack, applyMocking] : [config.tools?.rspack, applyMocking].filter( (v) => !!v ) } }; } export { previewMainTemplate, rsbuildFinal };