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

Upgrade storybook to v6 #47777

Merged
merged 18 commits into from
Aug 29, 2022
Merged

Upgrade storybook to v6 #47777

merged 18 commits into from
Aug 29, 2022

Conversation

maddiedierker
Copy link
Contributor

@maddiedierker maddiedierker commented Aug 23, 2022

Upgrades all packages within the @storybook/ scope to latest.

As part of this upgrade, Storybook has a new API (e.g., the storiesOf format we are using is deprecated and no longer works in this version of Storybook; see "storiesOf (Legacy) API" for details). This means we need to refactor all stories to use the new CSF format. Storybook has an automated tool for this, but it worked on 0/226 of our Storybook files 😢 so we have to do this refactor manually. I estimate the average Storybook file will take 5-10 minutes to refactor.

Implications of this upgrade:

  • All Storybook files need to be migrated to the new format. I've migrated Meter.story.jsx and Notification.story.jsx in this PR as examples.
  • Any stories using the deprecated storiesOf API will be ignored by Storybook. If you run yarn storybook and your stories don't show up, that's probably why! Our unit test harness still supports the old API, so we do not lose any test coverage during this migration.
  • All new stories must use the new format.
  • We can now use Storybook documentation and new addons because our API isn't years out of date!
  • We can upgrade to Webpack 5 without breaking Storybook.

I've added a README in apps/.storybook/ that outlines how Storybook should be used and documents this migration. This migration is also tracked in Storybook Files to Refactor (internal Google Doc) and PP-186.

Resources:

@@ -27,7 +27,7 @@ export default class InlineMarkdown extends React.Component {
};

render() {
const rendered = markdownToReact.processSync(this.props.markdown).contents;
const rendered = markdownToReact.processSync(this.props.markdown).result;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

note about this change: the unified library was upgraded with storybook, and the structure of the object returned from processSync changed with that upgrade. there are unit/UI tests that cover this and i manually tested components to make sure nothing changed

@maddiedierker maddiedierker changed the title Upgrade storybook Upgrade storybook to v6 Aug 24, 2022
@maddiedierker maddiedierker marked this pull request as ready for review August 24, 2022 17:08
// }
// },
features: {
babelModeV7: true
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@@ -30,19 +30,24 @@ yarn start
### Seeing your development version of Apps in Dashboard

1. To make your changes show up in dashboard, do the following after the first time you build apps:
- Set `use_my_apps: true` to your locals.yml config file.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

my editor reformatted some extra stuff in this file when i made changes, sorry 🤷🏻‍♀️

@maddiedierker maddiedierker requested review from jmkulwik and a team August 24, 2022 17:26
Copy link
Contributor

@bencodeorg bencodeorg left a comment

Choose a reason for hiding this comment

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

A couple notes/questions, but excited about this!

buttonLink: 'to a new page',
dismissible: false
};
InfoCallToActionButton.storyName = 'Information - call-to-action button';
Copy link
Contributor

Choose a reason for hiding this comment

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

When do you add a storyName vs not?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i only renamed stories when i thought it made more sense for organization/readability purposes. in this file, i thought

Information - call-to-action-button
Information - two buttons and a link
Information

was more readable in the storybook panel than

Information Call To Action Button
Information Two Buttons And A Link
Information

// STORIES
//

export const HalfFull = Template.bind({});
Copy link
Contributor

Choose a reason for hiding this comment

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

Found this in docs if anyone is curious what's going on here:

Template.bind({}) is a standard JavaScript technique for making a copy of a function. We copy the Template so each exported story can set its own properties on it.

@@ -31,7 +31,7 @@
"start:craft": "DEV=1 grunt dev --app=craft --watch-notify;",
"test-audio": "echo \"Open your browser to http://127.0.0.1:8080/test/audio/audio_test.html\" && http-server .",
"prestorybook": "curl -o build/package/css/application.css http://localhost-studio.code.org:3000/assets/application.css || curl -o build/package/css/application.css https://code-dot-org.github.io/cdo-styleguide/css/application.css",
"storybook": "start-storybook -p 9001 -s build/package/,../dashboard/public,../,../pegasus/sites.v3/code.org/public",
Copy link
Contributor

Choose a reason for hiding this comment

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

These are now in apps/.storybook/main.js if anyone's curious where they ended up :)

],
addons: ['@storybook/addon-actions', '@storybook/addon-options'],
framework: '@storybook/react',
// TODO: Add webpack5 configuration below when we upgrade to webpack 5.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this written down somewhere so we don't forget? Or will Storybook fully not work without this line uncommented

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it won't work! i have it written down personally since i'll be shipping the webpack upgrade (hopefully, unless something horrible comes up...) right after this is merged

});
// Customize webpack config for storybook.
// @param {Object} sbConfig - Webpack configuration from storybook library.
function storybookConfig(sbConfig) {
Copy link
Contributor

Choose a reason for hiding this comment

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

For my understanding, how does this work differently now? Did storybook not provide webpack config previously?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i think storybook always provided some webpack configuration and would try to merge theirs with ours (previously provided by apps/.storybook/webpack.config.js) and it caused bugs and annoying confusion. so now there is a config function that supplies the storybook config and you can pick-and-choose what you want or just overwrite it (although i think that might break some storybook features if you just ignored their config)

Copy link
Contributor

Choose a reason for hiding this comment

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

For my understanding, how did you decide where to include sbConfig when building the returned object? eg, no ...sbConfig.resolve.alias in resolve.alias?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

mostly guess-and-check 😅 i knew which configurations we cared about from our original storybookConfig options, so i tested out which options we needed from storybook and which we could overwrite/exclude without breaking anything

}

function testStorybookFile(file) {
const {default: defaultExport, ...stories} = file;
Copy link
Contributor

Choose a reason for hiding this comment

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

What is defaultExport? A JS thing, Storybook?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

just JS. you can access the default export from the file object this way, but you can't name a variable named "default," so i'm renaming it here

@maddiedierker
Copy link
Contributor Author

@bencodeorg is this okay to merge, or do you want to take another look?

Copy link
Contributor

@bencodeorg bencodeorg left a comment

Choose a reason for hiding this comment

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

Some of the config stuff is over my head, but LGTM generally

apps/test/storybook/util/testStorybook.js Outdated Show resolved Hide resolved
});
// Customize webpack config for storybook.
// @param {Object} sbConfig - Webpack configuration from storybook library.
function storybookConfig(sbConfig) {
Copy link
Contributor

Choose a reason for hiding this comment

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

For my understanding, how did you decide where to include sbConfig when building the returned object? eg, no ...sbConfig.resolve.alias in resolve.alias?

@maddiedierker maddiedierker merged commit 4854a7a into staging Aug 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants