Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addon-docs: Jest MDX transform for storyshots #8189

Merged
merged 16 commits into from
Oct 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions addons/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,20 @@ configure(require.context('../src', true, /\.stories\.(js|mdx)$/), module);

For more information on the new `configure`, see ["Loading stories"](https://github.com/storybookjs/storybook/blob/next/docs/src/pages/basics/writing-stories/index.md#loading-stories) in the Storybook documentation.

If using in conjunction with the [storyshots add-on](../storyshots/storyshots-core/README.md), you will need to
configure Jest to transform MDX stories into something Storyshots can understand:

Add the following to your Jest configuration:

```json
{
"transform": {
"^.+\\.[tj]sx?$": "babel-jest",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"^.+\\.mdx$": "@storybook/addon-docs/jest-transform-mdx"
}
}
```

## Preset options

The `addon-docs` preset has a few configuration options that can be used to configure its babel/webpack loading behavior. Here's an example of how to use the preset with options:
Expand Down
34 changes: 34 additions & 0 deletions addons/docs/jest-transform-mdx.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const path = require('path');
const mdx = require('@mdx-js/mdx');
const { ScriptTransformer } = require('@jest/transform');
const { dedent } = require('ts-dedent');

const createCompiler = require('./mdx-compiler-plugin');

const compilers = [createCompiler({})];

const getNextTransformer = (filename, config) => {
const extension = path.extname(filename);
const jsFileName = `${filename.slice(0, -extension.length)}.js`;
const self = config.transform.find(([pattern]) => new RegExp(pattern).test(filename));
const jsTransforms = config.transform.filter(([pattern]) => new RegExp(pattern).test(jsFileName));
return new ScriptTransformer({
...config,
transform: [
...config.transform.filter(entry => entry !== self),
...jsTransforms.map(([pattern, ...rest]) => [self[0], ...rest]),
],
});
};

module.exports = {
process(src, filename, config, { instrument }) {
const result = dedent`
/* @jsx mdx */
import React from 'react'
import { mdx } from '@mdx-js/react'
${mdx.sync(src, { compilers, filepath: filename })}
`;
return getNextTransformer(filename, config).transformSource(filename, result, instrument);
},
};
4 changes: 3 additions & 1 deletion addons/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@babel/parser": "^7.4.2",
"@babel/plugin-transform-react-jsx": "^7.3.0",
"@egoist/vue-to-react": "^1.1.0",
"@jest/transform": "^24.9.0",
"@mdx-js/loader": "^1.1.0",
"@mdx-js/mdx": "^1.1.0",
"@mdx-js/react": "^1.0.27",
Expand All @@ -52,7 +53,8 @@
"global": "^4.3.2",
"js-string-escape": "^1.0.1",
"lodash": "^4.17.15",
"prop-types": "^15.7.2"
"prop-types": "^15.7.2",
"ts-dedent": "^1.1.0"
},
"devDependencies": {
"@types/prop-types": "^15.5.9",
Expand Down
2 changes: 1 addition & 1 deletion addons/storyshots/storyshots-core/.storybook/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { configure } from '@storybook/react';

configure(
[
require.context('../stories/required_with_context', false, /\.stories\.js$/),
require.context('../stories/required_with_context', false, /\.stories\.(js|mdx)$/),
require.context('../stories/directly_required', false, /index\.js$/),
],
module
Expand Down
1 change: 1 addition & 0 deletions addons/storyshots/storyshots-core/.storybook/presets.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = ['@storybook/addon-docs/react/preset'];
17 changes: 17 additions & 0 deletions addons/storyshots/storyshots-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,23 @@ StoryShots addon for Preact is dependent on [preact-render-to-json](https://gith
yarn add preact-render-to-json --dev
```

### Configure Jest for MDX Docs Add-On Stories

If using the [Docs add-on](../../docs/README.md) with
[MDX stories](../../docs/docs/mdx.md) you will need
to configure Jest to transform MDX stories into something Storyshots can understand:

Add the following to your Jest configuration:

```json
{
"transform": {
"^.+\\.[tj]sx?$": "babel-jest",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the pipe symbol necessary? [t|j]

"^.+\\.mdx?$": "@storybook/addon-docs/jest-transform-mdx"
}
}
```

### <a name="deps-issue"></a>Why don't we install dependencies of each framework ?
Storyshots addon is currently supporting React, Angular and Vue. Each framework needs its own packages to be integrated with Jest. We don't want people that use only React will need to bring other dependencies that do not make sense for them.

Expand Down
3 changes: 3 additions & 0 deletions addons/storyshots/storyshots-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
"ts-dedent": "^1.1.0"
},
"devDependencies": {
"@storybook/addon-docs": "^5.3.0-alpha.11",
"@storybook/react": "^5.3.0-alpha.11",
"babel-loader": "^8.0.6",
"enzyme-to-json": "^3.4.1",
"jest-emotion": "^10.0.17",
"react": "^16.8.3"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ describe('getPossibleStoriesFiles', () => {
'test/foo.web.stories.jsx',
'test/foo.web.stories.ts',
'test/foo.web.stories.tsx',
'test/foo.web.stories.mdx',
]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import dedent from 'ts-dedent';
const defaultOptions: Stories2SnapsConverterOptions = {
snapshotsDirName: '__snapshots__',
snapshotExtension: '.storyshot',
storiesExtensions: ['.js', '.jsx', '.ts', '.tsx'],
storiesExtensions: ['.js', '.jsx', '.ts', '.tsx', '.mdx'],
};

export interface Stories2SnapsConverterOptions {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,210 @@ exports[`Storyshots Button With Text 1`] = `
</Button>
`;

exports[`Storyshots Welcome MDX To Storybook 1`] = `
<Welcome
showApp={[Function]}
>
<Main>
<article
style={
Object {
"backgroundColor": "#fff",
"color": "#000",
"fontFamily": "\\"Helvetica Neue\\", Helvetica, \\"Segoe UI\\", Arial, freesans, sans-serif",
"lineHeight": 1.4,
"padding": 15,
}
}
>
<Title>
<h1>
Welcome to storybook
</h1>
</Title>
<p>
This is a UI component dev environment for your app.
</p>
<p>
We've added some basic stories inside the
<InlineCode>
<code
style={
Object {
"backgroundColor": "#f3f2f2",
"border": "1px solid #eae9e9",
"borderRadius": 4,
"color": "#3a3a3a",
"fontSize": 15,
"fontWeight": 600,
"padding": "2px 5px",
}
}
>
src/stories
</code>
</InlineCode>
directory.
<br />
A story is a single state of one or more UI components. You can have as many stories as you want.
<br />
(Basically a story is like a visual test case.)
</p>
<p>
See these sample
<NavButton
onClick={[Function]}
>
<button
onClick={[Function]}
style={
Object {
"backgroundColor": "transparent",
"borderBottom": "1px solid #1474f3",
"borderLeft": "none",
"borderRight": "none",
"borderTop": "none",
"color": "#1474f3",
"cursor": "pointer",
"font": "inherit",
"padding": 0,
"paddingBottom": 2,
"textDecoration": "none",
}
}
type="button"
>
stories
</button>
</NavButton>
for a component called 
<InlineCode>
<code
style={
Object {
"backgroundColor": "#f3f2f2",
"border": "1px solid #eae9e9",
"borderRadius": 4,
"color": "#3a3a3a",
"fontSize": 15,
"fontWeight": 600,
"padding": "2px 5px",
}
}
>
Button
</code>
</InlineCode>
.
</p>
<p>
Just like that, you can add your own components as stories.
<br />
You can also edit those components and see changes right away.
<br />
(Try editing the
<InlineCode>
<code
style={
Object {
"backgroundColor": "#f3f2f2",
"border": "1px solid #eae9e9",
"borderRadius": 4,
"color": "#3a3a3a",
"fontSize": 15,
"fontWeight": 600,
"padding": "2px 5px",
}
}
>
Button
</code>
</InlineCode>
stories located at 
<InlineCode>
<code
style={
Object {
"backgroundColor": "#f3f2f2",
"border": "1px solid #eae9e9",
"borderRadius": 4,
"color": "#3a3a3a",
"fontSize": 15,
"fontWeight": 600,
"padding": "2px 5px",
}
}
>
src/stories/index.js
</code>
</InlineCode>
.)
</p>
<p>
Usually we create stories with smaller UI components in the app.
<br />
Have a look at the 
<Link
href="https://storybook.js.org/basics/writing-stories"
rel="noopener noreferrer"
target="_blank"
>
<a
href="https://storybook.js.org/basics/writing-stories"
rel="noopener noreferrer"
style={
Object {
"borderBottom": "1px solid #1474f3",
"color": "#1474f3",
"paddingBottom": 2,
"textDecoration": "none",
}
}
target="_blank"
>
Writing Stories
</a>
</Link>
 section in our documentation.
</p>
<Note>
<p
style={
Object {
"opacity": 0.5,
}
}
>
<b>
NOTE:
</b>
<br />
Have a look at the
<InlineCode>
<code
style={
Object {
"backgroundColor": "#f3f2f2",
"border": "1px solid #eae9e9",
"borderRadius": 4,
"color": "#3a3a3a",
"fontSize": 15,
"fontWeight": 600,
"padding": "2px 5px",
}
}
>
.storybook/webpack.config.js
</code>
</InlineCode>
to add webpack loaders and plugins you are using in this project.
</p>
</Note>
</article>
</Main>
</Welcome>
`;

exports[`Storyshots Welcome To Storybook 1`] = `
<Welcome
showApp={[Function]}
Expand Down
Loading