Skip to content

A working example of Storybook, with Vite, Svelte Kit and Tailwind CSS

Notifications You must be signed in to change notification settings

kematzy/storybook-svelte-kit-vite-app

Repository files navigation

Storybook with a Vite, Svelte & TailwindCSS setup

A working example of Storybook, with Vite, Svelte Kit and Tailwind CSS.

Installation

git clone https://github.com/kematzy/storybook-svelte-kit-vite-app your-app-name

cd your-app-name

npm install

npm run storybook

Details of Code setup

A step-by-step guide of how I made this work.


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

Svelte Kit Base


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

Svelte Kit with Tailwind




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 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/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 = {
  // 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"



5. Start Storybook again

If you have followed the above instructions everything should work when you start Storybook again:

npm run storybook

Storybook, Svelte Kit, Vite & Tailwind


Found something wrong?

Open a PR if anything is wrong or things can be done in a better and faster way.





SOURCES OF INFORMATION

Developing

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

Building

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.

About

A working example of Storybook, with Vite, Svelte Kit and Tailwind CSS

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published