A working example of Storybook, with Vite, Svelte Kit and Tailwind CSS.
I was struggling with getting this to work, so I thought I would share how I managed to get things to work in the end.
The code can be found at github.com/kematzy/storybook-svelte-kit-vite-app.
1. Initial SvelteKit installation
Follow the initial instructions on the Svelte Kit page.
npm init svelte@next your-storybook-vite-sveltekit-app
Choose the following setup options from those presented:
Question | Choice |
---|---|
Which Svelte app template? | Skeleton project |
Use TypeScript? | No |
Add ESLint for code linting? | Yes |
Add Prettier for code formatting? | Yes |
Further Reading:
Change into your created directory and run npm install
to install all packages:
cd your-storybook-vite-sveltekit-app
npm install
Optionally, create a Git repository and commit all the changes.
git init
git add -A
git commit -m "Initial commit"
Run some quick tests to ensure things are working.
npm run dev -- --open
2. Add TailwindCSS support
Install Tailwind CSS support based upon their general instructions.
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
Add additional PostCSS packages for better CSS formatting.
npm install -D postcss-import postcss-nesting
-
postcss-import
supports multiple CSS files -
postcss-nesting
supports nested CSS format
Add support for parallel CSS generation.
npm install -D postcss-cli concurrently cross-env
Create a postcss.config.cjs with the following contents:
module.exports = {
plugins: {
'postcss-import': {},
'postcss-nesting': {},
tailwindcss: {},
autoprefixer: {},
},
}
Add the Tailwind config file:
npx tailwindcss init tailwind.config.cjs
Then update tailwind.config.cjs with JIT and purge settings:
module.exports = {
// ...
mode: 'jit',
purge: ['./src/**/*.svelte'],
// ...
}
Create src/styles/tailwind.css with the following contents:
/* Injects Tailwind's base styles & any base styles registered by plugins. */
@tailwind base;
@layer base { /* custom CSS goes here */ }
/* Injects Tailwind's component classes & any component classes registered by plugins. */
@tailwind components;
@layer components { /* custom CSS goes here */ }
/* Injects Tailwind's utility classes & any utility classes registered by plugins. */
@tailwind utilities;
@layer utilities { /* custom CSS goes here */ }
/* Directive controlling where Tailwind injects responsive variations of utilities.
By default Tailwind normally append these at the end of your stylesheet. */
@tailwind screens;
Then update the script section in package.json as follows:
{
"scripts": {
"dev:only": "svelte-kit dev",
"build:only": "svelte-kit build",
"preview": "svelte-kit preview",
"tailwind:watch": "cross-env TAILWIND_MODE=watch cross-env NODE_ENV=development postcss src/styles/tailwind.css -o static/app.css -w",
"tailwind:build": "cross-env TAILWIND_MODE=build cross-env NODE_ENV=production postcss src/styles/tailwind.css -o static/app.css",
"dev": "concurrently \"npm run dev:only\" \"npm run tailwind:watch\"",
"build": "npm run tailwind:build && npm run build:only",
// other defined scripts
},
}
Update the src/routes/index.svelte with Tailwind classes and import the src/styles/tailwind.css file for Vite hot reloading.
<script>
import "../styles/tailwind.css";
</script>
<div class="flex flex-col justify-center align-middle p-4 mb-12">
<h1 class="text-4xl text-center text-purple-700 font-light">Welcome to SvelteKit</h1>
<p class="text-center mb-4 mt-2">
Visit
<a
class="text-purple-400 hover:text-pink-700 hover:underline"
href="https://kit.svelte.dev"
>
kit.svelte.dev
</a>
to read the documentation.
</p>
</div>
3. Add StyleLint support
Install stylelint
related packages to silence any errors and/or warnings in your code editor.
npm install -D stylelint stylelint-config-standard stylelint-config-recommended
Create a stylelintrc.json file with the following contents:
{
"extends": [
"stylelint-config-recommended"
],
"processors": [],
"rules": {
"at-rule-no-unknown": [
true,
{
"ignoreAtRules": [
"tailwind",
"apply",
"variants",
"responsive",
"screen",
"function",
"each",
"if",
"else",
"return",
"layer"
]
}
],
"declaration-block-trailing-semicolon": null,
"no-descending-specificity": [
true,
{
"ignore": [
"selectors-within-list"
]
}
],
"no-invalid-double-slash-comments": true,
"block-no-empty": null
}
}
Optional: If you are using VS Code, then add a .vscode/settings.json
file with the following settings:
{
"css.validate": false,
"less.validate": false,
"scss.validate": false,
"postcss.validate": false,
"files.associations": {
"*.css": "postcss"
},
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
"source.fixAll.html": true
},
"stylelint.enable": true,
"stylelint.validate": [
"css",
"postcss"
],
"typescript.disableAutomaticTypeAcquisition": true,
"javascript.format.enable": false
}
Run some quick tests to ensure the Tailwind implementation is working.
npm run dev -- --open
If you created a Git repository already, then this is a great time to commit all the changes.
git add -A && git commit -m "Added Tailwind, PostCSS & Stylelint support"
4. Install and Setup Storybook
So far things have been fairly straightforward and hopefully without any errors.
Follow the instructions in the Storybook's Svelte Getting Started and run:
npx sb init
And you will see output similar to this:
npx sb init
sb init - the simplest way to add a Storybook to your project.
✓ Detecting project type.
info Configuring preprocessor from 'svelte.config.js'
added 1357 packages, and audited 2102 packages in 33s
✓ Preparing to install dependencies.
up to date, audited 2102 packages in 2s
✓ To run your Storybook, type:
npm run storybook
For more information visit: https://storybook.js.org
Try to start Storybook in development mode:
npm run storybook
At this point you will very likely hit a number of errors along these lines:
npm run storybook
> ~TODO~@0.0.1 storybook
> start-storybook -p 6006
info @storybook/svelte v6.3.6
info
ERR! Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: [$HOME]/DEV/your-storybook-vite-sveltekit-app/.storybook/main.js
ERR! require() of ES modules is not supported.
ERR! require() of [$HOME]/DEV/your-storybook-vite-sveltekit-app/.storybook/main.js from [$HOME]/DEV/your-storybook-vite-sveltekit-app/node_modules/@storybook/core-common/dist/cjs/utils/interpret-require.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
ERR! Instead rename main.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from [$HOME]/DEV/your-storybook-vite-sveltekit-app/package.json.
ERR!
ERR! at Object.Module._extensions..js (internal/modules/cjs/loader.js:1080:13)
ERR! at Module.load (internal/modules/cjs/loader.js:928:32)
ERR! at Function.Module._load (internal/modules/cjs/loader.js:769:14)
ERR! at Module.require (internal/modules/cjs/loader.js:952:19)
ERR! at require (internal/modules/cjs/helpers.js:88:18)
ERR! at interopRequireDefault ([$HOME]/DEV/your-storybook-vite-sveltekit-app/node_modules/@storybook/core-common/dist/cjs/utils/interpret-require.js:64:16)
ERR! at serverRequire ([$HOME]/DEV/your-storybook-vite-sveltekit-app/node_modules/@storybook/core-common/dist/cjs/utils/interpret-require.js:101:10)
ERR! at getPreviewBuilder ([$HOME]/DEV/your-storybook-vite-sveltekit-app/node_modules/@storybook/core-server/dist/cjs/utils/get-preview-builder.js:25:55)
ERR! at buildDevStandalone ([$HOME]/DEV/your-storybook-vite-sveltekit-app/node_modules/@storybook/core-server/dist/cjs/build-dev.js:99:71)
ERR! at async buildDev ([$HOME]/DEV/your-storybook-vite-sveltekit-app/node_modules/@storybook/core-server/dist/cjs/build-dev.js:154:5)
ERR! Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: [$HOME]/DEV/your-storybook-vite-sveltekit-app/.storybook/main.js
ERR! require() of ES modules is not supported.
ERR! require() of [$HOME]/DEV/your-storybook-vite-sveltekit-app/.storybook/main.js from [$HOME]/DEV/your-storybook-vite-sveltekit-app/node_modules/@storybook/core-common/dist/cjs/utils/interpret-require.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
ERR! Instead rename main.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from [$HOME]/DEV/your-storybook-vite-sveltekit-app/package.json.
ERR!
ERR! at Object.Module._extensions..js (internal/modules/cjs/loader.js:1080:13)
ERR! at Module.load (internal/modules/cjs/loader.js:928:32)
ERR! at Function.Module._load (internal/modules/cjs/loader.js:769:14)
ERR! at Module.require (internal/modules/cjs/loader.js:952:19)
ERR! at require (internal/modules/cjs/helpers.js:88:18)
ERR! at interopRequireDefault ([$HOME]/DEV/your-storybook-vite-sveltekit-app/node_modules/@storybook/core-common/dist/cjs/utils/interpret-require.js:64:16)
ERR! at serverRequire ([$HOME]/DEV/your-storybook-vite-sveltekit-app/node_modules/@storybook/core-common/dist/cjs/utils/interpret-require.js:101:10)
ERR! at getPreviewBuilder ([$HOME]/DEV/your-storybook-vite-sveltekit-app/node_modules/@storybook/core-server/dist/cjs/utils/get-preview-builder.js:25:55)
ERR! at buildDevStandalone ([$HOME]/DEV/your-storybook-vite-sveltekit-app/node_modules/@storybook/core-server/dist/cjs/build-dev.js:99:71)
ERR! at async buildDev ([$HOME]/DEV/your-storybook-vite-sveltekit-app/node_modules/@storybook/core-server/dist/cjs/build-dev.js:154:5) {
ERR! code: 'ERR_REQUIRE_ESM'
ERR! }
WARN Broken build, fix the error above.
WARN You may need to refresh the browser.
If you created a Git repository already, then this is another great time to commit all the changes added before we change them.
git add -A
git commit -m "Added Storybook support (default with errors)"
To fix these errors we need to update the installed @storybook
packages to version ^6.4.0-alpha.22 or later.
I recommend removing the existing node_modules
folder and package-lock.json
from your project folder.
rm -rf node_modules
rm package-lock.json
And then update the following packages in the package.json
file to the latest version.
{
// snip
"devDependencies": {
"@storybook/addon-actions": "^6.4.0-alpha.22",
"@storybook/addon-essentials": "^6.4.0-alpha.22",
"@storybook/addon-links": "^6.4.0-alpha.22",
// snip
},
// snip
}
NOTE!
If you try to update the
"@storybook/svelte
package to^6.4.0-alpha.22
you will run into installation errors
so we leave it at the default for now.
Re-install all the npm packages again.
npm install
The we need to install @storybook/addon-docs package that is missing:
npm install -D @storybook/addon-docs@6.4.0-alpha.22
While we are installing packages, we also need to install the storybook-builder-vite package to make the Vite actually stuff work:
npm install -D storybook-builder-vite
Then we need to rename svelte.config.js to svelte.config.cjs...
mv svelte.config.js svelte.config.cjs
and convert the format as follows:
/** @type {import('@sveltejs/kit').Config} */
module.exports = {
config: {
kit: {
// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte',
},
},
}
As well as rename .storybook/main.js to .storybook/main.cjs...
mv .storybook/main.js .storybook/main.cjs
and convert the format as follows:
module.exports = {
core: {
builder: "storybook-builder-vite"
},
stories: [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx|svelte)"
],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-svelte-csf"
],
svelteOptions: {
preprocess: require("../svelte.config.cjs").preprocess
}
}
NOTE!
The added support for Vite through the following added code snippet:
core: {
builder: "storybook-builder-vite"
}
And then, finally, we need to just rename .storybook/preview.js to .storybook/preview.cjs and not change the contents:
mv .storybook/preview.js .storybook/preview.cjs
If you created a Git repository already, then this is another great point in time to commit all the changes.
git add -A && git commit -m "Fixed Storybook errors"
5. Start Storybook again
If you have followed the above instructions everything should hopefully work when you start Storybook again:
npm run storybook
Found something wrong?
Open a PR if anything is wrong or things can be done in a better and faster way.
Top comments (6)
It seems this is now unnecessary, and all you need to do is the following:
.storybook/pakckage.json
containing:.storybook/main.js
from"preprocess": require("../svelte.config.js").preprocess
to:
"preprocess": import("../svelte.config.js").preprocess
source: github.com/storybookjs/storybook/i...
this worked for me. thanks for the comment!
you do have a typo in
./storybook/package.json
Thanks a lot for sharing this info!
Does anyone know how to configure the storybook main.cjs file in order to make an alias work?
This is how I've set up an alias in vitejs
vite.config.cjs
ah, found it:
This is cool, by the edge of frontend creation technology
How to get the default values from component?