Svelte + Tailwind + Storybook 入门模板

2025-06-07

Svelte + Tailwind + Storybook 入门模板

这篇博客已经相当过时了,我在这里创建了一个更新版本。Svelte 生态系统已经非常成熟,我们确实不需要进行太多复杂的配置就可以开始使用,但这仍然不是一件容易的事。同样,这篇博客的内容已经过时了。请访问这里的更新版本

首先,这是Github 仓库的链接,赶紧开始你的项目吧,别再纠结配置了。相信我,这得花不少时间。

访问此网站查看结果:Svelte + TailwindCSS + Storybook

// Quickstart

npx degit jerriclynsjohn/svelte-storybook-tailwind my-svelte-project
cd my-svelte-project

yarn
yarn dev
yarn stories
Enter fullscreen mode Exit fullscreen mode

Svelte 和 TailwindCSS 是前端开发的绝佳组合,但有时设置起来似乎有点不直观,尤其是在尝试使用这个绝佳组合时。集成 Storybook(另一个用于 UI 组件开发和文档的优秀工具)时,却没有明确的地方介绍如何使用。这个 repo 就是为了解决这个问题而创建的!

您可以使用此模板轻松启动您的项目,而不必浪费时间弄清楚每个集成的配置。

您在此 repo 中获得了什么

Storybook UI

  1. 功能齐全的 Svelte + TailwindCSS 集成,并并行实现独立的 Storybook
  2. 包含 5 个必备插件的故事书
  3. Storybook 中充满了 Svelte + TailwindCSS 的基本示例

附加组件

  • 辅助功能插件

辅助功能插件

  • 辅助功能插件 - 色盲模拟

辅助功能插件 - 色盲模拟

  • 动作插件

动作插件

  • 笔记插件

笔记插件

  • 源插件

源插件

  • 视口插件

源插件

Svelte + TailwindCSS + Storybook

Storybook
是一个用于 独立开发 JavaScript UI 组件的开源工具

Svelte是一个组件框架,允许您编写高效的
命令式代码,通过精确更新 DOM 来保持性能。

TailwindCSS是一个高度可定制的低级 CSS 框架,它为
您提供了构建定制设计所需的所有构建块,而无需
您费力去覆盖任何令人讨厌的固有样式。

构建步骤

  1. 克隆此 repogit clone https://github.com/jerriclynsjohn/svelte-storybook-tailwind.git
  2. 进入目录cd svelte-storybook-tailwind
  3. 安装依赖项yarn
  4. 要开发您的 Svelte 应用程序:yarn dev
  5. 要开发独立于应用程序的 UI 组件:yarn stories

文档

  1. Svelte - API教程
  2. TailwindCSS -文档教程
  3. Storybook -文档教程(尚无 Svelte!)

自行构建的步骤和一些技巧 [警告:篇幅较长]

实例化 Svelte 应用

  • 使用以下方式启动模板文件npx degit sveltejs/template svelte-storybook-tailwind
  • 进入目录cd svelte-storybook-tailwind
  • 安装依赖项yarn
  • 尝试运行 svelte 应用yarn dev

将 Tailwind 添加到项目中

  • 安装依赖项:yarn add -D tailwindcss @fullhuman/postcss-purgecss autoprefixer postcss postcss-import svelte-preprocess rollup-plugin-postcss
  • 添加utils.csssrc添加这个:

/* Import Tailwind as Global Utils */
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
Enter fullscreen mode Exit fullscreen mode
  • 将其导入main.js import './utils.css'

  • 更改汇总配置,如下所示:

import svelte from 'rollup-plugin-svelte';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';
import postcss from 'rollup-plugin-postcss';
import autoPreprocess from 'svelte-preprocess';

const production = !process.env.ROLLUP_WATCH;

export default {
    input: 'src/main.js',
    output: {
        sourcemap: true,
        format: 'iife',
        name: 'app',
        file: 'public/bundle.js',
    },
    plugins: [
        svelte({
            preprocess: autoPreprocess({
                postcss: true,
            }),
            // enable run-time checks when not in production
            dev: !production,
            // we'll extract any component CSS out into
            // a separate file — better for performance
            css: css => {
                css.write('public/bundle.css');
            },
        }),
        postcss({
            extract: 'public/utils.css',
        }),

        // If you have external dependencies installed from
        // npm, you'll most likely need these plugins. In
        // some cases you'll need additional configuration —
        // consult the documentation for details:
        // https://github.com/rollup/rollup-plugin-commonjs
        resolve({
            browser: true,
            dedupe: importee => importee === 'svelte' || importee.startsWith('svelte/'),
        }),
        commonjs(),

        // Watch the `public` directory and refresh the
        // browser on changes when not in production
        !production && livereload('public'),

        // If we're building for production (npm run build
        // instead of npm run dev), minify
        production && terser(),
    ],
    watch: {
        clearScreen: false,
    },
};
Enter fullscreen mode Exit fullscreen mode
  • 使用以下命令添加 tailwind 配置npx tailwind init

  • 添加 PostCSS 配置./postcss.config.js如下:

const production = !process.env.ROLLUP_WATCH;
const purgecss = require('@fullhuman/postcss-purgecss');

module.exports = {
    plugins: [
        require('postcss-import')(),
        require('tailwindcss'),
        require('autoprefixer'),
        production &&
            purgecss({
                content: ['./**/*.html', './**/*.svelte'],
                defaultExtractor: content => {
                    const regExp = new RegExp(/[A-Za-z0-9-_:/]+/g);

                    const matchedTokens = [];

                    let match = regExp.exec(content);
                    // To make sure that you do not lose any tailwind classes used in class directive.
                    // https://github.com/tailwindcss/discuss/issues/254#issuecomment-517918397
                    while (match) {
                        if (match[0].startsWith('class:')) {
                            matchedTokens.push(match[0].substring(6));
                        } else {
                            matchedTokens.push(match[0]);
                        }

                        match = regExp.exec(content);
                    }

                    return matchedTokens;
                },
            }),
    ],
};
Enter fullscreen mode Exit fullscreen mode
  • global.css从文件夹中删除public,然后从中删除引用index.html

  • 使用一些 TailwindCSS 实用程序构建项目yarn dev

