玩转 Storybook: Day 29 Design System for Developers - Distribute

在整个组织中发布 Design System

从架构的角度来看,Design System 如同 lodash、moment 一样,可做为专案开发过程的 dependencies,我们利用它减少重复制作相同的程序码。纳入Design System的元件都会是经常被重复使用的元件。

本单元介绍了从打包UI元件、将其导入其他应用程序,另外,我们还找到一个Auto的工具,用以简化版本控制和发布。

Prepare Design System Package

一个组织会有很多个专案,也就表示会有成千上万个分布在不同专案里的UI元件,前面的单元的概念是将常用的元件extract到Design System中,这个单元的概念是将常用的元件import到不同的专案中。

可以使用NPM来处理将 Design System 的 Package 做发版。

对於新建立的Design System,最直接的方法是发布一个封装了以下内容的Package。

  • 通用的 UI 元件 (Common UI components)
  • 设计样式 (Design tokens)
  • 使用说明 (Documentation)

Export Design System

以下会介绍要导出 Design System Package 的 Step

Step 1 更新或新增 README.md

用来描述 Design System Package 要导入专案的使用说明

// README.md

# The Learn Storybook design system

The Learn Storybook design system is a subset of the full [Storybook design system](https://github.com/storybookjs/design-system/), created as a learning resource for those interested in learning how to write and publish a design system using best in practice techniques.

Learn more at [Learn Storybook](https://learnstorybook.com).

Step 2 建立要导出的 src/index.js 档案

index.js 是 Design System Package 的进入点,所以在这个档案,我们要export所有我们的 design tokens 及 UI元件


import * as styles from './shared/styles';
import * as global from './shared/global';
import * as animation from './shared/animation';
import * as icons from './shared/icons';

// export design tokens
export { styles, global, animation, icons };

// export common ui components
export * from './Avatar';
export * from './Badge';
export * from './Button';
export * from './Icon';
export * from './Link';

Step 3 安装建置导出用的开发套件 - @babel/cli 及 cross-env

$ yarn add --dev @babel/cli cross-env

Step 4 加上建置导出用指令

// package.json

{
  "scripts": {
    "build": "cross-env BABEL_ENV=production babel src -d dist"
  }
}

Step 5 建置要输出的目录 dist

$ npm run build

Step 6 加上 Pacakge 资讯

// dist/package.json

{
  "name": "lalalee-learnstorybook-design-system",
  "version": "1.0.0",
  "description": "Learn Storybook design system",
  "main": "dist/index.js",
  "repository": "https://github.com/lala-lee-jobs/learnstorybook-design-system",
  "author": "lalalee",
  "license": "MIT"
}

这样我们就准备好要发布的 Design System Package

Release management with Auto

发布 Release 到 npm 是一个工作流程,这个工作流程会发布版本,更新changelog,设定版号,建立repo tag连结至版号,为了要完成此工作流程,会使用Auto这个开源的工具。

安装 Auto:

yarn add --dev auto

Getting a GitHub and npm token

Auto会去协同使用Github及npm,所以需要取得这二个地方的Personal Access Token。

  • 在 npm 你可以使用下面的连结取得token
https://www.npmjs.com/settings/<your-username>/tokens

  • 在 github 你可以使用下面的连结取得token
https://github.com/settings/tokens

把 npm 和 github 的token 加到 .env

// dist/.env

GH_TOKEN=<value you just got from GitHub>
NPM_TOKEN=<value you just got from npm>

Create labels on GitHub

第一件事就是使用Auto在GitHub上建立一组label,将会使用这些label完成更新 package 的工作流程。

$ yarn auto create-labels

https://github.com/lala-lee-jobs/learnstorybook-design-system/labels

在每个未来要merge至主线的 Pull Request,都会至少伴随一个label包括:major,minor,patch,skip-release,prerelease,internal,documentation。

手动发布 Auto 的第一个版本

使用Auto,可以计动计算新的版号,但是第一个release还是要手动下指令

$ yarn auto changelog

它会自动的产生 CHANGELOG.md

# v0.1.0 (Tue Sep 03 2019)

- Created first version of the design system, with `Avatar`, `Badge`, `Button`, `Icon` and `Link` components.

#### Authors: 1
- Tom Coleman ([@tmeasday](https://github.com/tmeasday))

现在我们可以发布

npm version 0.1.0 -m "Bump version to: %s [skip ci]"
npm publish

并使用Auto在GitHub上也发布版本

git push --follow-tags origin master
yarn auto release

设置 Script 使用 Auto

// package.json

{
  "scripts": {
    "release": "auto shipit"
  }
}

现在,当我们运行时yarn release,我们将以自动化的方式完成上述所有步骤。

Publish releases automatically

把 npm tokens 储存到 GitHub secrets

使用GitHub Actions自动发布

每次Merge Pull Request时,我们都希望自动发布Design System。

在.github/workflows/下加上push.yml,并添加以下内容

# .github/workflows/push.yml

## name of our action
name: Release

# the event that will trigger the action
on:
  push:
    branches: [master]

# what the action will do
jobs:
  release:
    # the operating system it will run on
    runs-on: ubuntu-latest
    # this check needs to be in place to prevent a publish loop with auto and github actions
    if: "!contains(github.event.head_commit.message, 'ci skip') && !contains(github.event.head_commit.message, 'skip ci')"
    # the list of steps that the action will go through
    steps:
      - uses: actions/checkout@v2
      - name: Prepare repository
        run: git fetch --unshallow --tags
      - name: Use Node.js 12.x
        uses: actions/setup-node@v1
        with:
          node-version: 12.x
      - name: Cache node modules
        uses: actions/cache@v1
        with:
          path: node_modules
          key: yarn-deps-${{ hashFiles('yarn.lock') }}
          restore-keys: |
            yarn-deps-${{ hashFiles('yarn.lock') }}

      - name: Create Release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: |
          yarn install --frozen-lockfile
          yarn build
          yarn release

现在,每次将PR合并到master时,它都会自动发布新版本,并根据您添加的标签适当增加版本号。

在新的专案导入 Design System

Get the example app

在这个Demo,我们会运行二个Storybook,一个是For Example App,一个是Design System

执行以下的指令来复制及取得 Example App

# Clones the files locally
$ npx degit chromaui/learnstorybook-design-system-example-app example-app

$ cd example-app

# Install the dependencies
$ npm install

## Start Storybook
$ npm run storybook

这是 example-app 运行的 Storybook

Integrating the design system

我们 Design System Storybook 之前已经发行的 Chromatic上,我们可以把它做为参考纳入 Eample App 的 Storybook,更新example app 的.storybook/main.js如下

// .storybook/main.js

module.exports = {
  stories: [
    "../src/**/*.stories.mdx", 
    "../src/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  refs: {
    'design-system': {
      title: 'My design system',
      // The url provided by Chromatic when it was deployed
      url: 'https://your-published-url.chromatic.com',
    },
  },  
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/preset-create-react-app",
  ],
};

现在就可以在新的专案开发时期浏览Design System提供的共用元件和文件说明。在功能开发过程中展示Design System会让开发人员更加的采用现有元件,而不是浪费时间去发明自己的元件。

在专案中加入,之前发行到 npm 的 Design System Package

$ yarn add <your-username>-learnstorybook-design-system

修改 UserItem 的元件程序码,让它改成使用 Design System Package 的 Avatar

// src/components/UserItem.js

import { Avatar } from '<your-username>-learnstorybook-design-system';

保存後,该UserItem元件将在Storybook中更新以显示新的Avatar元件。

由於UserItem是UserList组件的一部分,因此UserList也能看到引用的Avatar。

已经顺利地将Design System导入到新专案中。每当在Design System中发布对Avatar元件的更新时,当您更新Package时,该更改也将反映在专案中。

Next

Design System 的工作流程始於在 Storybook 中开发UI元件,最後将其分发给客户端的APP。Design System 必须不断循环的开发,以满足不断变化的产品要求。在铁人赛的最後一篇文章,会再次统整Design System 的工作流程,让大家对於这样的循环印象更深刻。

Reference

Design System for Developers - Distribute


<<:  为你自己学 Laravel - Day 29 前端生态圈

>>:  动员大外宣: 让资安进步成为公司的光环(向外)

用 Queue 制作 Stack

记录学习内容。 以下内容和截图大多引用文章。 还不了解,内容可能有错误。 Implement Sta...

Day 3 | 物件控制与事件监听

绑定:将xml中的元件与Kotlin程序码做连结。 监听事件:开发者可以在程序码中拦截使用者的操作过...

RxJava operators && Java.Optional as a type class

本篇是用来补充 RxJava 的基础知识跟 functional programming 的应用,最...

自动化测试,让你上班拥有一杯咖啡的时间 | Day 16 - 如何选取下拉式选单的值

此系列文章会同步发文到个人部落格,有兴趣的读者可以前往观看喔。 在 E2E 测试中,不仅有选取元素...

Day22 : 【TypeScript 学起来】Generic Function 泛型函式

上一篇介绍了 Generic 泛型, 其实这篇差不多意思 XDD 主要针对 Generic Fun...