從架構的角度來看,Design System 如同 lodash、moment 一樣,可做為專案開發過程的 dependencies,我們利用它減少重複製作相同的程式碼。納入Design System的元件都會是經常被重複使用的元件。
本單元介紹了從打包UI元件、將其導入其他應用程序,另外,我們還找到一個Auto的工具,用以簡化版本控制和發布。
一個組織會有很多個專案,也就表示會有成千上萬個分佈在不同專案裡的UI元件,前面的單元的概念是將常用的元件extract到Design System中,這個單元的概念是將常用的元件import到不同的專案中。
可以使用NPM
來處理將 Design System 的 Package 做發版。
對於新建立的Design System,最直接的方法是發布一個封裝了以下內容的Package。
以下會介紹要導出 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 到 npm 是一個工作流程,這個工作流程會發佈版本,更新changelog,設定版號,建立repo tag連結至版號,為了要完成此工作流程,會使用Auto
這個開源的工具。
安裝 Auto:
yarn add --dev auto
Auto會去協同使用Github及npm,所以需要取得這二個地方的Personal Access Token。
https://www.npmjs.com/settings/<your-username>/tokens
https://github.com/settings/tokens
// dist/.env
GH_TOKEN=<value you just got from GitHub>
NPM_TOKEN=<value you just got from npm>
第一件事就是使用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,可以計動計算新的版號,但是第一個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
// package.json
{
"scripts": {
"release": "auto shipit"
}
}
現在,當我們運行時yarn release,我們將以自動化的方式完成上述所有步驟。
把 npm tokens 儲存到 GitHub secrets
每次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時,它都會自動發布新版本,並根據您添加的標籤適當增加版本號。
在這個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
我們 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時,該更改也將反映在專案中。
Design System 的工作流程始於在 Storybook 中開發UI元件,最後將其分發給客戶端的APP。Design System 必須不斷循環的開發,以滿足不斷變化的產品要求。在鐵人賽的最後一篇文章,會再次統整Design System 的工作流程,讓大家對於這樣的循環印象更深刻。
Design System for Developers - Distribute