A working example of Storybook, with Vite, Svelte Kit and Tailwind CSS.
git clone https://github.com/kematzy/storybook-svelte-kit-vite-app your-app-name
cd your-app-name
npm install
npm run storybook
A step-by-step guide of how I made this work.
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
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 filespostcss-nesting
supports nested CSS formatAdd 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>
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"
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
> [email protected] 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 make the necessary changes.
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/[email protected]
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 = {
// NOTE! added support for Vite builder
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"
If you have followed the above instructions everything should work when you start Storybook again:
npm run storybook
Open a PR if anything is wrong or things can be done in a better and faster way.
Once you've created a project and installed dependencies with npm install
(or pnpm install
or yarn
), start a development server:
npm run dev
# or start the server and open the app in a new browser tab
npm run dev -- --open
Before creating a production version of your app, install an adapter for your target environment. Then:
npm run build
You can preview the built app with
npm run preview
, regardless of whether you installed an adapter. This should not be used to serve your app in production.