@storybook/preset-react-webpack
Version:
Storybook for React: Develop React Component in isolation with Hot Reloading
197 lines (185 loc) • 7.44 kB
JavaScript
import CJS_COMPAT_NODE_URL_yhv20ho0s6p from 'node:url';
import CJS_COMPAT_NODE_PATH_yhv20ho0s6p from 'node:path';
import CJS_COMPAT_NODE_MODULE_yhv20ho0s6p from "node:module";
var __filename = CJS_COMPAT_NODE_URL_yhv20ho0s6p.fileURLToPath(import.meta.url);
var __dirname = CJS_COMPAT_NODE_PATH_yhv20ho0s6p.dirname(__filename);
var require = CJS_COMPAT_NODE_MODULE_yhv20ho0s6p.createRequire(import.meta.url);
// ------------------------------------------------------------
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
// ------------------------------------------------------------
// src/loaders/react-docgen-loader.ts
import { getProjectRoot } from "storybook/internal/common";
import { logger } from "storybook/internal/node-logger";
// ../../node_modules/empathic/find.mjs
import { join as join2 } from "node:path";
import { existsSync, statSync } from "node:fs";
// ../../node_modules/empathic/walk.mjs
import { dirname } from "node:path";
// ../../node_modules/empathic/resolve.mjs
import { isAbsolute, join, resolve } from "node:path";
function absolute(input, root) {
return isAbsolute(input) ? input : resolve(root || ".", input);
}
// ../../node_modules/empathic/walk.mjs
function up(base, options) {
let { last, cwd } = options || {}, tmp = absolute(base, cwd), root = absolute(last || "/", cwd), prev, arr = [];
for (; prev !== root && (arr.push(tmp), tmp = dirname(prev = tmp), tmp !== prev); )
;
return arr;
}
// ../../node_modules/empathic/find.mjs
function up2(name, options) {
let dir, tmp, start = options && options.cwd || "";
for (dir of up(start, options))
if (tmp = join2(dir, name), existsSync(tmp)) return tmp;
}
// src/loaders/react-docgen-loader.ts
import MagicString from "magic-string";
import {
ERROR_CODES,
builtinHandlers as docgenHandlers,
builtinResolvers as docgenResolver,
makeFsImporter,
parse,
utils
} from "react-docgen";
import * as TsconfigPaths from "tsconfig-paths";
// src/loaders/docgen-resolver.ts
import { extname } from "node:path";
import resolve2 from "resolve";
var ReactDocgenResolveError = class extends Error {
constructor(filename) {
super(`'${filename}' was ignored by react-docgen.`);
// the magic string that react-docgen uses to check if a module is ignored
this.code = "MODULE_NOT_FOUND";
}
}, RESOLVE_EXTENSIONS = [
".js",
".cts",
// These were originally not in the code, I added them
".mts",
// These were originally not in the code, I added them
".ctsx",
// These were originally not in the code, I added them
".mtsx",
// These were originally not in the code, I added them
".ts",
".tsx",
".mjs",
".cjs",
".mts",
".cts",
".jsx"
];
function defaultLookupModule(filename, basedir) {
let resolveOptions = {
basedir,
extensions: RESOLVE_EXTENSIONS,
// we do not need to check core modules as we cannot import them anyway
includeCoreModules: !1
};
try {
return resolve2.sync(filename, resolveOptions);
} catch (error) {
let ext = extname(filename), newFilename;
switch (ext) {
case ".js":
case ".mjs":
case ".cjs":
newFilename = `${filename.slice(0, -2)}ts`;
break;
case ".jsx":
newFilename = `${filename.slice(0, -3)}tsx`;
break;
default:
throw error;
}
return resolve2.sync(newFilename, {
...resolveOptions,
// we already know that there is an extension at this point, so no need to check other extensions
extensions: []
});
}
}
// src/loaders/react-docgen-loader.ts
var { getNameOrValue, isReactForwardRefCall } = utils, actualNameHandler = function(documentation, componentDefinition) {
if (documentation.set("definedInFile", componentDefinition.hub.file.opts.filename), (componentDefinition.isClassDeclaration() || componentDefinition.isFunctionDeclaration()) && componentDefinition.has("id"))
documentation.set(
"actualName",
getNameOrValue(componentDefinition.get("id"))
);
else if (componentDefinition.isArrowFunctionExpression() || componentDefinition.isFunctionExpression() || isReactForwardRefCall(componentDefinition)) {
let currentPath = componentDefinition;
for (; currentPath.parentPath; ) {
if (currentPath.parentPath.isVariableDeclarator()) {
documentation.set("actualName", getNameOrValue(currentPath.parentPath.get("id")));
return;
}
if (currentPath.parentPath.isAssignmentExpression()) {
let leftPath = currentPath.parentPath.get("left");
if (leftPath.isIdentifier() || leftPath.isLiteral()) {
documentation.set("actualName", getNameOrValue(leftPath));
return;
}
}
currentPath = currentPath.parentPath;
}
documentation.set("actualName", "");
}
}, defaultHandlers = Object.values(docgenHandlers).map((handler) => handler), defaultResolver = new docgenResolver.FindExportedDefinitionsResolver(), handlers = [...defaultHandlers, actualNameHandler], tsconfigPathsInitialized = !1, matchPath;
async function reactDocgenLoader(source, map) {
let callback = this.async(), options = this.getOptions() || {}, { debug = !1 } = options;
if (!tsconfigPathsInitialized) {
let tsconfigPath = up2("tsconfig.json", { cwd: process.cwd(), last: getProjectRoot() }), tsconfig = TsconfigPaths.loadConfig(tsconfigPath);
tsconfig.resultType === "success" && (logger.debug("Using tsconfig paths for react-docgen"), matchPath = TsconfigPaths.createMatchPath(tsconfig.absoluteBaseUrl, tsconfig.paths, [
"browser",
"module",
"main"
])), tsconfigPathsInitialized = !0;
}
try {
let docgenResults = parse(source, {
filename: this.resourcePath,
resolver: defaultResolver,
handlers,
importer: getReactDocgenImporter(matchPath),
babelOptions: {
babelrc: !1,
configFile: !1
}
}), magicString = new MagicString(source);
docgenResults.forEach((info) => {
let { actualName, definedInFile, ...docgenInfo } = info;
if (actualName && definedInFile == this.resourcePath) {
let docNode = JSON.stringify(docgenInfo);
magicString.append(`;${actualName}.__docgenInfo=${docNode}`);
}
}), callback(
null,
magicString.toString(),
map ?? magicString.generateMap({
hires: !0,
source: this.resourcePath,
includeContent: !0
})
);
} catch (error) {
error.code === ERROR_CODES.MISSING_DEFINITION || (debug ? (logger.warn(
`Failed to parse ${this.resourcePath} with react-docgen. Please use the below error message and the content of the file which causes the error to report the issue to the maintainers of react-docgen. https://github.com/reactjs/react-docgen`
), logger.error(error)) : logger.warn(
`Failed to parse ${this.resourcePath} with react-docgen. Rerun Storybook with --loglevel=debug to get more info.`
)), callback(null, source);
}
}
function getReactDocgenImporter(matchingPath) {
return makeFsImporter((filename, basedir) => {
let mappedFilenameByPaths = matchingPath && matchingPath(filename) || filename, result = defaultLookupModule(mappedFilenameByPaths, basedir);
if (RESOLVE_EXTENSIONS.find((ext) => result.endsWith(ext)))
return result;
throw new ReactDocgenResolveError(filename);
});
}
export {
reactDocgenLoader as default,
getReactDocgenImporter
};