module.exports.pitch = function() { /* istanbul ignore if */ if (this.cacheable) { this.cacheable(); } const config = this._styleguidist; let sections = getSections(config.sections, config); if (config.skipComponentsWithoutExample) { sections = filterComponentsWithExample(sections); } const allComponentFiles = getComponentFilesFromSections( config.sections, config.configDir, config.ignore ); const allContentPages = getAllContentPages(sections); // Nothing to show in the style guide const welcomeScreen = allContentPages.length === 0 && allComponentFiles.length === 0; const patterns = welcomeScreen ? getComponentPatternsFromSections(config.sections) : undefined; /* istanbul ignore if */ if (config.verbose) { console.log(); console.log('Loading components:'); console.log(allComponentFiles.join('\n')); console.log(); } // Setup Webpack context dependencies to enable hot reload when adding new files if (config.contextDependencies) { config.contextDependencies.forEach(dir => this.addContextDependency(dir)); } else if (allComponentFiles.length > 0) { // Use common parent directory of all components as a context this.addContextDependency(commonDir(allComponentFiles)); } const styleguide = { config: pick(config, CLIENT_CONFIG_OPTIONS), welcomeScreen, patterns, sections, }; return ` if (module.hot) { module.hot.accept([]) } module.exports = ${generate(toAst(styleguide))} `; };
module.exports = function(source) { /* istanbul ignore if */ if (this.cacheable) { this.cacheable(); } const file = this.request.split('!').pop(); const config = this._styleguidist; const defaultParser = (filePath, source, resolver, handlers) => reactDocs.parse(source, resolver, handlers); const propsParser = config.propsParser || defaultParser; let props = {}; try { props = propsParser(file, source, config.resolver, config.handlers(file)); } /* istanbul ignore next */ catch (err) { const errorMessage = err.toString(); const componentPath = path.relative(process.cwd(), file); const message = errorMessage === 'Error: No suitable component definition found.' ? `Warning: ${componentPath} matches a pattern defined in ”components” or “sections” options in your ` + 'style guide config but doesn’t export a component.' : `Error when parsing ${componentPath}: ${err}\n\n` + 'It usually means that react-docgen cannot parse your source code, try to file an issue here:\n' + 'https://github.com/reactjs/react-docgen/issues'; console.log(`\n${message}\n`); } // Support only one component if (isArray(props)) { props = props[0]; } props = getProps(props); // Examples from Markdown file const examplesFile = config.getExampleFilename(file); props.examples = getExamples(examplesFile, props.displayName, config.defaultExample); return ` if (module.hot) { module.hot.accept([]) } module.exports = ${generate(toAst(props))} `; };
function examplesLoader(source) { /* istanbul ignore if */ if (this.cacheable) { this.cacheable(); } const query = loaderUtils.getOptions(this) || {}; const config = this._styleguidist; // Append React to context modules, since it’s required for JSX const fullContext = Object.assign({ React: 'react' }, config.context); // Replace placeholders (__COMPONENT__) with the passed-in component name if (query.componentName) { source = expandDefaultComponent(source, query.componentName); } // Load examples const examples = chunkify(source); // We're analysing the examples' source code to figure out the require statements. We do it manually with regexes, // because webpack unfortunately doesn't expose its smart logic for rewriting requires // (https://webpack.github.io/docs/context.html). Note that we can't just use require(...) directly in runtime, // because webpack changes its name to __webpack__require__ or something. const codeFromAllExamples = map(filter(examples, { type: 'code' }), 'content').join('\n'); const requiresFromExamples = getRequires(codeFromAllExamples); const allRequires = Object.assign({}, requiresFromExamples, fullContext); // “Prerequire” modules required in Markdown examples and context so they end up in a bundle and be available at runtime const allRequiresCode = reduce(allRequires, (requires, requireRequest) => { requires[requireRequest] = requireIt(requireRequest); return requires; }, {}); // Require context modules so they are available in an example const requireContextCode = b.program(map(fullContext, (requireRequest, name) => b.variableDeclaration('var', [ b.variableDeclarator(b.identifier(name), requireIt(requireRequest).toAST()), ]) )); // Stringify examples object except the evalInContext function const examplesWithEval = examples.map(example => { if (example.type === 'code') { example.evalInContext = { toAST: () => b.identifier('evalInContext') }; } return example; }); return ` if (module.hot) { module.hot.accept([]) } var requireMap = ${generate(toAst(allRequiresCode))}; var requireInRuntimeBase = require(${JSON.stringify(absolutize('utils/client/requireInRuntime'))}); var requireInRuntime = requireInRuntimeBase.bind(null, requireMap); var evalInContextBase = require(${JSON.stringify(absolutize('utils/client/evalInContext'))}); var evalInContext = evalInContextBase.bind(null, ${JSON.stringify(generate(requireContextCode))}, requireInRuntime); module.exports = ${generate(toAst(examplesWithEval))} `; }