使用storybook6和webpack5搭建react组件库

/ 前端 / 没有评论 / 1467浏览

Storybook 是一个开源工具,用于独立构建 UI 组件和页面。它简化了 UI 开发、测试和文档。

下面我们就一步一步的使用storybook6搭建一个react组件库吧。

storybook的官方文档详见:https://storybook.js.org/

一、初始化

  1. 安装storybook
npx sb init

选择类型为webpack-react

alt

alt

alt

2、安装相关依赖

npm i react react-dom --save

alt

3、检查安装情况

npm run storybook

执行以上命令,显示安装成功 alt

在浏览器中打开 alt

二、webpack打包配置优化

修改.storybook>main.js 支持sass\css module

const path = require('path');

module.exports = {
  "stories": [
    "../stories/**/*.stories.mdx",
    "../stories/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-actions",
    "@storybook/addon-knobs"
  ],
  core: {
    builder: 'webpack5',
  },
  webpackFinal: async (config, { configType }) => {
    config.module.rules.push({
      test: /\.scss$/,
      use: [
        {
          loader: "style-loader",
        },
        {
          loader: "css-loader",
          options: {
            importLoaders: 2,
            modules: {
              auto: /\.module\.\w+$/i,
              localIdentName: "[local]--[hash:base64:5]",
              exportLocalsConvention: "camelCase",
            },
          },
        },
        {
          loader: "postcss-loader",
          options: {
            postcssOptions: {
              plugins: [require("autoprefixer"), require("cssnano")],
            },
          },
        },
        {
          loader: "sass-loader", // compiles Sass to CSS
        },
      ],
      include: path.resolve(__dirname, '../'),
    });
    return config;
  }
}

然后就可以编写自己的组件啦。

三、在src目录下编写components

alt

四、在stories目录下编写storybook的demo展示代码

alt

// Button.stories.js 
import React from 'react';

import { Button } from '../src/Button';

export default {
  title: 'Example/Button',
  component: Button,
  argTypes: {
    backgroundColor: { control: 'color' },
  },
};

const Template = (args) => <Button {...args} />;

export const Primary = Template.bind({});
Primary.args = {
  primary: true,
  label: 'Button',
};

export const Secondary = Template.bind({});
Secondary.args = {
  label: 'Button',
};

export const Large = Template.bind({});
Large.args = {
  size: 'large',
  label: 'Button',
};

export const Small = Template.bind({});
Small.args = {
  size: 'small',
  label: 'Button',
};

更多的写法请参照官方文档。

五、使用webpack打包

在跟目录下增加webpack的配置文件,将组件库单独打包为umd格式,然后可以执行npm publish发布自己的npm包。

具体配置如下:


const path = require('path');
const webpack = require('webpack');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
  mode: 'production',
  entry: {
    index: './src/index.js',
    timeSelect: './src/widgets/TimeSelect/index.js'
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, "lib"),
    publicPath: "/assets/",
    libraryTarget: 'umd'
  },
  externals: {
    react: {
      commonjs: 'react',
      commonjs2: 'react',
      amd: 'react',
      root: 'React',
    },
    'react-dom': {
      commonjs: 'react-dom',
      commonjs2: 'react-dom',
      amd: 'react-dom',
      root: 'ReactDOM',
    },
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx|ts|tsx)$/,
        include: [
          path.resolve(__dirname, "src")
        ],
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env', '@babel/preset-react'],
          plugins: ['@babel/plugin-transform-runtime']
        },
      },
      { 
        test: /\.(css|scss)$/, 
        use: [
          'style-loader',
          {
            loader: 'css-loader', 
            options: {
              modules: {
                auto: /\.module\.\w+$/i,
                localIdentName: "[local]--[hash:base64:5]",
                exportLocalsConvention: "camelCase",
              },
            }
          },
          'sass-loader'
        ],
      }
    ],
  },
  plugins: [
    // 清除打包文件夹
    new CleanWebpackPlugin(),
    new webpack.ProgressPlugin(),
  ],
};