Add shared configuration for storybook in new '@essex/storybook-config' package. (#836)

* add common storybook config package

* semver

* update turbo in ci

* add @fluentui/react resolve alias

* lint updates

* run formatter

* ignore storybook output; drop node 18 b/c of storybook

* update sb config

* run formatter

* use regexp in default transpile matchers

* Run formatter

* add make rome_fix script public

* remove an addon

* Remove another addon

* peer out sb deps

* run format

* add storybook-static to eslintignore

* restore 18.x
This commit is contained in:
Chris Trevino 2023-01-23 10:37:58 -08:00 коммит произвёл GitHub
Родитель 160a9be1f5
Коммит cefe996078
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
21 изменённых файлов: 8891 добавлений и 336 удалений

Просмотреть файл

@ -6,5 +6,6 @@ coverage/
public/
docs/
.yarn/
storybook-static/
.pnp.*
yarn.lock

9
.github/workflows/ci.yml поставляемый
Просмотреть файл

@ -59,12 +59,17 @@ jobs:
- run: yarn install
- name: TurboRepo local server
uses: felixmosh/turborepo-gh-artifacts@v1
uses: felixmosh/turborepo-gh-artifacts@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
server-token: ${{ secrets.TURBO_SERVER_TOKEN }}
- run: yarn ci --api="http://127.0.0.1:9080" --token="${{ secrets.TURBO_SERVER_TOKEN }}" --team="essex"
- run: yarn ci
env:
TURBO_API: 'http://127.0.0.1:9080'
TURBO_TOKEN: ${{ secrets.TURBO_SERVER_TOKEN }}
TURBO_TEAM: 'essex'
- run: yarn is_clean
- name: Publish coverage to codecov.io

1
.gitignore поставляемый
Просмотреть файл

@ -12,6 +12,7 @@ packages/*/docsTemp/
# Testing Output
coverage/
storybook-static/
test-report.xml
linked_data/

3
.yarn/versions/2705a60d.yml поставляемый Normal file
Просмотреть файл

@ -0,0 +1,3 @@
declined:
- "@essex/storybook-config"
- "@essex/test-stories"

Просмотреть файл

@ -7,6 +7,13 @@ packageExtensions:
fork-ts-checker-webpack-plugin@*:
dependencies:
"@types/tapable": ^1.0.6
"@storybook/store@*":
peerDependenciesMeta:
react: { optional: true }
react-dom: { optional: true }
"@storybook/addon-docs@*":
peerDependencies:
"@babel/core": "*"
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs

Просмотреть файл

@ -15,16 +15,16 @@
"_ci_packages": "turbo run ci",
"_essex_lint": "essex check --formatter none",
"_essex_lint_fix": "essex fix --formatter none",
"_rome_check": "rome ci .",
"rome_check": "rome ci .",
"format": "rome format . --write",
"_rome_check_apply": "rome check --apply-suggested .",
"rome_fix": "rome check --apply-suggested .",
"clean": "turbo run clean",
"check": "run-s _rome_check _check_packages _essex_lint",
"check-deps": "turbo run check-deps",
"fix": "run-s _fix_packages _essex_lint_fix format _rome_check_apply",
"fix": "run-s _fix_packages _essex_lint_fix format rome_fix",
"build": "turbo run build",
"test": "turbo run test",
"ci": "run-s _rome_check _ci_packages _essex_lint",
"ci": "run-s rome_check _ci_packages _essex_lint",
"is_clean": "essex git-is-clean",
"update_sdks": "yarn dlx @yarnpkg/sdks vscode",
"release": "run-s clean _version_cut ci _release_packages"

Просмотреть файл

@ -0,0 +1,65 @@
{
"name": "@essex/storybook-config",
"version": "0.0.1",
"scripts": {
"clean": "rimraf dist",
"build": "tsc -b ."
},
"exports": {
".": "./lib/index.js",
"./main": "./lib/main.js",
"./main.js": "./lib/main.js",
"./preview": "./lib/preview.js",
"./preview.js": "./lib/preview.js",
"./babel.config": "./lib/babel.config.js",
"./babel.config.js": "./lib/babel.config.js"
},
"dependencies": {
"@open-wc/webpack-import-meta-loader": "^0.4.7",
"hsluv": "^1.0.0",
"react-docgen-typescript": "^2.2.2",
"react-is": "^18.2.0",
"resolve-typescript-plugin": "^2.0.0",
"tslib": "^2.4.1"
},
"devDependencies": {
"@babel/core": "^7.16.5",
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@essex/tsconfig-node": "workspace:^",
"@fluentui/react": "^8.104.6",
"@storybook/addon-essentials": "^6.5.15",
"@storybook/addon-interactions": "^6.5.15",
"@storybook/addon-links": "^6.5.15",
"@storybook/react": "^6.5.15",
"@thematic/core": "^4.0.4",
"@thematic/fluent": "^5.0.5",
"@thematic/react": "^2.1.6",
"@types/open-wc__webpack-import-meta-loader": "^0",
"@types/react": "^18.0.27",
"@types/styled-components": "^5.1.26",
"@types/webpack": "^5.28.0",
"react": "^18.2.0",
"rimraf": "^4.1.1",
"styled-components": "^5.3.6",
"typescript": "^4.9.4"
},
"peerDependencies": {
"@babel/core": ">= 7",
"@babel/preset-env": ">= 7",
"@babel/preset-react": ">= 7",
"@babel/preset-typescript": ">= 7",
"@fluentui/react": ">= 8",
"@storybook/addon-essentials": ">= 6",
"@storybook/addon-interactions": ">= 6",
"@storybook/addon-links": ">= 6",
"@storybook/react": ">= 6",
"@thematic/core": ">= 4",
"@thematic/fluent": ">= 5",
"@thematic/react": ">= 2",
"react": ">= 18",
"react-dom": ">= 18",
"styled-components": ">= 5"
}
}

Просмотреть файл

@ -0,0 +1,60 @@
/*!
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project.
*/
import { initializeIcons, Toggle } from '@fluentui/react'
import type { StoryFnReactReturnType } from '@storybook/react/dist/ts3.9/client/preview/types'
import { loadById } from '@thematic/core'
import { loadFluentTheme, ThematicFluentProvider } from '@thematic/fluent'
import { ApplicationStyles } from '@thematic/react'
import { useCallback, useMemo, useState } from 'react'
import styled, { ThemeProvider } from 'styled-components'
initializeIcons()
/**
* ThematicFluentDecorator configures both Thematic and the Fluent wrapper
* @param storyFn
*/
export const ThematicFluentDecorator = (
storyFn: any,
): StoryFnReactReturnType => {
const [dark, setDark] = useState(false)
// load a non-standard theme, so it is obvious that it isn't the default
// this helps identify problems with theme application in Fluent, which looks a lot like our default essex theme
const thematicTheme = useMemo(
() =>
loadById('autumn', {
dark,
}),
[dark],
)
const fluentTheme = useMemo(
() => loadFluentTheme(thematicTheme),
[thematicTheme],
)
const handleDarkChange = useCallback(
(_e: unknown, v: boolean | undefined) => {
setDark(v ?? false)
},
[],
)
return (
<ThematicFluentProvider theme={thematicTheme}>
<style>
{`* {
box-sizing: border-box;
}`}
</style>
<ApplicationStyles />
<Toggle label="Dark mode" checked={dark} onChange={handleDarkChange} />
<ThemeProvider theme={fluentTheme}>
<Container>{storyFn(undefined, undefined)}</Container>
</ThemeProvider>
</ThematicFluentProvider>
)
}
const Container = styled.div`
padding: 20px;
border: 1px solid ${({ theme }) => theme.application().faint().hex()};
`

Просмотреть файл

@ -0,0 +1,18 @@
/*!
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project.
*/
module.exports = {
presets: [
[require.resolve('@babel/preset-react'), { runtime: 'automatic' }],
[
require.resolve('@babel/preset-env'),
{
targets: {
esmodules: true,
},
},
],
[require.resolve('@babel/preset-typescript'), {}],
],
}

Просмотреть файл

@ -0,0 +1,5 @@
/*!
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project.
*/
throw new Error('')

Просмотреть файл

@ -0,0 +1,119 @@
/*!
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project.
*/
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import ResolveTypescriptPlugin from 'resolve-typescript-plugin'
import type {
Configuration as WebpackConfig,
RuleSetRule,
WebpackPluginInstance,
} from 'webpack'
export interface EssexStorybookConfig {
stories?: string[]
staticDirs?: string[]
resolveAliases?: Record<string, string>
transpileMatch: (string | RegExp)[]
}
const DEFAULT_STORIES = [
/**
* search sibling packages by default
*/
'../../*/src/**/*.stories.@(mdx|js|jsx|ts|tsx)',
]
const DEFAULT_STATIC_DIRS: string[] = []
const DEFAULT_TRANSPILE_MATCHES = [/@essex\/components/, /styled-components/]
export function configure({
stories = DEFAULT_STORIES,
staticDirs = DEFAULT_STATIC_DIRS,
resolveAliases = {},
transpileMatch = [],
}: EssexStorybookConfig) {
return {
stories,
staticDirs,
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
],
framework: '@storybook/react',
typescript: {
reactDocgen: require.resolve('react-docgen-typescript'),
reactDocgenTypescriptOptions: {
compilerOptions: {
allowSyntheticDefaultImports: false,
esModuleInterop: false,
},
},
},
webpackFinal(config: WebpackConfig) {
// mute build output
if (process.env['CI'] || process.env['SB_QUIET']) {
config.stats = 'errors-only'
config.plugins = config.plugins?.filter(
(plugin: WebpackPluginInstance) =>
plugin.constructor.name !== 'ProgressPlugin',
)
}
if (!config.resolve) {
config.resolve = {}
}
config.resolve.alias = {
...(config.resolve.alias ?? {}),
'styled-components': require.resolve('styled-components'),
hsluv: require.resolve('hsluv'),
'@thematic/react': require.resolve('@thematic/react'),
'@thematic/fluent': require.resolve('@thematic/fluent'),
'@fluentui/react': require.resolve('@fluentui/react'),
...resolveAliases,
}
// resolve files ending with .ts
if (!config.resolve.plugins) {
config.resolve.plugins = []
}
// Resolve extensions from TS code
config.resolve.plugins.push(new ResolveTypescriptPlugin())
// run transpiler over monorepo linked projects
const firstRule = config.module?.rules?.[0] as RuleSetRule | undefined
if (firstRule != null) {
const transpileMatchRules: RuleSetRule[] = [
...DEFAULT_TRANSPILE_MATCHES,
transpileMatch,
].map((match) => {
return {
...firstRule,
include: match,
exclude: undefined,
}
})
const importMeta = {
test: /\.js$/,
loader: require.resolve('@open-wc/webpack-import-meta-loader'),
}
const handleMjs = {
test: /\.mjs$/,
include: /node_modules/,
type: 'javascript/auto',
}
config.module!.rules!.push(
...transpileMatchRules,
importMeta,
handleMjs,
)
} else {
throw new Error('unexpected incoming webpack config')
}
return config
},
}
}

