iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 29
1
Modern Web

玩轉 Storybook系列 第 29

玩轉 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


上一篇
玩轉 Storybook: Day 28 Design System for Developers - Document
下一篇
玩轉 Storybook: Day 30 總結 & 學習資源
系列文
玩轉 Storybook30

尚未有邦友留言

立即登入留言