# ccharts-test-buttton

> # 前言 最近菜鸟整个前端在推物料中心，发现上面的组件全部是StoryBook + react jsx 的写法， 想着推下 TS 的组件写法， 就整理了这篇 组件开发文章 StoryBook + Typescript + Tslint(tslint-config-ali) 。

Latest version **0.0.4** (published 2019-08-11) · MIT license · 0 weekly downloads

## Install

```sh
npm install ccharts-test-buttton
pnpm add ccharts-test-buttton
yarn add ccharts-test-buttton
bun add ccharts-test-buttton
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.4 |
| Published | 2019-08-11 |
| First published | 2019-08-11 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 13.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | test_zy |

## Links

- npm: https://www.npmjs.com/package/ccharts-test-buttton
- npm.io page: https://npm.io/package/ccharts-test-buttton

## Recent versions

- 0.0.4 (latest) — 2019-08-11
- 0.0.3 — 2019-08-11
- 0.0.2 — 2019-08-11
- 0.0.1 — 2019-08-11

## README

# 组件(库)  之  ButtonDemo

# 前言
  最近菜鸟整个前端在推物料中心，发现上面的组件全部是StoryBook + react jsx 的写法， 想着推下 TS 的组件写法， 就整理了这篇 组件开发文章 StoryBook + Typescript + Tslint(tslint-config-ali) 。

> 图说

![003.png](https://intranetproxy.alipay.com/skylark/lark/0/2019/png/5014/1550646503785-9cbfa5a8-76f2-43c4-8ca3-654fa0da66c2.png#align=left&display=inline&height=528&linkTarget=_blank&name=003.png&originHeight=1240&originWidth=1753&size=506470&width=747)



# 简介

## StoryBook

[StoryBook](https://github.com/storybooks/storybook) : 在你的应用程序之外运行。这允许您单独开发UI组件，这可以提高组件重用，可测试性和开发速度。您可以快速构建，而无需担心特定于应用程序的依赖项。

## TS
[TypeScript](https://www.tslang.cn/index.html)： 老生常谈， js 超级， 拥有可选的强类型定义， 类型可以让你方便快捷的进行类型检查、定义软件组件之间的接口和洞察现有JavaScript库的属性和方法， 在集团不包含蚂蚁金服的已有 990 个 TS 库； 


## TSLint (tslint-config-ali) 
[TSLint](https://palantir.github.io/tslint/):  是一种可扩展的静态分析工具，可检查TypeScript代码的可读性，可维护性和功能性错误。它在现代编辑器和构建系统中得到广泛支持，可以使用您自己的lint规则，配置和格式化程序进行自定义。

[tslint-config-ali](https://npm.alibaba-inc.com/package/@ali/tslint-config-ali)： 是集团 TS 规约配套 TSLint 规则和扩展包, 已经融入到[喜码](https://xima.alibaba-inc.com/guides#/guide/10/cover)中，会作为检测、修复工具辅助集团内部的 TS 开发。

# 方法步骤

### 一、初始化Story 

#### 1. 初始化项目 test-comp

```bash
mkdir test-comp
cd test-comp
yarn init -y
yarn add -D @storybook/react @storybook/addon-info @storybook/addon-knobs storybook-addon-jsx @types/react babel-core typescript awesome-typescript-loader react-docgen-typescript-webpack-plugin jest "@types/jest" ts-jest 
yarn add react react-dom
mkdir .storybook src
touch .storybook/config.js .storybook/addons.js .storybook/welcomeStory.js utils.js
```

#### 2. 在 package.json 中增加 启动 story 脚本

```json
{
  "scripts": {
    "storybook": "start-storybook -p 6001 -c .storybook"
  }
}
```


#### 3. 配置 storybook/config.js 

```javascript
import { configure } from '@storybook/react';
import { setAddon, addDecorator } from '@storybook/react';
import JSXAddon from 'storybook-addon-jsx';
import { withKnobs, select } from '@storybook/addon-knobs/react';
addDecorator(withKnobs);
setAddon(JSXAddon);

// automatically import all files ending in *.stories.js
const req = require.context('../src', true, /.stories.js$/);
function loadStories() {
  require('./welcomeStory');
  req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);