Просмотреть файл

@ -0,0 +1,9 @@
/*!
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project.
*/
import { addDecorator } from '@storybook/react'
import { ThematicFluentDecorator } from './ThematicFluentDecorator.js'
addDecorator(ThematicFluentDecorator)

Просмотреть файл

@ -0,0 +1,10 @@
{
"extends": "@essex/tsconfig-node",
"compilerOptions": {
"module": "CommonJS",
"outDir": "lib",
"jsx": "react-jsx",
"declaration": true
},
"include": ["src/**/*.ts*"]
}

Просмотреть файл

@ -0,0 +1,3 @@
const config = require('@essex/storybook-config/babel.config')
module.exports = config

Просмотреть файл

@ -0,0 +1,6 @@
const { configure } = require('@essex/storybook-config/main')
const path = require('path')
module.exports = configure({
stories: [path.join(__dirname, '../src/*.stories.tsx')],
})

Просмотреть файл

@ -0,0 +1,3 @@
const config = require('@essex/storybook-config/lib/preview.js')
module.exports = config

Просмотреть файл

@ -0,0 +1,34 @@
{
"name": "@essex/test-stories",
"version": "0.0.1",
"private": true,
"scripts": {
"clean": "rimraf dist storybook_static",
"build": "build-storybook",
"start": "start-storybook"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/essex-js-build.git",
"directory": "packages/test-suite-lib"
},
"devDependencies": {
"@babel/core": "^7.16.5",
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@essex/scripts": "workspace:^",
"@essex/storybook-config": "workspace:^",
"@essex/tsconfig-base": "workspace:^",
"@storybook/addon-essentials": "^6.5.15",
"@storybook/addon-interactions": "^6.5.15",
"@storybook/addon-links": "^6.5.15",
"@storybook/react": "^6.5.15",
"@types/react": "^18.0.27"
},
"dependencies": {
"@types/react-dom": "^18.0.10",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
}

Просмотреть файл

@ -0,0 +1,13 @@
/*!
* Copyright (c) Microsoft. All rights reserved.
* Licensed under the MIT license. See LICENSE file in the project.
*/
const Component = () => <div>A story lives here</div>
const meta = {
title: '@essex:components/Tree',
component: Component,
}
export default meta
export const Basic = () => <Component />

Просмотреть файл

@ -0,0 +1,10 @@
{
"extends": "../config-ts-base/tsconfig",
"compilerOptions": {
"outDir": "lib",
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"jsx": "react-jsx"
},
"include": ["src"]
}

Просмотреть файл

@ -1,5 +1,16 @@
{
"$schema": "./node_modules/rome/configuration_schema.json",
"files": {
"ignore": [
"dist",
"lib",
"build",
"storybook-static",
".turbo",
".pnp.cjs",
".pnp.loader.mjs"
]
},
"linter": {
"enabled": true,
"rules": {
@ -7,15 +18,7 @@
"suspicious": {
"noExplicitAny": "off"
}
},
"ignore": [
"dist",
"lib",
"build",
".turbo",
".pnp.cjs",
".pnp.loader.mjs"
]
}
},
"javascript": {
"formatter": {
@ -26,14 +29,6 @@
}
},
"formatter": {
"indentStyle": "tab",
"ignore": [
"dist",
"lib",
"build",
".turbo",
".pnp.cjs",
".pnp.loader.mjs"
]
"indentStyle": "tab"
}
}

8812
yarn.lock

Разница между файлами не показана из-за своего большого размера Загрузить разницу