diff --git a/.changeset/pink-feet-trade.md b/.changeset/pink-feet-trade.md
new file mode 100644
index 000000000..d63683ebd
--- /dev/null
+++ b/.changeset/pink-feet-trade.md
@@ -0,0 +1,11 @@
+---
+'sku': minor
+---
+
+Adds support for Storybook configuration via the `.storybook` directory
+
+sku now supports the standard `.storybook` configuration directory, as documented in [Storybook's configuration documentation].
+Please read [sku's storybook documentation][sku storybook docs] for more info.
+
+[Storybook configuration documentation]: https://storybook.js.org/docs/react/configure/overview
+[sku storybook docs]: https://seek-oss.github.io/sku/#/./docs/storybook
diff --git a/.changeset/real-rabbits-yawn.md b/.changeset/real-rabbits-yawn.md
new file mode 100644
index 000000000..f05d82128
--- /dev/null
+++ b/.changeset/real-rabbits-yawn.md
@@ -0,0 +1,13 @@
+---
+'sku': minor
+---
+
+Drop support for running `devServerMiddleware` alongside `sku storybook`
+
+Now that sku supports Storybook configuration via the `.storybook` directory, this feature is unnecessary.
+Storybook middleware can be configured by creating a `middleware.js` file in the `.storybook` directory.
+See [the sku docs][sku storybook middleware] for more info.
+
+**NOTE**: While this is technically a breaking change, it does not affect app builds, therefore it has been downgraded to a `minor` release.
+
+[sku storybook middleware]: https://seek-oss.github.io/sku/#/./docs/storybook?id=devserver-middleware
diff --git a/docs/docs/storybook.md b/docs/docs/storybook.md
index 28d198cc6..353af6f59 100644
--- a/docs/docs/storybook.md
+++ b/docs/docs/storybook.md
@@ -21,6 +21,35 @@ export const Secondary = () => ;
_**NOTE:** To access the Storybook API, you should import from `sku/@storybook/...`, since your project isn't depending on Storybook packages directly._
+## Configuration
+
+Storybook can be configured by creating specially-named files inside the `.storybook` folder of your app.
+Take a look at the [Storybook configuration docs] for all the ways to customize your Storybook.
+
+_**NOTE:** sku maintains control of the `main.js` configuration file as it is critical to ensuring compatibility between Storybook and your app.
+If you have a valid use case for customizing this file, please reach out in [`#sku-support`]._
+
+[Storybook configuration docs]: https://storybook.js.org/docs/react/configure/overview
+[`#sku-support`]: https://seekchat.slack.com/channels/sku-support
+
+### Addons
+
+There are no storybook addons configured by default in sku but they can be added through the `storybookAddons` option in `sku.config.ts`.
+
+For example, if you want to use `@storybook/addon-essentials`, first install the addon.
+
+```bash
+yarn add --dev @storybook/addon-essentials
+```
+
+Then add it to your `sku.config.ts`.
+
+```ts
+export default {
+ storybookAddons: ['@storybook/addon-essentials'],
+} satisfies SkuConfig;
+```
+
### Story Rendering
Story rendering can be customized globally by creating a `.storybook/preview.js` (or `.ts`, or `.tsx`) file.
@@ -53,7 +82,14 @@ See [the Storybook docs][storybook preview.js] for more info.
### DevServer Middleware
-When running `sku storybook`, if you have configured [`devServerMiddleware`][devserver middleware] in your sku config, that middleware will be passed through to storybook and injected into its own middleware stack.
+When running `sku storybook`, if you want to run your [`devServerMiddleware`][devserver middleware] at the same time, add a `middleware.js` file to the `.storybook` folder and export it:
+
+```js
+// .storybook/middleware.js
+import devServerMiddleware from '../devServerMiddleware.js';
+
+export default devServerMiddleware;
+```
[devserver middleware]: ./docs/extra-features.md#devserver-middleware
@@ -68,24 +104,6 @@ export default {
} satisfies SkuConfig;
```
-## Addons
-
-There are no storybook addons configured by default in sku but they can be added through the `storybookAddons` option in `sku.config.ts`.
-
-For example, if you want to use `@storybook/addon-essentials`, first install the addon.
-
-```bash
-yarn add --dev @storybook/addon-essentials
-```
-
-Then add it to your `sku.config.ts`.
-
-```ts
-export default {
- storybookAddons: ['@storybook/addon-essentials'],
-} satisfies SkuConfig;
-```
-
## Build Storybook
To build your Storybook, first add the following npm script:
diff --git a/fixtures/assertion-removal/.eslintignore b/fixtures/assertion-removal/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/assertion-removal/.eslintignore
+++ b/fixtures/assertion-removal/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/assertion-removal/.gitignore b/fixtures/assertion-removal/.gitignore
index 9472e0ebe..d2e00244e 100644
--- a/fixtures/assertion-removal/.gitignore
+++ b/fixtures/assertion-removal/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/assertion-removal/.prettierignore b/fixtures/assertion-removal/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/assertion-removal/.prettierignore
+++ b/fixtures/assertion-removal/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/braid-design-system/.eslintignore b/fixtures/braid-design-system/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/braid-design-system/.eslintignore
+++ b/fixtures/braid-design-system/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/braid-design-system/.gitignore b/fixtures/braid-design-system/.gitignore
index 9472e0ebe..d2e00244e 100644
--- a/fixtures/braid-design-system/.gitignore
+++ b/fixtures/braid-design-system/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/braid-design-system/.prettierignore b/fixtures/braid-design-system/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/braid-design-system/.prettierignore
+++ b/fixtures/braid-design-system/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/custom-src-paths/.eslintignore b/fixtures/custom-src-paths/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/custom-src-paths/.eslintignore
+++ b/fixtures/custom-src-paths/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/custom-src-paths/.gitignore b/fixtures/custom-src-paths/.gitignore
index 9472e0ebe..d2e00244e 100644
--- a/fixtures/custom-src-paths/.gitignore
+++ b/fixtures/custom-src-paths/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/custom-src-paths/.prettierignore b/fixtures/custom-src-paths/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/custom-src-paths/.prettierignore
+++ b/fixtures/custom-src-paths/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/library-build/.eslintignore b/fixtures/library-build/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/library-build/.eslintignore
+++ b/fixtures/library-build/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/library-build/.gitignore b/fixtures/library-build/.gitignore
index 9472e0ebe..d2e00244e 100644
--- a/fixtures/library-build/.gitignore
+++ b/fixtures/library-build/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/library-build/.prettierignore b/fixtures/library-build/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/library-build/.prettierignore
+++ b/fixtures/library-build/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/library-file/.eslintignore b/fixtures/library-file/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/library-file/.eslintignore
+++ b/fixtures/library-file/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/library-file/.gitignore b/fixtures/library-file/.gitignore
index 9472e0ebe..d2e00244e 100644
--- a/fixtures/library-file/.gitignore
+++ b/fixtures/library-file/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/library-file/.prettierignore b/fixtures/library-file/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/library-file/.prettierignore
+++ b/fixtures/library-file/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/lint-format/.eslintignore b/fixtures/lint-format/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/lint-format/.eslintignore
+++ b/fixtures/lint-format/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/lint-format/.gitignore b/fixtures/lint-format/.gitignore
index e603e2924..4f42a791f 100644
--- a/fixtures/lint-format/.gitignore
+++ b/fixtures/lint-format/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/lint-format/.prettierignore b/fixtures/lint-format/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/lint-format/.prettierignore
+++ b/fixtures/lint-format/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/multiple-routes/.eslintignore b/fixtures/multiple-routes/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/multiple-routes/.eslintignore
+++ b/fixtures/multiple-routes/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/multiple-routes/.gitignore b/fixtures/multiple-routes/.gitignore
index 9472e0ebe..d2e00244e 100644
--- a/fixtures/multiple-routes/.gitignore
+++ b/fixtures/multiple-routes/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/multiple-routes/.prettierignore b/fixtures/multiple-routes/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/multiple-routes/.prettierignore
+++ b/fixtures/multiple-routes/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/public-path/.eslintignore b/fixtures/public-path/.eslintignore
index 58df60132..1c8778aba 100644
--- a/fixtures/public-path/.eslintignore
+++ b/fixtures/public-path/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/static/
diff --git a/fixtures/public-path/.gitignore b/fixtures/public-path/.gitignore
index 987acfe8f..f10987025 100644
--- a/fixtures/public-path/.gitignore
+++ b/fixtures/public-path/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/static/
diff --git a/fixtures/public-path/.prettierignore b/fixtures/public-path/.prettierignore
index 58df60132..1c8778aba 100644
--- a/fixtures/public-path/.prettierignore
+++ b/fixtures/public-path/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/static/
diff --git a/fixtures/react-css-modules/.eslintignore b/fixtures/react-css-modules/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/react-css-modules/.eslintignore
+++ b/fixtures/react-css-modules/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/react-css-modules/.gitignore b/fixtures/react-css-modules/.gitignore
index 9472e0ebe..d2e00244e 100644
--- a/fixtures/react-css-modules/.gitignore
+++ b/fixtures/react-css-modules/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/react-css-modules/.prettierignore b/fixtures/react-css-modules/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/react-css-modules/.prettierignore
+++ b/fixtures/react-css-modules/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/sku-test/.eslintignore b/fixtures/sku-test/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/sku-test/.eslintignore
+++ b/fixtures/sku-test/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/sku-test/.gitignore b/fixtures/sku-test/.gitignore
index 9472e0ebe..d2e00244e 100644
--- a/fixtures/sku-test/.gitignore
+++ b/fixtures/sku-test/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/sku-test/.prettierignore b/fixtures/sku-test/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/sku-test/.prettierignore
+++ b/fixtures/sku-test/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/sku-with-https/.eslintignore b/fixtures/sku-with-https/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/sku-with-https/.eslintignore
+++ b/fixtures/sku-with-https/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/sku-with-https/.gitignore b/fixtures/sku-with-https/.gitignore
index 7bfb4a45b..f6980b14d 100644
--- a/fixtures/sku-with-https/.gitignore
+++ b/fixtures/sku-with-https/.gitignore
@@ -2,6 +2,7 @@
.eslintrc
.prettierrc
.ssl
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/sku-with-https/.prettierignore b/fixtures/sku-with-https/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/sku-with-https/.prettierignore
+++ b/fixtures/sku-with-https/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/source-maps/.eslintignore b/fixtures/source-maps/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/source-maps/.eslintignore
+++ b/fixtures/source-maps/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/source-maps/.gitignore b/fixtures/source-maps/.gitignore
index 9472e0ebe..d2e00244e 100644
--- a/fixtures/source-maps/.gitignore
+++ b/fixtures/source-maps/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/source-maps/.prettierignore b/fixtures/source-maps/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/source-maps/.prettierignore
+++ b/fixtures/source-maps/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/ssr-hello-world/.eslintignore b/fixtures/ssr-hello-world/.eslintignore
index e9b94e25e..bca860144 100644
--- a/fixtures/ssr-hello-world/.eslintignore
+++ b/fixtures/ssr-hello-world/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-build/
dist-storybook/
diff --git a/fixtures/ssr-hello-world/.gitignore b/fixtures/ssr-hello-world/.gitignore
index 2395ad75e..e646cbdd9 100644
--- a/fixtures/ssr-hello-world/.gitignore
+++ b/fixtures/ssr-hello-world/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-build/
dist-storybook/
diff --git a/fixtures/ssr-hello-world/.prettierignore b/fixtures/ssr-hello-world/.prettierignore
index e9b94e25e..bca860144 100644
--- a/fixtures/ssr-hello-world/.prettierignore
+++ b/fixtures/ssr-hello-world/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-build/
dist-storybook/
diff --git a/fixtures/storybook-config/.eslintignore b/fixtures/storybook-config/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/storybook-config/.eslintignore
+++ b/fixtures/storybook-config/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/storybook-config/.gitignore b/fixtures/storybook-config/.gitignore
index 6e1650ecc..5d73a2f5c 100644
--- a/fixtures/storybook-config/.gitignore
+++ b/fixtures/storybook-config/.gitignore
@@ -4,6 +4,7 @@ npm-debug.log
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/storybook-config/.prettierignore b/fixtures/storybook-config/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/storybook-config/.prettierignore
+++ b/fixtures/storybook-config/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/storybook-config/.storybook/middleware.js b/fixtures/storybook-config/.storybook/middleware.js
new file mode 100644
index 000000000..6d7fa83d6
--- /dev/null
+++ b/fixtures/storybook-config/.storybook/middleware.js
@@ -0,0 +1,3 @@
+import middleware from '../dev-middleware';
+
+export default middleware;
diff --git a/fixtures/storybook-config/.storybook/preview.tsx b/fixtures/storybook-config/.storybook/preview.tsx
index f561527bb..57fe89090 100644
--- a/fixtures/storybook-config/.storybook/preview.tsx
+++ b/fixtures/storybook-config/.storybook/preview.tsx
@@ -5,7 +5,7 @@ import apac from 'braid-design-system/themes/apac';
import type { Preview } from 'sku/@storybook/react';
-const preview: Preview = {
+export default {
decorators: [
(Story) => (
@@ -21,6 +21,4 @@ const preview: Preview = {
),
],
-};
-
-export default preview;
+} satisfies Preview;
diff --git a/fixtures/styling/.eslintignore b/fixtures/styling/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/styling/.eslintignore
+++ b/fixtures/styling/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/styling/.gitignore b/fixtures/styling/.gitignore
index 9472e0ebe..d2e00244e 100644
--- a/fixtures/styling/.gitignore
+++ b/fixtures/styling/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/styling/.prettierignore b/fixtures/styling/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/styling/.prettierignore
+++ b/fixtures/styling/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/translations/.eslintignore b/fixtures/translations/.eslintignore
index b2d0a058b..70e1e3110 100644
--- a/fixtures/translations/.eslintignore
+++ b/fixtures/translations/.eslintignore
@@ -1,6 +1,7 @@
# managed by sku
**/*.vocab/index.ts
*.less.d.ts
+.storybook/main.js
coverage/
dist-ssr/
dist-storybook/
diff --git a/fixtures/translations/.gitignore b/fixtures/translations/.gitignore
index 9aaf8c715..83ebc8152 100644
--- a/fixtures/translations/.gitignore
+++ b/fixtures/translations/.gitignore
@@ -4,6 +4,7 @@
**/*.vocab/index.ts
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-ssr/
dist-storybook/
diff --git a/fixtures/translations/.prettierignore b/fixtures/translations/.prettierignore
index 5121f98f6..ba10121aa 100644
--- a/fixtures/translations/.prettierignore
+++ b/fixtures/translations/.prettierignore
@@ -3,6 +3,7 @@ translations.ts
# managed by sku
**/*.vocab/index.ts
*.less.d.ts
+.storybook/main.js
coverage/
dist-ssr/
dist-storybook/
diff --git a/fixtures/typescript-css-modules/.eslintignore b/fixtures/typescript-css-modules/.eslintignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/typescript-css-modules/.eslintignore
+++ b/fixtures/typescript-css-modules/.eslintignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/typescript-css-modules/.gitignore b/fixtures/typescript-css-modules/.gitignore
index 9472e0ebe..d2e00244e 100644
--- a/fixtures/typescript-css-modules/.gitignore
+++ b/fixtures/typescript-css-modules/.gitignore
@@ -1,6 +1,7 @@
# managed by sku
.eslintrc
.prettierrc
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/fixtures/typescript-css-modules/.prettierignore b/fixtures/typescript-css-modules/.prettierignore
index be5af46ed..a8fee4a3e 100644
--- a/fixtures/typescript-css-modules/.prettierignore
+++ b/fixtures/typescript-css-modules/.prettierignore
@@ -1,5 +1,6 @@
# managed by sku
*.less.d.ts
+.storybook/main.js
coverage/
dist-storybook/
dist/
diff --git a/packages/sku/config/storybook/build/main.js b/packages/sku/config/storybook/build/main.js
deleted file mode 100644
index 5686f9864..000000000
--- a/packages/sku/config/storybook/build/main.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('../config');
diff --git a/packages/sku/config/storybook/build/webpack.config.js b/packages/sku/config/storybook/build/webpack.config.js
deleted file mode 100644
index f150312fa..000000000
--- a/packages/sku/config/storybook/build/webpack.config.js
+++ /dev/null
@@ -1,4 +0,0 @@
-const storybookWebpackConfig = require('../storybookWebpackConfig');
-
-module.exports = (storybookConfig) =>
- storybookWebpackConfig(storybookConfig, { isDevServer: false });
diff --git a/packages/sku/config/storybook/config.js b/packages/sku/config/storybook/config.js
deleted file mode 100644
index c060dc4e4..000000000
--- a/packages/sku/config/storybook/config.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const fs = require('fs');
-const path = require('path');
-const {
- paths,
- storybookAddons,
- storybookStoryStore,
-} = require('../../context');
-
-/** @type {import("@storybook/react-webpack5").StorybookConfig} */
-module.exports = {
- stories: paths.src
- .filter((srcPath) => fs.statSync(srcPath).isDirectory())
- .map((srcPath) => path.join(srcPath, '**/*.stories.@(js|ts|tsx)')),
- addons: storybookAddons,
- framework: {
- name: '@storybook/react-webpack5',
- options: {},
- },
- core: {
- builder: {
- name: '@storybook/builder-webpack5',
- options: {
- fsCache: true,
- },
- },
- },
- features: {
- storyStoreV7: storybookStoryStore,
- },
- babel: (config) => ({
- ...config,
- presets: [
- ...config.presets,
- [
- require.resolve('@babel/preset-env'),
- {
- targets: {
- chrome: 100,
- },
- },
- ],
- require.resolve('@babel/preset-typescript'),
- ],
- }),
-};
diff --git a/packages/sku/config/storybook/index.js b/packages/sku/config/storybook/index.js
new file mode 100644
index 000000000..7bced1d34
--- /dev/null
+++ b/packages/sku/config/storybook/index.js
@@ -0,0 +1,68 @@
+const fs = require('fs');
+const path = require('path');
+const {
+ paths,
+ storybookAddons,
+ storybookStoryStore,
+} = require('../../context');
+
+const makeStorybookWebpackConfig = require('./storybookWebpackConfig');
+
+/** @type {import("@storybook/react-webpack5").StorybookConfig} */
+module.exports = {
+ stories: paths.src
+ .filter((srcPath) => fs.statSync(srcPath).isDirectory())
+ .map((srcPath) => path.join(srcPath, '**/*.stories.@(js|ts|tsx)')),
+ addons: storybookAddons,
+ framework: {
+ // Storybook looks for a `/preset` entrypoint on the framework package,
+ // so we give it only the dirname of the resolved package path
+ // https://github.com/storybookjs/storybook/blob/aecfa1791f982bef6a06b51d20df3e31dd82b5b4/code/lib/core-common/src/utils/validate-config.ts#L34
+ name: path.dirname(require.resolve('@storybook/react-webpack5')),
+ options: {},
+ },
+ core: {
+ builder: {
+ name: require.resolve('@storybook/builder-webpack5'),
+ options: {
+ fsCache: true,
+ },
+ },
+ disableTelemetry: true,
+ },
+ features: {
+ storyStoreV7: storybookStoryStore,
+ },
+ // sku storybook -> configType === 'DEVELOPMENT'
+ // sku build-storybook -> configType === 'PRODUCTION'
+ webpackFinal: (config, { configType }) =>
+ makeStorybookWebpackConfig(config, {
+ isDevServer: configType === 'DEVELOPMENT',
+ }),
+ babel: (config) => ({
+ ...config,
+ presets: [
+ // Includes `@babel/preset-react`
+ ...config.presets,
+
+ // Storybook as of 7.0 no longer handles babel stuff for you (other than react)
+ // We need to configure TypeScript support ourselves, if we want it
+ // https://github.com/storybookjs/storybook/issues/22357#issuecomment-1532548058
+ [
+ require.resolve('@babel/preset-env'),
+ {
+ targets: {
+ chrome: 100,
+ },
+ },
+ ],
+ [
+ require.resolve('@babel/preset-typescript'),
+ {
+ allExtensions: true,
+ isTSX: true,
+ },
+ ],
+ ],
+ }),
+};
diff --git a/packages/sku/config/storybook/start/main.js b/packages/sku/config/storybook/start/main.js
deleted file mode 100644
index 5686f9864..000000000
--- a/packages/sku/config/storybook/start/main.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('../config');
diff --git a/packages/sku/config/storybook/start/middleware.js b/packages/sku/config/storybook/start/middleware.js
deleted file mode 100644
index c48e34d7d..000000000
--- a/packages/sku/config/storybook/start/middleware.js
+++ /dev/null
@@ -1,10 +0,0 @@
-const { paths, useDevServerMiddleware } = require('../../../context');
-
-const dummyMiddleware = (app) => app;
-let middleware = dummyMiddleware;
-
-if (useDevServerMiddleware) {
- middleware = require(paths.devServerMiddleware);
-}
-
-module.exports = middleware;
diff --git a/packages/sku/config/storybook/start/webpack.config.js b/packages/sku/config/storybook/start/webpack.config.js
deleted file mode 100644
index c26d286be..000000000
--- a/packages/sku/config/storybook/start/webpack.config.js
+++ /dev/null
@@ -1,4 +0,0 @@
-const storybookWebpackConfig = require('../storybookWebpackConfig');
-
-module.exports = (storybookConfig) =>
- storybookWebpackConfig(storybookConfig, { isDevServer: true });
diff --git a/packages/sku/config/storybook/storybookWebpackConfig.js b/packages/sku/config/storybook/storybookWebpackConfig.js
index 6ddf57604..b6546be4e 100644
--- a/packages/sku/config/storybook/storybookWebpackConfig.js
+++ b/packages/sku/config/storybook/storybookWebpackConfig.js
@@ -6,7 +6,11 @@ const { resolvePackage } = require('../webpack/utils/resolvePackage');
const hot = process.env.SKU_HOT !== 'false';
-module.exports = ({ config }, { isDevServer }) => {
+/**
+ * @param {import("webpack").Configuration} config
+ * @param {{isDevServer: boolean}}
+ */
+module.exports = (config, { isDevServer }) => {
const clientWebpackConfig = find(
makeWebpackConfig({
isIntegration: true,
diff --git a/packages/sku/lib/configure.js b/packages/sku/lib/configure.js
index 01516d9ea..2d064e99f 100755
--- a/packages/sku/lib/configure.js
+++ b/packages/sku/lib/configure.js
@@ -1,4 +1,5 @@
#!/usr/bin/env node
+
const { writeFile, rm } = require('fs/promises');
const path = require('path');
@@ -13,12 +14,14 @@ const prettierConfig = require('../config/prettier/prettierConfig');
const eslintConfig = require('../config/eslint/eslintConfig');
const createTSConfig = require('../config/typescript/tsconfig.js');
const getCertificate = require('./certificate');
+const { storybookMainConfigPath } = require('./storybook');
+const managedConfigBanner = require('./managedConfigBanner.js');
+
const coverageFolder = 'coverage';
const convertToForwardSlashPaths = (pathStr) => pathStr.replace(/\\/g, '/');
const addSep = (p) => `${p}${path.sep}`;
-const prependBanner = (str) =>
- `/** THIS FILE IS GENERATED BY SKU, MANUAL CHANGES WILL BE DISCARDED **/\n${str}`;
+const prependBanner = (str) => `${managedConfigBanner}\n${str}`;
const writeFileToCWD = async (fileName, content, { banner = true } = {}) => {
const outPath = getPathFromCwd(fileName);
@@ -28,20 +31,18 @@ const writeFileToCWD = async (fileName, content, { banner = true } = {}) => {
await writeFile(outPath, contentStr);
};
-const storybookMainConfig = '.storybook/main.js';
-
module.exports = async () => {
// Ignore webpack bundle report output
const gitIgnorePatterns = [
addSep(bundleReportFolder),
addSep(coverageFolder),
- storybookMainConfig,
+ storybookMainConfigPath,
];
const lintIgnorePatterns = [
addSep(bundleReportFolder),
addSep(coverageFolder),
'*.less.d.ts',
- storybookMainConfig,
+ storybookMainConfigPath,
];
// Ignore webpack target directories
diff --git a/packages/sku/lib/managedConfigBanner.js b/packages/sku/lib/managedConfigBanner.js
new file mode 100644
index 000000000..a5e8e157b
--- /dev/null
+++ b/packages/sku/lib/managedConfigBanner.js
@@ -0,0 +1 @@
+module.exports = `/** THIS FILE IS GENERATED BY SKU, MANUAL CHANGES WILL BE DISCARDED **/`;
diff --git a/packages/sku/lib/storybook.js b/packages/sku/lib/storybook.js
index cdc8ac1fe..f3fe7816c 100644
--- a/packages/sku/lib/storybook.js
+++ b/packages/sku/lib/storybook.js
@@ -1,70 +1,35 @@
const path = require('path');
-
-const { paths } = require('../context');
const fs = require('fs/promises');
const debug = require('debug');
-const glob = require('fast-glob');
const log = debug('sku:storybook');
-const previewFileName = 'preview.{js,ts,tsx}';
-
-const previewFileAbsolutePath = path.join(
- path.dirname(paths.appSkuConfigPath),
- '.storybook',
- previewFileName,
-);
-
-/**
- * This function first cleans up any existing preview.{js,ts,tsx} files in the provided storybook config directory.
- * This includes any potentially dangling symlinks.
- * Then it looks for a `.storybook/preview.{js,ts,tsx}` file relative to the sku config.
- * If 1 file is found, a symlink pointing to it is created in the provided storybook config directory.
- * Does nothing if 0 or >1 files are found.
- *
- * @param {string} storybookConfigDirectory The path to the storybook config directory
- */
-const setUpStorybookPreviewFile = async (storybookConfigDirectory) => {
- const symlinkFileAsbolutePath = path.join(
- storybookConfigDirectory,
- previewFileName,
- );
- const symlinkFiles = await glob(symlinkFileAsbolutePath, {
- dot: true,
- onlyFiles: false, // Required to find dangling symlinks
- });
-
- // Clean up any existing files in the storybook config folder so we have a clean slate
- for (const symlinkFile of symlinkFiles) {
- await fs.unlink(symlinkFile);
- log(`Cleaning up exising file ${symlinkFile}.`);
- }
+const managedConfigBanner = require('./managedConfigBanner');
- const previewFiles = await glob(previewFileAbsolutePath);
+// Since this config will be in the user's project, we can use ESM
+// Spread `storybookConfig` to prevent warning
+// https://github.com/storybookjs/storybook/issues/23675
+const mainConfigFileContents = `${managedConfigBanner}
+import storybookConfig from 'sku/config/storybook';
- if (previewFiles.length > 1) {
- console.error(
- 'Multiple storybook preview files found. Please only define a single preview file.',
- );
- console.error(previewFiles);
+export default { ...storybookConfig };
+`;
- return;
- }
+const storybookMainConfigPath = '.storybook/main.js';
+const storybookConfigDirectory = path.dirname(storybookMainConfigPath);
- const previewFile = previewFiles?.[0];
-
- if (previewFile) {
- const previewFileExtension = path.extname(previewFile);
- const symlinkFile = path.join(
+const setUpStorybookConfigDirectory = async () => {
+ await fs.mkdir(storybookConfigDirectory, { recursive: true });
+ log(
+ `Created '${path.resolve(
storybookConfigDirectory,
- `preview${previewFileExtension}`,
- );
-
- log(`Found preview file at ${previewFile}`);
- log(`Creating symlink from ${symlinkFile} to ${previewFile}`);
+ )}' directory if it didn't exist`,
+ );
- await fs.symlink(previewFile, symlinkFile);
- }
+ await fs.writeFile(storybookMainConfigPath, mainConfigFileContents);
+ log(
+ `Wrote storybook config file to '${path.resolve(storybookMainConfigPath)}'`,
+ );
};
-module.exports = { setUpStorybookPreviewFile };
+module.exports = { setUpStorybookConfigDirectory, storybookMainConfigPath };
diff --git a/packages/sku/scripts/build-storybook.js b/packages/sku/scripts/build-storybook.js
index 748e58223..c9f3d5c25 100644
--- a/packages/sku/scripts/build-storybook.js
+++ b/packages/sku/scripts/build-storybook.js
@@ -1,23 +1,20 @@
// First, ensure the build is running in production mode
process.env.NODE_ENV = 'production';
-const path = require('path');
const { rimraf } = require('rimraf');
const { argv } = require('../config/args');
const gracefulSpawn = require('../lib/gracefulSpawn');
const { storybookTarget } = require('../context');
const buildStorybookPath = require.resolve('@storybook/cli/bin/index');
-const configDir = path.resolve(__dirname, '../config/storybook/build');
const { runVocabCompile } = require('../lib/runVocab');
-const { setUpStorybookPreviewFile } = require('../lib/storybook');
+const { setUpStorybookConfigDirectory } = require('../lib/storybook');
(async () => {
await runVocabCompile();
await rimraf(storybookTarget);
- await setUpStorybookPreviewFile(configDir);
+ await setUpStorybookConfigDirectory();
argv.push('build');
- argv.push('--config-dir', configDir);
argv.push('--output-dir', storybookTarget);
argv.push('--quiet');
diff --git a/packages/sku/scripts/storybook.js b/packages/sku/scripts/storybook.js
index 9aff9076d..70080b70b 100644
--- a/packages/sku/scripts/storybook.js
+++ b/packages/sku/scripts/storybook.js
@@ -1,21 +1,18 @@
-const path = require('path');
const { argv } = require('../config/args');
const gracefulSpawn = require('../lib/gracefulSpawn');
const { storybookPort } = require('../context');
const startStorybookPath = require.resolve('@storybook/cli/bin/index');
-const configDir = path.resolve(__dirname, '../config/storybook/start');
const { watchVocabCompile } = require('../lib/runVocab');
-const { setUpStorybookPreviewFile } = require('../lib/storybook');
+const { setUpStorybookConfigDirectory } = require('../lib/storybook');
// Unshift args to allow pushing --ci as an arg during storybook-config tests
argv.unshift('--quiet');
-argv.unshift('--config-dir', configDir);
argv.unshift('--port', storybookPort);
argv.unshift('dev');
(async () => {
await watchVocabCompile();
- await setUpStorybookPreviewFile(configDir);
+ await setUpStorybookConfigDirectory();
const storybookProcess = gracefulSpawn(startStorybookPath, argv, {
stdio: 'inherit',
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 50df8bca5..3d7e573db 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1,9 +1,5 @@
lockfileVersion: '6.0'
-settings:
- autoInstallPeers: true
- excludeLinksFromLockfile: false
-
importers:
.:
@@ -950,10 +946,10 @@ importers:
version: 6.0.1
webpack:
specifier: ^5.52.0
- version: 5.88.0(webpack-cli@5.0.1)
+ version: 5.88.0(esbuild@0.17.16)(webpack-cli@5.0.1)
webpack-cli:
specifier: ^5.0.0
- version: 5.0.1(webpack-dev-server@4.11.1)(webpack@5.88.0)
+ version: 5.0.1(webpack-bundle-analyzer@4.8.0)(webpack-dev-server@4.11.1)(webpack@5.88.0)
webpack-dev-server:
specifier: 4.11.1
version: 4.11.1(debug@4.3.4)(webpack-cli@5.0.1)(webpack@5.88.0)
@@ -6083,7 +6079,7 @@ packages:
debug: 4.3.4(supports-color@8.1.1)
es-module-lexer: 0.9.3
virtual-resource-loader: 1.0.1
- webpack: 5.88.0(webpack-cli@5.0.1)
+ webpack: 5.88.0(esbuild@0.17.16)(webpack-cli@5.0.1)
transitivePeerDependencies:
- supports-color
dev: false
@@ -10028,7 +10024,7 @@ packages:
lodash: 4.17.21
pretty-error: 4.0.0
tapable: 2.2.1
- webpack: 5.88.0(webpack-cli@5.0.1)
+ webpack: 5.88.0(esbuild@0.17.16)(webpack-cli@5.0.1)
/htmlparser2@3.10.1:
resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==}
@@ -11803,7 +11799,7 @@ packages:
webpack: ^5.0.0
dependencies:
schema-utils: 4.0.0
- webpack: 5.88.0(webpack-cli@5.0.1)
+ webpack: 5.88.0(esbuild@0.17.16)(webpack-cli@5.0.1)
/minimalistic-assert@1.0.1:
resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==}
@@ -14508,29 +14504,6 @@ packages:
terser: 5.18.1
webpack: 5.88.0(esbuild@0.17.16)(webpack-cli@5.0.1)
- /terser-webpack-plugin@5.3.9(webpack@5.88.0):
- resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==}
- engines: {node: '>= 10.13.0'}
- peerDependencies:
- '@swc/core': '*'
- esbuild: '*'
- uglify-js: '*'
- webpack: ^5.1.0
- peerDependenciesMeta:
- '@swc/core':
- optional: true
- esbuild:
- optional: true
- uglify-js:
- optional: true
- dependencies:
- '@jridgewell/trace-mapping': 0.3.18
- jest-worker: 27.5.1
- schema-utils: 3.3.0
- serialize-javascript: 6.0.1
- terser: 5.18.1
- webpack: 5.88.0(webpack-cli@5.0.1)
-
/terser@5.18.1:
resolution: {integrity: sha512-j1n0Ao919h/Ai5r43VAnfV/7azUYW43GPxK7qSATzrsERfW7+y2QW9Cp9ufnRF5CQUWbnLSo7UJokSWCqg4tsQ==}
engines: {node: '>=10'}
@@ -15269,39 +15242,6 @@ packages:
webpack-dev-server: 4.11.1(debug@4.3.4)(webpack-cli@5.0.1)(webpack@5.88.0)
webpack-merge: 5.8.0
- /webpack-cli@5.0.1(webpack-dev-server@4.11.1)(webpack@5.88.0):
- resolution: {integrity: sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==}
- engines: {node: '>=14.15.0'}
- hasBin: true
- peerDependencies:
- '@webpack-cli/generators': '*'
- webpack: 5.x.x
- webpack-bundle-analyzer: '*'
- webpack-dev-server: '*'
- peerDependenciesMeta:
- '@webpack-cli/generators':
- optional: true
- webpack-bundle-analyzer:
- optional: true
- webpack-dev-server:
- optional: true
- dependencies:
- '@discoveryjs/json-ext': 0.5.7
- '@webpack-cli/configtest': 2.0.1(webpack-cli@5.0.1)(webpack@5.88.0)
- '@webpack-cli/info': 2.0.1(webpack-cli@5.0.1)(webpack@5.88.0)
- '@webpack-cli/serve': 2.0.1(webpack-cli@5.0.1)(webpack-dev-server@4.11.1)(webpack@5.88.0)
- colorette: 2.0.19
- commander: 9.5.0
- cross-spawn: 7.0.3
- envinfo: 7.8.1
- fastest-levenshtein: 1.0.16
- import-local: 3.1.0
- interpret: 3.1.1
- rechoir: 0.8.0
- webpack: 5.88.0(webpack-cli@5.0.1)
- webpack-dev-server: 4.11.1(debug@4.3.4)(webpack-cli@5.0.1)(webpack@5.88.0)
- webpack-merge: 5.8.0
-
/webpack-dev-middleware@5.3.3(webpack@5.88.0):
resolution: {integrity: sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==}
engines: {node: '>= 12.13.0'}
@@ -15435,46 +15375,6 @@ packages:
- esbuild
- uglify-js
- /webpack@5.88.0(webpack-cli@5.0.1):
- resolution: {integrity: sha512-O3jDhG5e44qIBSi/P6KpcCcH7HD+nYIHVBhdWFxcLOcIGN8zGo5nqF3BjyNCxIh4p1vFdNnreZv2h2KkoAw3lw==}
- engines: {node: '>=10.13.0'}
- hasBin: true
- peerDependencies:
- webpack-cli: '*'
- peerDependenciesMeta:
- webpack-cli:
- optional: true
- dependencies:
- '@types/eslint-scope': 3.7.4
- '@types/estree': 1.0.1
- '@webassemblyjs/ast': 1.11.6
- '@webassemblyjs/wasm-edit': 1.11.6
- '@webassemblyjs/wasm-parser': 1.11.6
- acorn: 8.9.0
- acorn-import-assertions: 1.9.0(acorn@8.9.0)
- browserslist: 4.21.9
- chrome-trace-event: 1.0.3
- enhanced-resolve: 5.15.0
- es-module-lexer: 1.3.0
- eslint-scope: 5.1.1
- events: 3.3.0
- glob-to-regexp: 0.4.1
- graceful-fs: 4.2.11
- json-parse-even-better-errors: 2.3.1
- loader-runner: 4.3.0
- mime-types: 2.1.35
- neo-async: 2.6.2
- schema-utils: 3.3.0
- tapable: 2.2.1
- terser-webpack-plugin: 5.3.9(webpack@5.88.0)
- watchpack: 2.4.0
- webpack-cli: 5.0.1(webpack-dev-server@4.11.1)(webpack@5.88.0)
- webpack-sources: 3.2.3
- transitivePeerDependencies:
- - '@swc/core'
- - esbuild
- - uglify-js
-
/websocket-driver@0.7.4:
resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==}
engines: {node: '>=0.8.0'}
@@ -15793,3 +15693,7 @@ packages:
/yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false