diff --git a/packages/pwa-buildpack/lib/cli/create-project.js b/packages/pwa-buildpack/lib/cli/create-project.js index 6fb6c73733..2e2c99638e 100644 --- a/packages/pwa-buildpack/lib/cli/create-project.js +++ b/packages/pwa-buildpack/lib/cli/create-project.js @@ -256,9 +256,12 @@ module.exports.handler = async function buildpackCli(argv) { ${showCommand( 'run watch' )} to start the dev server and do real-time development. + ${showCommand( + 'run storybook' + )} to start Storybook dev server and view available components in your app. ${showCommand( 'run build' - )} to build the project into optimized assets in the '/dist' directory + )} to build the project into optimized assets in the '/dist' directory. ${showCommand( 'start' )} after build to preview the app on a local staging server. diff --git a/packages/venia-concept/_buildpack/__tests__/__snapshots__/create.spec.js.snap b/packages/venia-concept/_buildpack/__tests__/__snapshots__/create.spec.js.snap index 53dbad0339..416d5dfd55 100644 --- a/packages/venia-concept/_buildpack/__tests__/__snapshots__/create.spec.js.snap +++ b/packages/venia-concept/_buildpack/__tests__/__snapshots__/create.spec.js.snap @@ -12,6 +12,8 @@ Object { "name": "whee", "private": true, "scripts": Object { + "storybook": "start-storybook -p 9001 -c src/.storybook", + "storybook:build": "build-storybook -c src/.storybook -o storybook-dist", "watch": "yarn run do watch this", }, "version": "0.0.1", @@ -30,6 +32,8 @@ Object { "name": "whee", "private": true, "scripts": Object { + "storybook": "start-storybook -p 9001 -c src/.storybook", + "storybook:build": "build-storybook -c src/.storybook -o storybook-dist", "watch": "npm run do watch this", }, "version": "0.0.1", diff --git a/packages/venia-concept/_buildpack/create.js b/packages/venia-concept/_buildpack/create.js index 005cf67120..b6981443f4 100644 --- a/packages/venia-concept/_buildpack/create.js +++ b/packages/venia-concept/_buildpack/create.js @@ -28,7 +28,10 @@ function createProjectFromVenia({ fs, tasks, options }) { 'validate-queries', 'watch' ]; - const scriptsToInsert = {}; + const scriptsToInsert = { + storybook: 'start-storybook -p 9001 -c src/.storybook', + 'storybook:build': 'build-storybook -c src/.storybook -o storybook-dist' + }; const filesToIgnore = [ 'CHANGELOG*', diff --git a/packages/venia-concept/package.json b/packages/venia-concept/package.json index f6fbef680e..fb8107b460 100644 --- a/packages/venia-concept/package.json +++ b/packages/venia-concept/package.json @@ -23,8 +23,6 @@ "prettier:fix": "yarn run -s prettier -- --write", "start": "node server.js", "start:debug": "node --inspect-brk ./node_modules/.bin/webpack-dev-server --progress --color --env.mode development", - "storybook": "echo 'Venia component stories have moved to @magento/venia-ui. Trying to run in sibling directory...' && (cd ../venia-ui && yarn run storybook:build)", - "storybook:build": "yarn run storybook", "test": "yarn run -s prettier:check && yarn run -s lint && jest", "validate-queries": "yarn run download-schema && graphql validate-magento-pwa-queries --project venia", "watch": "webpack-dev-server --progress --color --env.mode development" diff --git a/packages/venia-concept/src/.storybook/config.js b/packages/venia-concept/src/.storybook/config.js new file mode 100644 index 0000000000..890aecdcfb --- /dev/null +++ b/packages/venia-concept/src/.storybook/config.js @@ -0,0 +1,35 @@ +import React from 'react'; +import { configure, addDecorator } from '@storybook/react'; +import { Adapter } from '@magento/venia-drivers'; +import store from '../store'; +import '../index.css'; +import { PeregrineContextProvider } from '@magento/peregrine'; + +const loadStories = () => { + // Load all stories from venia-ui + const veniaContext = require.context( + '../../node_modules/@magento/venia-ui/lib', + true, + /__stories__\/.+\.js$/ + ); + veniaContext.keys().forEach(veniaContext); + + // Load all custom defined stories in src + const customContext = require.context('..', true, /__stories__\/.+\.js$/); + customContext.keys().forEach(customContext); +}; + +const backendUrl = process.env.MAGENTO_BACKEND_URL; +const apiBase = new URL('/graphql', backendUrl).toString(); + +addDecorator(storyFn => ( + + {storyFn()} + +)); + +configure(loadStories, module); diff --git a/packages/venia-concept/src/.storybook/webpack.config.js b/packages/venia-concept/src/.storybook/webpack.config.js new file mode 100644 index 0000000000..2cf5feac9c --- /dev/null +++ b/packages/venia-concept/src/.storybook/webpack.config.js @@ -0,0 +1,40 @@ +const path = require('path'); +const { + graphQL: { getUnionAndInterfaceTypes }, + Utilities: { loadEnvironment } +} = require('@magento/pwa-buildpack'); +const baseWebpackConfig = require('../../webpack.config'); +const { DefinePlugin, EnvironmentPlugin } = require('webpack'); + +// Storybook 5.2.8 uses a different signature for webpack config than webpack +// defines in the docs. +// See https://storybook.js.org/docs/configurations/custom-webpack-config/#full-control-mode +module.exports = async ({ config: storybookBaseConfig, mode }) => { + const projectConfig = loadEnvironment( + // Load .env from root + path.resolve(__dirname, '../..') + ); + + if (projectConfig.error) { + throw projectConfig.error; + } + + const unionAndInterfaceTypes = await getUnionAndInterfaceTypes(); + + const webpackConfig = await baseWebpackConfig(mode); + + storybookBaseConfig.module = webpackConfig.module; + storybookBaseConfig.resolve = webpackConfig.resolve; + + // Make sure to provide any plugins that UI code may depend on. + storybookBaseConfig.plugins = [ + ...storybookBaseConfig.plugins, + new DefinePlugin({ + UNION_AND_INTERFACE_TYPES: JSON.stringify(unionAndInterfaceTypes), + STORE_NAME: JSON.stringify('Storybook') + }), + new EnvironmentPlugin(projectConfig.env) + ]; + + return storybookBaseConfig; +}; diff --git a/packages/venia-ui/.storybook/webpack.config.js b/packages/venia-ui/.storybook/webpack.config.js index 06ba82dc34..ec9ed04e4b 100644 --- a/packages/venia-ui/.storybook/webpack.config.js +++ b/packages/venia-ui/.storybook/webpack.config.js @@ -22,7 +22,7 @@ module.exports = async ({ config: storybookBaseConfig, mode }) => { const unionAndInterfaceTypes = await getUnionAndInterfaceTypes(); - const [webpackConfig] = await baseWebpackConfig(mode); + const webpackConfig = await baseWebpackConfig(mode); storybookBaseConfig.module = webpackConfig.module; storybookBaseConfig.resolve = webpackConfig.resolve;