npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ccharts-test-buttton

v0.0.4

Published

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

Downloads

6

Readme

组件(库) 之 ButtonDemo

前言

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

图说

003.png

简介

StoryBook

StoryBook : 在你的应用程序之外运行。这允许您单独开发UI组件,这可以提高组件重用,可测试性和开发速度。您可以快速构建,而无需担心特定于应用程序的依赖项。

TS

TypeScript: 老生常谈, js 超级, 拥有可选的强类型定义, 类型可以让你方便快捷的进行类型检查、定义软件组件之间的接口和洞察现有JavaScript库的属性和方法, 在集团不包含蚂蚁金服的已有 990 个 TS 库; 

TSLint (tslint-config-ali) 

TSLint:  是一种可扩展的静态分析工具,可检查TypeScript代码的可读性,可维护性和功能性错误。它在现代编辑器和构建系统中得到广泛支持,可以使用您自己的lint规则,配置和格式化程序进行自定义。

tslint-config-ali: 是集团 TS 规约配套 TSLint 规则和扩展包, 已经融入到喜码中,会作为检测、修复工具辅助集团内部的 TS 开发。

方法步骤

一、初始化Story 

1. 初始化项目 test-comp

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 脚本

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

3. 配置 storybook/config.js 

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 说明

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

5. 写 Style 工具类  utils.js

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

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

二、引入TypeScript 

1. 创建 ts 组件空文件

mkdir src/Button
touch src/Button/Button.tsx src/Button/Button.css src/Button/Button.stories.js

2. 写 ts 组件内容: src/Button/Button.tsx

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

.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

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, 创建相关配置文件

touch .storybook/webpack.config.js tsconfig.json

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

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

{
  "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

三、引入 TSLint

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

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

2. 配置 tslint 规则:   tslint.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

四、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 脚本

{
  "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

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

4. npm run build 测试编译文件

image.png

小结

       组件的开发方式有很多, 结合 Typescript 和 TSLint 会让我们的开发更紧跟时代潮流, 让我们的组件更具有明确的类型的属性和方法、让我们组件的使用者更快捷方便的使用;一起努力吧, 为更高效的开发;