```

#### 4. 配置 .storybook/addons.js
> [addons](https://storybook.js.org/addons/introduction/) 说明


```javascript
import '@storybook/addon-knobs/register';
import 'storybook-addon-jsx/register';
```

#### 5. 写 Style 工具类  utils.js

```javascript
import { withInfo } from '@storybook/addon-info';
const wInfoStyle = {
  header: {
    h1: {
      marginRight: '20px',
      fontSize: '25px',
      display: 'inline'
    },
    body: {
      paddingTop: 0,
      paddingBottom: 0
    },
    h2: {
      display: 'inline',
      color: '#999'
    }
  },
  infoBody: {
    backgroundColor: '#eee',
    padding: '0px 5px',
    lineHeight: '2'
  }
};
export const wInfo = text =>
  withInfo({ inline: true, source: false, styles: wInfoStyle, text: text });
```


#### 6. 写Story 欢迎页 .storybook·/welcomeStory.js
```javascript
import React from 'react';
import { storiesOf } from '@storybook/react';
import { wInfo } from '../utils';
storiesOf('Welcome', module).addWithJSX(
  'to your new Storybook🎊',
  wInfo(`
    ### Notes
    Hello world!:
    ### Usage
    ~~~js
    <div>This is an example component</div>
    ~~~
    ### To use this Storybook
    Explore the panels on the left.
  `)(() => <div>This is an example component</div>)
);
```

#### 7. 试运行 Story : npm run storybook
![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2019/png/5014/1550585827711-73184115-b58c-4b80-b971-25495fd8e4b9.png#align=left&display=inline&height=335&linkTarget=_blank&name=image.png&originHeight=502&originWidth=732&size=42109&width=488)

### 二、引入TypeScript 

#### 1. 创建 ts 组件空文件
```bash
mkdir src/Button
touch src/Button/Button.tsx src/Button/Button.css src/Button/Button.stories.js
```

#### 2. 写 ts 组件内容： src/Button/Button.tsx
```typescript
import * as React from 'react';
import './Button.scss';
export interface Props {
  /** this dictates what the button will say  */
  label: string;
  /** this dictates what the button will do  */
  onClick: () => void;
  /**
   * Disables onclick
   *
   * @default false
   **/
  disabled?: boolean;
  testA?: boolean;
}
const noop = () => {}; // tslint:disable-line
const Button = (props: Props) => {
  const { label, onClick, disabled = false } = props;
  const disabledclass = disabled ? 'Button_disabled' : '';
  return (
    <div
      className={`Button ${disabledclass}`}
      onClick={!disabled ? onClick : noop}
    >
      <span>{label}</span>
    </div>
  );
};
export { Button };


