Skip to content

Commit

Permalink
chore!: Upgrade Storybook and Webpack (#2674)
Browse files Browse the repository at this point in the history
Fixes: #2618 

We've upgraded Storybook, Webpack, Typescript and Cypress.

[category:Infrastructure]

Release Note:
- In Storybook, each component now has a "Docs" page. This is dedicated to documentation of the component and has examples as it did before. 
- We now use the Cypress Component runner and not e2e.
- Codemod formatting has been updated with a dependency update and docs have been added to reflect the formatting issue. 

The following have been upgraded:
- Storybook 7
- Webpack 5 
- Typescript 4.9
- Cypress 13

### BREAKING CHANGES
Codemods formatting have been updated and users will need to format their files after the codemod has been used.

Co-authored-by: @NicholasBoll <nicholas.boll@gmail.com>
Co-authored-by: manuel.carrera <manuel.carrera@workday.com>
Co-authored-by: @josh-bagwell <josh.bagwell@workday.com>
  • Loading branch information
4 people committed Aug 28, 2024
1 parent 0362d83 commit f1f40e7
Show file tree
Hide file tree
Showing 483 changed files with 17,606 additions and 14,497 deletions.
8 changes: 8 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,12 @@ module.exports = {
curly: 'error',
radix: 'error',
},
overrides: [
{
files: ['**/*.stories.tsx'],
rules: {
'react-hooks/rules-of-hooks': 'off',
},
},
],
};
5 changes: 1 addition & 4 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,8 @@ jobs:
path: docs
key: ${{ runner.os }}-build-${{ github.sha }}

- name: Start Server
run: npx http-server docs -p 9001 & npx wait-on http://localhost:9001

- name: Integration tests
run: yarn cypress run --record --parallel
run: yarn cypress run --component --record --parallel
env:
# Github Actions doesn't support encryption on forks
# If these keys become compromised, we will rotate and disable these features
Expand Down
82 changes: 33 additions & 49 deletions .storybook/main.js → .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
const path = require('node:path');
const createCompiler = require('@storybook/addon-docs/mdx-compiler-plugin');

const modulesPath = path.resolve(__dirname, '../modules');
const getSpecifications = require('../modules/docs/utils/get-specifications');
import {StorybookConfig} from '@storybook/react-webpack5';
const {createDocProgram} = require('../modules/docs/docgen/createDocProgram');

const processDocs = process.env.SKIP_DOCGEN !== 'true';

const Doc = createDocProgram();

