Skip to content

Commit

Permalink
feat: add ability to exclude paths for stories (storybookjs#285)
Browse files Browse the repository at this point in the history
  • Loading branch information
jgornick committed Oct 13, 2021
1 parent 11a4c65 commit 6bbfb43
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 1 deletion.
35 changes: 35 additions & 0 deletions app/react-native/scripts/__snapshots__/loader.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,40 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`loader writeRequires when there is a story glob and exclude paths globs writes the story imports 1`] = `
"
/* do not change this file, it is auto generated by storybook. */
import { configure, addDecorator, addParameters, addArgsEnhancer } from '@storybook/react-native';
import \\"@storybook/addon-ondevice-notes/register\\";
import \\"@storybook/addon-ondevice-controls/register\\";
import \\"@storybook/addon-ondevice-backgrounds/register\\";
import \\"@storybook/addon-ondevice-actions/register\\";
import { argsEnhancers } from \\"@storybook/addon-actions/dist/modern/preset/addArgs\\"
import { decorators, parameters } from './preview';
if (decorators) {
decorators.forEach((decorator) => addDecorator(decorator));
}
if (parameters) {
addParameters(parameters);
}
argsEnhancers.forEach(enhancer => addArgsEnhancer(enhancer))
const getStories=() => {
return [require(\\"include-components/FakeStory.stories.tsx\\")];
}
configure(getStories, module, false)
"
`;

exports[`loader writeRequires when there is a story glob writes the story imports 1`] = `
"
/* do not change this file, it is auto generated by storybook. */
Expand Down
28 changes: 27 additions & 1 deletion app/react-native/scripts/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@ const previewImports = `
}
`;

function normalizeExcludePaths(paths) {
// automatically convert a string to an array of a single string
if (typeof paths === 'string') {
return [paths];
}

// ensure the paths is an array and if any items exists, they are strings
if (Array.isArray(paths) && paths.every((p) => typeof p === 'string')) {
return paths;
}

// when the paths aren't a string or an (empty) array of strings, return
return undefined;
}

function requireUncached(module) {
delete require.cache[require.resolve(module)];
return require(module);
Expand All @@ -36,8 +51,19 @@ function writeRequires({ configPath, absolute = false }) {
const storybookRequiresLocation = path.resolve(cwd, configPath, 'storybook.requires.js');

const main = getMain({ configPath });
const reactNativeOptions = main.reactNativeOptions;
const excludePaths = reactNativeOptions && reactNativeOptions.excludePaths;
const normalizedExcludePaths = normalizeExcludePaths(excludePaths);

const storyPaths = main.stories.reduce((acc, storyGlob) => {
const paths = glob.sync(storyGlob, { cwd: path.resolve(cwd, configPath), absolute });
const paths = glob.sync(storyGlob, {
cwd: path.resolve(cwd, configPath),
absolute,
// default to always ignore (exclude) anything in node_modules
ignore: normalizedExcludePaths !== undefined
? normalizedExcludePaths
: ['**/node_modules'],
});
return [...acc, ...paths];
}, []);

Expand Down
14 changes: 14 additions & 0 deletions app/react-native/scripts/loader.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@ describe('loader', () => {
});
});

describe('when there is a story glob and exclude paths globs', () => {
it('writes the story imports', () => {
writeRequires({ configPath: 'scripts/mocks/exclude-config-files' });
expect(pathMock).toEqual(
path.resolve(__dirname, 'mocks/exclude-config-files/storybook.requires.js')
);

expect(fileContentMock).toContain('include-components/FakeStory.stories.tsx');
expect(fileContentMock).not.toContain('exclude-components/FakeStory.stories.tsx');

expect(fileContentMock).toMatchSnapshot();
});
});

describe('when there is no story glob or addons', () => {
it('writes no story imports or addons', () => {
writeRequires({ configPath: 'scripts/mocks/blank-config' });
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const FakeComponent = () => null;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { FakeComponentExcluded } from './FakeComponent';

export default {
title: 'components/FakeComponentExcluded',
component: FakeComponentExcluded,
};

export const Basic = {
args: {},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const FakeComponent = () => null;
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { FakeComponent } from './FakeComponent';

export default {
title: 'components/FakeComponent',
component: FakeComponent,
};

export const Basic = {
args: {},
};
12 changes: 12 additions & 0 deletions app/react-native/scripts/mocks/exclude-config-files/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
stories: ['**/*.stories.tsx'],
reactNativeOptions: {
excludePaths: '**/exclude-components/**',
},
addons: [
'@storybook/addon-ondevice-notes',
'@storybook/addon-ondevice-controls',
'@storybook/addon-ondevice-backgrounds',
'@storybook/addon-ondevice-actions',
],
};
24 changes: 24 additions & 0 deletions app/react-native/scripts/mocks/exclude-config-files/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import { View, StyleSheet } from 'react-native';
import { withBackgrounds } from '@storybook/addon-ondevice-backgrounds';

export const decorators = [
(StoryFn) => (
<View style={styles.container}>
<StoryFn />
</View>
),
withBackgrounds,
];
export const parameters = {
my_param: 'anything',
backgrounds: [
{ name: 'plain', value: 'white', default: true },
{ name: 'warm', value: 'hotpink' },
{ name: 'cool', value: 'deepskyblue' },
],
};

const styles = StyleSheet.create({
container: { padding: 8, flex: 1 },
});

0 comments on commit 6bbfb43

Please sign in to comment.