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))}
	`;
};
Example #2
0
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))}
	`;
}