本文将会介绍一个开源库storybook
在用Javascript 或者 Typescript 开发web组件库(library)的过程中,如果想写一个使用这个库的示例(demo)。这个demo的代码结构用什么方式来进行组织呢。我看了很多知名开源项目的代码,不同的项目对于这块代码的组织,我总结了以下,大致上有以下几种:
demo 代码放在工程中的一个单独的文件夹中,demo代码是直接放在html 中,在demo 的html 中直接引用自身库打包发布后的代码。
比方说facebook 开源的https://github.com/facebook/draft-js
这个项目的example代码中其中的一个demo叫做https://github.com/facebook/draft-js/blob/master/examples/draft-0-10-0/link/link.html
Draft • Link Editor
demo是一个使用packages.json来组织的项目
这种情况有两种做法:
demo 代码也放在库的同一个仓库中
这种情况又有好几种组织方式,下面列举两种常见的方案:
- demo代码用一个新的packages.json来组织
例如draft.js下的这个示例https://github.com/facebook/draft-js/blob/master/examples/draft-0-10-0,这是一个用packages.json来组织的demo。 packages.json里面的内容如下:
{
"name": "playground",
"version": "0.1.0",
"private": true,
"dependencies": {
"codemirror": "^5.32.0",
"draft-convert": "^2.0.1",
"draft-js": "file:../../..",
"immutable": "^3.8.2",
"react": "^16.2.0",
"react-codemirror2": "^3.0.7",
"react-dom": "^16.2.0",
"react-json-tree": "^0.11.0",
"react-panelgroup": "^1.0.5",
"react-scripts": "^1.1.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
这里demo对draft.js的依赖使用了这样的写法
"draft-js": "file:../../..",
表示直接通过文件系统的相对路径进行查找,相比较与写版本号,这种写法的好处是库的代码发生了更新之后,只需要重新打包生成,demo代码中就可以看到库发生的变化,而不需要每次都将库推送到npm 仓库里面去。当然也可以通过yarn link 和yarn unlink来实现。
- demo代码用webpack-dev-server来进行启动
这样的话只要在库的工程目录下新建一个用于启动webpack-dev-server的webpack 配置文件, 然后使用webpack-dev-server 来启动示例。这是一种非常常见的做法。
例如在开源项目slate https://github.com/ianstormtaylor/slate
中启动示例的方法
"server": "webpack-dev-server --config ./support/webpack/config.js",
demo 代码和库代码在不同的仓库中
这也是一种常见的做法,将库打包生成的代码发布到npm, demo代码依赖库代码。通过版本号,或者yarn link。
正题
上面说了这么多,然而最深得我心的还是使用storybook 这个库来启动示例。
storybook 对常见的前端开发框架都做了支持。具体怎么在项目中使用可以查看文档https://storybook.js.org/docs/basics/introduction/
使用步骤
对于我最熟悉的react框架,使用storybook的步骤大致如下:
- 添加依赖
npm install @storybook/react --save-dev
or
yarn add @storybook/react --dev
确保react, react-dom, @babel/core, babel-loader 这些依赖也添加到了项目中,如果没有,也请添加。
2.添加npm script
{
"scripts": {
"storybook": "start-storybook -p 6006"
}
}
-p 指定端口号
- 创建配置文件
创建.storybook/config.js 作为storybook的基础配置
import { configure } from '@storybook/react';
function loadStories() {
require('../stories/index.js');
// You can require as many stories as you need.
}
configure(loadStories, module);
- 编写示例
举个栗子:
../stories/index.js 是示例文件的路径
比方说在我的项目中创建了很多个demo,
import * as React from "react";
import { storiesOf } from "@storybook/react";
import { action } from "@storybook/addon-actions";
import { linkTo } from "@storybook/addon-links";
import { Button, Welcome } from "@storybook/react/demo";
import SimpleDemo from "./demo-blink-mind-react/SimpleDemo";
import AutoGenerateDepthForTest from "./demo-blink-mind-react/AutoGenerateDepthForTest";
import DemoScrollApi1 from "./demo-scroll-api/Demo1";
import DemoScrollApi2 from "./demo-scroll-api/Demo2";
import DemoScrollApi3 from "./demo-scroll-api/Demo3";
import DragDropDemo1 from "./demo-drag-drop/Demo1";
import DragDropDemo2 from "./demo-drag-drop/Demo2";
import DragDropDemo3 from "./demo-drag-drop/Demo3";
import DragDropDemo4 from "./demo-drag-drop/Demo4";
import DragDropDemo5 from "./demo-drag-drop/Demo5";
import DragDropDemo6 from "./demo-drag-drop/Demo6";
import DragDropDemo7 from "./demo-drag-drop/Demo7";
import DragDropDemo8 from "./demo-drag-drop/Demo8";
storiesOf("Welcome", module).add("to Storybook", () => (
));
storiesOf("blink-mind-react-demo", module)
.add("SimpleDemo", () => )
.add("AutoGenerateDepthForTest", () => );
storiesOf("drag-scroll-demo", module)
.add("demo1", () => )
.add("demo2", () => )
.add("demo3", () => );
storiesOf("drag-drop", module)
.add("demo1", () => )
.add("demo2", () => )
.add("demo3", () => )
.add("demo4", () => )
.add("demo5", () => )
.add("demo6", () => )
.add("demo7", () => )
.add("demo8", () => );
可以用这样的代码将demo进行分组
storiesOf("blink-mind-react-demo", module)
.add("SimpleDemo", () => )
.add("AutoGenerateDepthForTest", () => );
- 启动storybook
npm run storybook
打开浏览器的localhost:6006可以看到storybook的主界面。非常的方便。省去了很多自己去搭积木的时间。
好的,关于storybook 怎么使用就介绍完了。
storybook 高级配置
storybook 如何支持typescript , 各种css 预处理器呢?在storybook中也可以使用webpack的各种loader。只需要在.storybook目录下创建一个webpack.config.js,
在里面写webpack 的各种配置,支持typescript, css预处理器,以及其他loader和plugin支持的功能。
具体怎么配置,可以参考:
https://github.com/awehook/blink-mind-react/blob/master/.storybook/webpack.config.js