```
### 
#### 3. 写 scss 组件样式：  src/Button/Button.scss
```css
.Button span {
  margin: auto;
  font-size: 16px;
  font-weight: bold;
  text-align: center;
  color: #fff;
  text-transform: uppercase;
}
.Button {
  padding: 0px 20px;
  height: 49px;
  border-radius: 2px;
  border: 2px solid var(--ui-bkgd, #3d5567);
  display: inline-flex;
  background-color: var(--ui-bkgd, #3d5567);
}
.Button:hover:not(.Button_disabled) {
  cursor: pointer;
}
.Button_disabled {
  --ui-bkgd: rgba(61, 85, 103, 0.3);
}
```

#### 4. 组件接入 story 文档： src/Button/Button.stories.js
```javascript
import React from 'react';
import { storiesOf } from '@storybook/react';
import { Button } from './Button';
import { wInfo } from '../../utils';
import { text, boolean } from '@storybook/addon-knobs/react';
storiesOf('Components/Button', module).addWithJSX(
  'basic Button',
  wInfo(`
  ### Notes
  This is a button
  ### Usage
  ~~~js
  <Button
    label={'Enroll'}
    disabled={false}
    onClick={() => alert('hello there')}
  />
  ~~~`
)(() => (
    <Button
      label={text('label', 'Enroll')}
      disabled={boolean('disabled', false)}
      onClick={() => alert('hello there')}
    />
  ))
);
```
### 
#### 5. 让strorybook 接入typescript， 创建相关配置文件
```bash
touch .storybook/webpack.config.js tsconfig.json
```


#### 6. 配置 storybook 的 webpack 配置文件:   storybook/webpack.config.js

```javascript
const path = require('path');
const TSDocgenPlugin = require('react-docgen-typescript-webpack-plugin');
module.exports = (baseConfig, env, defaultConfig) => {
  const rules = defaultConfig.module.rules;
  rules.push({
    test: /\.tsx?$/,
    use: [
      {
        loader: 'babel-loader',
      },
      {
        loader: 'ts-loader',
        options: {
          transpileOnly: true, // IMPORTANT! use transpileOnly mode to speed-up compilation
        },
      },
    ],
    exclude: /node_modules/,
  });

  rules.push({
    test: /\.scss$/,
    include: [path.resolve(__dirname, '../src')],
    use: ['style-loader', 'css-loader', 'sass-loader'],
  });

  defaultConfig.plugins.push(new TSDocgenPlugin());
  defaultConfig.resolve.extensions.push('.ts', '.tsx');
  return defaultConfig;
};

```

#### 7. 配置tsconfig 文件:  tsconfig.json

```json
{
  "compilerOptions": {
    "outDir": "build/lib",
    "module": "commonjs",
    "target": "es5",
    "lib": ["es5", "es6", "es7", "es2017", "dom"],
    "sourceMap": true,
    "allowJs": false,
    "jsx": "react",
    "moduleResolution": "node",
    "rootDir": "src",
    "baseUrl": "src",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "declaration": true,
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "build", "scripts"]
}
```
#### 
#### 8. 试运行 Story : npm run storybook

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2019/png/5014/1550633702881-fd95cfcf-c0c9-4416-9895-df86895a73ab.png#align=left&display=inline&height=740&linkTarget=_blank&name=image.png&originHeight=740&originWidth=1135&size=126525&width=1135)

### 
### 三、引入 TSLint

#### 1. 引入 tslint 依赖并添加 lint 配置空文件

```bash
yarn add tslint @ali/tslint-config-ali
touch tslint.json
```

#### 2. 配置 tslint 规则:   tslint.json

```json
{
  "extends": ["@ali/tslint-config-ali"],
  "rules": {
    "no-namespace": false,
    "whitespace": false,
    "no-boolean-literal-compare": false,
    "no-unsafe-any": false,
    "no-implicit-dependencies": false,
    "semicolon": false,
    "no-eval": false,
    "trailing-comma": false,
    "no-use-before-declare": false,
    "variable-name": [
      false,
      "allow-trailing-underscore",
      "allow-leading-underscore"
    ],
    "no-unused-variable": false,
    "ali-method-length": {
      "options": { "limit": 100 },
      "severity": "warning"
    }
  }
}

```
#### 3. 重启 VScode IDE， 测试 TSLint 是否生效 (其他 IDE 工具没有测试)

> 如图： 有 tslint 错误提示 则为生效

![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2019/png/5014/1550634315546-5cc8f477-ffc6-4622-9b17-4d61fc2b72a0.png#align=left&display=inline&height=272&linkTarget=_blank&name=image.png&originHeight=272&originWidth=948&size=36539&width=948)
# 
### 四、build & 暴露组件

#### 1. 添加 copy 依赖库, 增加 index 文件

```
yarn add -D cpx
touch src/index.tsx
echo "node_modules" >> .gitignore
echo "build" >> .gitignore
git init # version control is good for you
```
# 
#### 2. 添加 main、types 指引 和 build  脚本

```json
{
  "main": "build/lib/index.js",
  "types": "build/lib/index.d.ts",
  "files": [
    "build/lib"
  ],
  "scripts": {
    "storybook": "start-storybook -p 6001 -c .storybook",
    "build": "npm run build-lib && build-storybook",
    "build-lib": "tsc && npm run copy-css-to-lib",
    "build-storybook": "build-storybook",
    "copy-css-to-lib": "cpx \"./src/**/*.css\" ./build/lib"
  },
}
```
# 
#### 3. 添加要暴露的组件到 index 文件 ： src/index.tsx

```typescript
import { Button } from './Button/Button';
export { Button };

```


#### 4. npm run build 测试编译文件
![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2019/png/5014/1550636291275-3628ed27-e361-4bb2-88d1-40410fccad49.png#align=left&display=inline&height=394&linkTarget=_blank&name=image.png&originHeight=394&originWidth=956&size=67719&width=956)
# 
# 小结
   <br />    组件的开发方式有很多， 结合 Typescript 和 TSLint 会让我们的开发更紧跟时代潮流， 让我们的组件更具有明确的类型的属性和方法、让我们组件的使用者更快捷方便的使用；一起努力吧， 为更高效的开发；

---
_Source: https://npm.io/package/ccharts-test-buttton · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
