Skip to content

Commit

Permalink
Fix skipping current component imports, clearer names
Browse files Browse the repository at this point in the history
  • Loading branch information
sapegin committed Feb 20, 2021
1 parent 93af6ca commit 7d91a03
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 22 deletions.
11 changes: 4 additions & 7 deletions src/loaders/mdx-loader.ts
Expand Up @@ -19,7 +19,7 @@ import { mdx } from '@mdx-js/react';
export default async function mdxLoader(this: Rsg.StyleguidistLoaderContext, content: string) {
const callback = this.async() || (() => '');
const { updateExample, context } = this._styleguidist;
const { component } = loaderUtils.getOptions(this) || {};
const { component: componentPath } = loaderUtils.getOptions(this) || {};

let result;
try {
Expand All @@ -29,16 +29,13 @@ export default async function mdxLoader(this: Rsg.StyleguidistLoaderContext, con
addReact,
markStaticExamples,
addExampleIndicies,
updateExamples({ updateExample, resourcePath: this.resourcePath }),
updateExamples({ updateExample, mdxDocumentPath: this.resourcePath }),
exportExamples,
// Sections don't have current components
component && exportStories({ component, resourcePath: this.resourcePath }),
componentPath && exportStories({ componentPath, mdxDocumentPath: this.resourcePath }),
provideDocumentScope({ context }),
provideExampleScope,
component && provideCurrentComponent({ component }),
// TODO: Use smart (no-duplicates) insert instead of deduplication
// TODO: Or better insert needed imports in front of each example
// deduplicateImports,
componentPath && provideCurrentComponent({ componentPath }),
],
});
} catch (err) {
Expand Down
33 changes: 32 additions & 1 deletion src/loaders/rehype/__tests__/exportStories.spec.ts
Expand Up @@ -15,7 +15,9 @@ const compile = async (mdxContent: string, storyContent: string) => {
vol.fromJSON({ '/Pizza/Pizza.stories.tsx': storyContent });
const result = await mdx(mdxContent, {
filepath: 'Pizza.md',
rehypePlugins: [exportStories({ component: 'Pizza', resourcePath: '/Pizza/Pizza.md' })],
rehypePlugins: [
exportStories({ componentPath: './index.tsx', mdxDocumentPath: '/Pizza/Readme.md' }),
],
});

// Strip repeated parts
Expand Down Expand Up @@ -182,6 +184,35 @@ export const basic = () => <Container><Pizza /></Container>
`);
});

test('skips current component (named import)', async () => {
const result = await compile(
`Henlo`,
`
import { Pizza } from '.';
import Container from './Container';
export const basic = () => <Container><Pizza /></Container>
`
);
expect(result).toMatchInlineSnapshot(`
"
import * as __story_import_0 from '.'
import * as __story_import_1 from './Container'
export const __namedExamples = {
'basic': 'import Container from \\\\'./Container\\\\';\\\\n\\\\n<Container><Pizza /></Container>'
};
export const __storiesScope = {
'.': __story_import_0,
'./Container': __story_import_1
};
const layoutProps = {
__namedExamples,
__storiesScope
};
"
`);
});

test('includes the current component when it is not the only import', async () => {
const result = await compile(
`Henlo`,
Expand Down
25 changes: 16 additions & 9 deletions src/loaders/rehype/exportStories.ts
Expand Up @@ -21,6 +21,7 @@ import toAst from 'to-ast';
import { builders as b } from 'ast-types';
import getAst from '../utils/getAst';
import { ModuleMap } from './types';
import getNameFromFilePath from '../utils/getNameFromFilePath';

// TODO: Hot reload
// TODO: Unindenting
Expand Down Expand Up @@ -209,12 +210,12 @@ const getExportCode = (node: Declaration, code: string) => {
const prependExampleWithDependencies = (
code: string,
dependencies: Dependency[],
component: string
componentName: string
) => {
const usedDependencies = dependencies.filter(
(dependency) =>
// Ignore the current component import it it's the only import
!(dependency.names.length === 1 && dependency.names[0] === component) &&
!(dependency.names.length === 1 && dependency.names[0] === componentName) &&
// Include imports when any of the names are present in the code
dependency.names.some((name) => code.match(new RegExp(`\\b${name}\\b`)))
);
Expand All @@ -229,7 +230,7 @@ const prependExampleWithDependencies = (
.join('\n\n');
};

const getExports = (ast: Program, code: string, component: string) => {
const getExports = (ast: Program, code: string, componentName: string) => {
const imports = getImportStatements(ast, code);
const variables = getVariableStatements(ast, code);

Expand All @@ -245,7 +246,7 @@ const getExports = (ast: Program, code: string, component: string) => {
exports[exportCode.name] = prependExampleWithDependencies(
exportCode.code,
[...imports, ...variables],
component
componentName
);
}
}
Expand Down Expand Up @@ -275,12 +276,16 @@ const getExports = (ast: Program, code: string, component: string) => {
* './Button': __story_import_0
* }
*/
export default ({ component, resourcePath }: { component: string; resourcePath: string }) => () => (
treeRaw: MdxNode
) => {
export default ({
componentPath,
mdxDocumentPath,
}: {
componentPath: string;
mdxDocumentPath: string;
}) => () => (treeRaw: MdxNode) => {
const tree = treeRaw as Parent;

const componentAbsolutePath = path.resolve(path.dirname(resourcePath), component);
const componentAbsolutePath = path.resolve(path.dirname(mdxDocumentPath), componentPath);
const storiesFile = getStoriesFile(componentAbsolutePath);
if (!storiesFile) {
return tree;
Expand All @@ -292,8 +297,10 @@ export default ({ component, resourcePath }: { component: string; resourcePath:
return tree;
}

const componentName = getNameFromFilePath(componentAbsolutePath);

// Generate export for named examples
const exports = getExports(storiesAst, storiesCode, component);
const exports = getExports(storiesAst, storiesCode, componentName);
const examplesExportCode = `export const __namedExamples = ${generate(toAst(exports))}`;
tree.children.push({
type: 'export',
Expand Down
4 changes: 2 additions & 2 deletions src/loaders/rehype/provideCurrentComponent.ts
Expand Up @@ -9,13 +9,13 @@ const getLocalName = () => `__ex_component`;
* import * as __ex_component from './Button'
* export const __currentComponent = __ex_component
*/
export default ({ component }: { component: string }) => () => (treeRaw: Node) => {
export default ({ componentPath }: { componentPath: string }) => () => (treeRaw: Node) => {
const tree = treeRaw as Parent;

// Generate import
tree.children.push({
type: 'import',
value: `import * as ${getLocalName()} from '${component}'`,
value: `import * as ${getLocalName()} from '${componentPath}'`,
});

// Generate export
Expand Down
6 changes: 3 additions & 3 deletions src/loaders/rehype/updateExamples.ts
Expand Up @@ -17,17 +17,17 @@ const getCode = (node: CodeNode): string =>
*/
export default ({
updateExample,
resourcePath,
mdxDocumentPath,
}: {
updateExample: Rsg.SanitizedStyleguidistConfig['updateExample'];
resourcePath: string;
mdxDocumentPath: string;
}) => () => (tree: Node) => {
visit<CodeNode>(tree, { type: 'element', tagName: 'code' }, (node) => {
const content = getCode(node);
const lang = getCodeLang(node);
const { className, metastring, ...settings } = node.properties;

const nextExample = updateExample({ content, lang, settings }, resourcePath);
const nextExample = updateExample({ content, lang, settings }, mdxDocumentPath);

// TODO: Update lang
node.children[0].value = nextExample.content.trim();
Expand Down

0 comments on commit 7d91a03

Please sign in to comment.