module.exports = {
stories: [
'../modules/docs/mdx/**/*.mdx',
'../modules/**/*.stories.mdx',
'../modules/**/stories*.@(js|jsx|ts|tsx)',
],
const config: StorybookConfig = {
framework: '@storybook/react-webpack5',
staticDirs: ['../public'],
stories: ['../modules/**/mdx/**/*.mdx', '../modules/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
{
name: '@storybook/addon-essentials',
Expand All @@ -25,17 +23,24 @@ module.exports = {
'./readme-panel/preset.js',
'@storybook/addon-storysource',
],
core: {
builder: '@storybook/builder-webpack5',
disableTelemetry: true,
},
docs: {
autodocs: 'tag',
defaultName: 'Docs',
},
typescript: {
skipBabel: true,
check: false,
reactDocgen: false, // we'll handle this ourselves
},
webpackFinal: async (config, {configType}) => {
webpackFinal: async config => {
// Get the specifications object and replace with a real object in the spec.ts file
if (processDocs) {
const specs = await getSpecifications();

config.module.rules.push({
config.module?.rules?.push({
test: /.ts$/,
include: [path.resolve(__dirname, '../modules/docs')],
use: [
Expand All @@ -50,10 +55,10 @@ module.exports = {
});

// Load the source code of story files to display in docs.
config.module.rules.push({
test: /stories.*\.tsx?$/,
config.module?.rules?.push({
test: /\.stories\.tsx?$/,
include: [modulesPath],
loaders: [
use: [
{
loader: require.resolve('@storybook/source-loader'),
options: {parser: 'typescript'},
Expand All @@ -62,12 +67,12 @@ module.exports = {
enforce: 'pre',
});

config.module.rules.push({
config.module?.rules?.push({
test: /.+\.tsx?$/,
include: [modulesPath],
exclude: /examples|stories|spec|codemod|docs/,
loaders: [
// loaders are run in reverse order. style-transform-loader needs to be done first
use: [
// loaders are run in reverse order. symbol-doc-loader needs to be done first
{
loader: path.resolve(__dirname, 'symbol-doc-loader'),
options: {
Expand All @@ -94,9 +99,11 @@ module.exports = {
* These warnings relate to this open GitHub issue: https://github.com/microsoft/TypeScript/issues/39436
* If you no longer see these warnings when this is config is removed, you can safely delete this config.
*/
config.module.noParse = [require.resolve('typescript/lib/typescript.js')];
if (config.module) {
config.module.noParse = [require.resolve('typescript/lib/typescript.js')];
}

config.module.rules.push({
config.module?.rules?.push({
test: /\.mdx?$/,
include: [path.resolve(__dirname, '..')],
exclude: [/node_modules/],
Expand All @@ -107,12 +114,9 @@ module.exports = {
],
});

config.module.rules.push({
config.module?.rules?.push({
test: /\.mdx?$/,
include: [path.resolve(__dirname, '..')],
// Don't replace `<ExampleCodeBlock>` with Storybook tags in the
// documentation guidelines
exclude: [/node_modules/, /DOCUMENTATION_GUIDELINES/],
use: [
{
loader: path.resolve(__dirname, 'mdx-code-block-rewrite'),
Expand All @@ -121,47 +125,27 @@ module.exports = {
});

// Load the whole example code of story files to display in docs.
config.module.rules.push({
test: /examples\/.*\.tsx?$/,
config.module?.rules?.push({
test: /\/examples\/.*\.tsx?$/,
include: [modulesPath],
loaders: [
use: [
{
loader: path.resolve(__dirname, 'whole-source-loader'),
},
],
enforce: 'pre',
});

/**
* Added this because Storybook 6.3 is on emotion 10, so we rewrote the imports to point to emotion 11
* https://github.com/storybookjs/storybook/issues/13145
*/
config.resolve = {
...config.resolve,
alias: {
...config.resolve.alias,
},
};

// Update @storybook/addon-docs webpack rules to load all .mdx files in storybook
const mdxRule = config.module.rules.find(rule => rule.test.toString() === /\.mdx$/.toString());
mdxRule.use.find(loader => loader.loader.includes('mdx1-csf')).options['compilers'] = [
createCompiler({}),
];

return config;
},
babel: async options => ({
...options,
plugins: [
...options.plugins,
'@babel/plugin-transform-modules-commonjs',
// Needed temporarily until https://github.com/storybookjs/storybook/issues/14805 is resolved
['@babel/plugin-proposal-private-property-in-object', {loose: true}],
],
plugins: [...(options.plugins as []), '@babel/plugin-transform-modules-commonjs'],
presets: [
...options.presets,
...(options.presets as []),
['@babel/preset-react', {runtime: 'classic'}, 'react-16-backwards-compatible-override'],
],
}),
};

export default config;
23 changes: 13 additions & 10 deletions .storybook/manager-head.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<link rel="icon" type="image/png" href="/canvas-kit-favicon.png" sizes="192x192" />
<link rel="shortcut icon" href="/canvas-kit-favicon.ico" />
<link href="https://fonts.googleapis.com/css?family=Roboto:100,200,300,400,500&display=swap" rel="stylesheet" />
<link
href="https://fonts.googleapis.com/css?family=Roboto:100,200,300,400,500&display=swap"
rel="stylesheet"
/>
<script src="https://use.fontawesome.com/660238b999.js"></script>
<script>
document.title = 'Canvas Kit Storybook';
Expand All @@ -12,18 +15,18 @@
</style>

<style type="text/css">
body {
font-family: "Roboto", sans-serif;
/* body {
font-family: 'Roboto', sans-serif;
background: #e6f1ff !important;
font-size: 14px;
}
#storybook-explorer-tree {
font-family: "Roboto", sans-serif;
font-family: 'Roboto', sans-serif;
}
.sto-1ngr21r {
color: #0875e1 !important;
font-size: 20px;
font-family: "Roboto", sans-serif;
font-family: 'Roboto', sans-serif;
}

#storybook-explorer-menu svg {
Expand All @@ -35,20 +38,20 @@
background-color: #a6d2ff;
}

#storybook-explorer-menu a[data-selected="true"],
#storybook-explorer-menu a[data-selected="true"]:hover {
#storybook-explorer-menu a[data-selected='true'],
#storybook-explorer-menu a[data-selected='true']:hover {
background-color: #0875e1;
color: #e6f1ff;
}

#storybook-explorer-menu a[data-selected="true"] svg {
#storybook-explorer-menu a[data-selected='true'] svg {
color: #d7eafc;
}

.sidebar-subheading button,
.sidebar-subheading span,
.sidebar-item span {
color: #5e6a75;
color: #5e6a75;
}

.os-content button:hover,
Expand All @@ -59,5 +62,5 @@

.os-content button:hover svg {
color: #0875e1;
}
} */
</style>
2 changes: 1 addition & 1 deletion .storybook/manager.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {addons} from '@storybook/addons';
import {addons} from '@storybook/preview-api';
import theme from './theme';

addons.setConfig({
Expand Down
12 changes: 4 additions & 8 deletions .storybook/mdx-code-block-rewrite.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,17 @@ module.exports = function rewriteExampleCodeBlock(source) {
const hasCanvas = /import {.*Canvas[,\s}]/.test(source);
const hasStory = /import {.*Story[,\s}]/.test(source);
const hasArgsTable = /import {.*ArgsTable[,\s}]/.test(source);
const hasSource = /import {.*Source[,\s}]/.test(source);
const imports = [];
if (!hasMeta) imports.push('Meta');
if (!hasCanvas) imports.push('Canvas');
if (!hasStory) imports.push('Story');
if (!hasArgsTable) imports.push('ArgsTable');
if (!hasSource) imports.push('Source');

return (
(imports.length && hasSpecialBlocks
? `import {${imports.join(',')}} from '@storybook/addon-docs';\n\n`
: '') +
source
.replace(/\<ExampleCodeBlock code={([A-Za-z0-9]+)} \/\>/g, function replacer(match, p1, p2) {
return `<Canvas><Story name="${storyNameFromExport(
p1
)}" parameters={{storySource: {source: ${p1}.__RAW__}}}><${p1} /></Story></Canvas>`;
})
.replace(/\<PropsTable of=/g, '<ArgsTable of=')
: '') + source.replace(/\<PropsTable of=/g, '<ArgsTable of=')
);
};
94 changes: 48 additions & 46 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,60 +12,62 @@ import '@workday/canvas-tokens-web/css/system/_variables.css';
// set routes on window for testing the validity of the routes
window.__routes = routes;

/** If the string contains a phrase, prefix it. This is useful for making ordering sections */
const prefix = (phrase, prefix) => (/** @type {string} */ value) => {
const index = value.indexOf(phrase);
return index > -1 ? value.substr(0, index) + prefix + value.substr(index) : value;
};
const pipe =
(...fns) =>
value =>
fns.reduce((result, fn) => fn(result), value);
function storySort(a, b) {
const prefixFn = pipe(
prefix('welcome-', '0'),
prefix('guides-', '1'),
prefix('guides-getting-started', '1'),
prefix('styling', '2'),
prefix('styling-why-canvas-styling', '2'),
prefix('features-', '3'),
prefix('tokens-', '4'),
prefix('overview', 'a'),
prefix('components-', '5'),
prefix('hooks-and-utilities-', '6'),
prefix('preview-', '7'),
prefix('labs-', '8'),
prefix('assets-', '9'),
prefix('overview', 'a'),
prefix('css-', 'zzzz'),
prefix('css-overview-page', 'zzza'),
prefix('getting-started', 'aaabc'),
prefix('stencils', 'aabcd'),
prefix('functions', 'abcde'),
prefix('basic', 'aa'),
prefix('default', 'ab'),
prefix('testing', 'zzz'),
prefix('examples', 'zz'),
// Make sure upgrade guides follow chronological order by replacing `v9.0` with `v09.0`
value => value.replace(/v([1-9]\-0)/, '0$1')
);

const left = prefixFn(a[0]);
const right = prefixFn(b[0]);

return left === right ? 0 : left.localeCompare(right);
}

export const decorators = [CanvasProviderDecorator];

export const parameters = {
options: {
storySort,
storySort: (a, b) => {
/** If the string contains a phrase, prefix it. This is useful for making ordering sections */
const prefix = (phrase, prefix) => (/** @type {string} */ value) => {
const index = value.indexOf(phrase);
return index > -1 ? value.substr(0, index) + prefix + value.substr(index) : value;
};

const pipe =
(...fns) =>
value =>
fns.reduce((result, fn) => fn(result), value);

const prefixFn = pipe(
prefix('welcome-', '0'),
prefix('guides-', '1'),
prefix('guides-getting-started', '1'),
prefix('styling', '2'),
prefix('styling-why-canvas-styling', '2'),
prefix('features-', '3'),
prefix('tokens-', '4'),
prefix('overview', 'a'),
prefix('components-', '5'),
prefix('hooks-and-utilities-', '6'),
prefix('preview-', '7'),
prefix('labs-', '8'),
prefix('assets-', '9'),
prefix('overview', 'a'),
prefix('css-', 'zzzz'),
prefix('css-overview-page', 'zzza'),
prefix('getting-started', 'aaabc'),
prefix('stencils', 'aabcd'),
prefix('functions', 'abcde'),
prefix('basic', 'aa'),
prefix('default', 'ab'),
prefix('testing', 'zzz'),
prefix('examples', 'zz'),
// Make sure upgrade guides follow chronological order by replacing `v9.0` with `v09.0`
value => value.replace(/v([1-9]\-0)/, '0$1'),
// Make sure docs stories goes first
value => value.replace(/docs/, '0000docs')
);

const left = prefixFn(a.id);
const right = prefixFn(b.id);

return left === right ? 0 : left.localeCompare(right);
},
},
docs: {
theme,
container: DocsContainer,
page: DocsPage,
theme,
},
readme: {
codeTheme: 'github',
Expand Down
Loading

0 comments on commit f1f40e7

Please sign in to comment.