将 Storybook 添加到 Svelte 项目中

  • 添加 Storybook 依赖项yarn add -D @storybook/svelte
  • 添加 5 个常用的 Storybook插件

    • 来源yarn add -D @storybook/addon-storysource
    • 行动yarn add -D @storybook/addon-actions
    • 注意yarn add -D @storybook/addon-notes
    • 视口yarn add -D @storybook/addon-viewport
    • 可访问性yarn add @storybook/addon-a11y --dev
  • 在根目录创建一个.storybook/addons.js包含以下内容的插件文件,并继续

    在此文件中添加其他插件。

import '@storybook/addon-storysource/register';
import '@storybook/addon-actions/register';
import '@storybook/addon-notes/register';
import '@storybook/addon-viewport/register';
import '@storybook/addon-a11y/register';
Enter fullscreen mode Exit fullscreen mode
  • 在根目录创建一个配置文件.storybook/config.js,内容如下:
import { configure, addParameters, addDecorator } from '@storybook/svelte';
import { withA11y } from '@storybook/addon-a11y';

// automatically import all files ending in *.stories.js
const req = require.context('../storybook/stories', true, /\.stories\.js$/);
function loadStories() {
    req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);
addDecorator(withA11y);
addParameters({ viewport: { viewports: newViewports } });
Enter fullscreen mode Exit fullscreen mode
  • webpack.config.js在下面添加 tailwind 配置.storybook并适应 Source 插件:
const path = require('path');

module.exports = ({ config, mode }) => {
    config.module.rules.push(
        {
            test: /\.css$/,
            loaders: [
                {
                    loader: 'postcss-loader',
                    options: {
                        sourceMap: true,
                        config: {
                            path: './.storybook/',
                        },
                    },
                },
            ],

            include: path.resolve(__dirname, '../storybook/'),
        },
        //This is the new block for the addon
        {
            test: /\.stories\.js?$/,
            loaders: [require.resolve('@storybook/addon-storysource/loader')],
            include: [path.resolve(__dirname, '../storybook')],
            enforce: 'pre',
        },
    );

    return config;
};
Enter fullscreen mode Exit fullscreen mode
  • 创建postcss.config.js.storybook
var tailwindcss = require('tailwindcss');

module.exports = {
    plugins: [
        require('postcss-import')(),
        tailwindcss('./tailwind.config.js'),
        require('autoprefixer'),
    ],
};
Enter fullscreen mode Exit fullscreen mode
  • 确保你有 babel 和 svelte-loader 依赖项yarn add -D babel-loader @babel/core svelte-loader
  • 在你的package.json
{
    "scripts": {
        // Rest of the scripts
        "stories": "start-storybook",
        "build-stories": "build-storybook"
    }
}
Enter fullscreen mode Exit fullscreen mode
  • 添加一个 utils.css 文件storybook/css/并确保import 'utils.css'在您的stories.js文件中:
/* Import Tailwind as Global Utils */

@import 'tailwindcss/base';

@import 'tailwindcss/components';

@import 'tailwindcss/utilities';
Enter fullscreen mode Exit fullscreen mode
  • 编写你的 Svelte 组件,storybook\components没错,你可以使用你的常规.svelte文件。唯一的问题是,你目前还不能在故事中使用模板,目前还不支持,但你可以将其他组件组合在一起。对于入门包,我们只需创建一个可点击的按钮即可。
<script>
    import { createEventDispatcher } from 'svelte';
    export let text = '';
    const dispatch = createEventDispatcher();
    function onClick(event) {
      dispatch('click', event);
    }
</script>

<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
        on:click={onClick}>
  {text}
</button>
Enter fullscreen mode Exit fullscreen mode
  • 在其中编写你的故事storybook/stories,你可以用 命名任意数量的故事文件<anything>.stories.js。对于入门包,我们可以Button使用 中的自述文件注释创建 的故事<anything>.stories.md。注意:引用此处的 CSS 以确保 postcss 调用 tailwind:
import '../../css/utils.css';

import { storiesOf } from '@storybook/svelte';
import ButtonSimple from '../../components/buttons/button-simple.svelte';
import markdownNotes from './buttons.stories.md';

storiesOf('Buttons | Buttons', module)
    //Simple Button
    .add(
        'Simple',
        () => ({
            Component: ButtonSimple,
            props: { text: 'Button' },
            on: {
                click: action('I am logging in the actions tab too'),
            },
        }),
        { notes: { markdown: markdownNotes } },
    )
Enter fullscreen mode Exit fullscreen mode
  • 为组件编写自己的文档,其将<anything>.stories.md
# Buttons

_Examples of building buttons with Tailwind CSS._

---

Tailwind doesn't include pre-designed button styles out of the box, but they're easy to build using
existing utilities.

Here are a few examples to help you get an idea of how to build components like this using Tailwind.
Enter fullscreen mode Exit fullscreen mode
  • 运行你的故事板yarn stories,你会看到:

Storybook UI

您可以添加更多插件并试用它们。

就这样结束了!

文章来源:https://dev.to/jerric/svelte-tailwind-storybook-starter-template-2nih
PREV
DEV 注意事项:不要忘记清除缓存!
NEXT
我很幸运,你却不是。