Skip to content

xianengqi/turing-react-ant

Repository files navigation

引用ant design团队的issue编写高质量的业务组件

看了大佬的论述后,觉得非常棒,就摘抄下来,学习大佬的思路。

本文中以React为例, 但其中的观点及方法论,对 Vue, Angular 等同样适用.

React 于2013开源至今,已经过去了七年。这七年里,前端界从一开始对 HTML in JS(JSX) 等新概念的抗拒,到接受,并且在项目中大量使用。现在,React 已经改变了 View 层的开发方式。

可惜对于不少人而言,使用React 也只是改变了他们的开发方式而已。React所提供的,以组件的方式拆分 View 层代码,并通过组件组合的方式搭建页面,这一基本能力并没有被充分发挥。从我过去三年接触过的React项目来看,大多数的开发者(全栈 & 专业前端),只是把组件当作拆分代码的方式,很少会去思考组件该如何设计。结果就是,在项目里随处都能看到组件与 owner 的逻辑, 样式强耦合.

在使用了 React 的前提下,项目里却还是一大堆没有正确封装且相互之间高度耦合的组件,相当讽刺(毕竟 React 在 README.md 里面可是强调了 Component-Based),却在意料之中。因为, React 只是降低了组件实现的难度,并没有降低组件设计的难度。

为了提高项目的质量,我们需要提高项目中 React 组件的设计质量。如果项目只有一个开发者,事情相对容易,只需要不断地提高个人的组件设计能力,并保持相关意识即可。但对由多人协作开发的项目而言,还需要有相应的开发流程保证,才能全面的提高整个项目的质量,如 EsLint 之于代码风格。

但在介绍相应的方法论之前,得先讨论一个更加基本的问题。

为什么需要设计良好的组件


对于业务线的开发者而言,在组件设计上花费较多时间,似乎不是一件值得的事情。毕竟业务系统中的组件,往往只有一个使用场景,所以即使组件与其使用场景强耦合,也不是什么罪过。

对一次性项目而言,如活动页,这个论点是对的。但对于需要长期维护的项目而言,一个组件从开发完成,到最终被废弃,它的使用场景其实是不断变化的,因为项目在不断地迭代,重构。例如,C 组件在一开始是在 A 组件下,

image

一段时间后,A 组件被大幅度重构,可以理解为 A 被一个更好的实现 D 替代了,

image

如果 A 与 C 强耦合,那么这次重构将会非常辛苦,C 也需要面临本可以避免的重构。可见,设计良好的组件,能够降低重构的成本。

当然,上面提到的优点是建立在一个组件会被长期使用,随着项目不断迭代的前提下。但前端界面是一个非常不稳定的存在,一个组件被开发出来用不了多久可能就被废弃了,这还有认真设计的必要么?

即使是会被废弃的组件,仍然需要有良好的设计。同样是上面的例子, A 组件被替换为 D 组件后, root 中与 A 相关的代码必然需要调整。如果 root 与 A 强耦合, 那么 root 就需要较大的改动,而如果 A 是封装良好的组件,那么 root 中只需要移除 A 相关的 state 与 handler 即可。可见,设计良好的组件,能相对容易的移除,被其他组件替换或替换其他组件。

以上。

以下。

在一个隔离的环境中开发组件


与其在开发组件时,时刻堤防着不能与其他组件耦合,还不如直接在一个隔离的环境中开发组件,其实这也是通用组件的开发方式。

为了方便读者理解与实践,接下来会用Storaybook + DvaJS 展示该方法论。必须强调的是,工具和框架是可以自由选择的。

接入 Storybook

  1. npm install dva-cli-g 安装dva-cli, 然后运行 dva ne demo 生成项目目录。
  2. npm i -g @storybook/cli 安装storybook, 然后在 1 创建的项目中运行 getstorybook
  3. 更新 package.json 中的脚本
{
  "scripts": {
    "storybook": "start-storybook -p 9001 -c .storybook"
  }
}
  1. 更新 .storybook/config.js 为以下内容
import { configure } from '@storybook/react';

function loadStories() {
  require('../src/components/stories/Example.js');
}

configure(loadStories, module);
  1. 创建文件 src/components/stories/Example.js 并写入以下内容
import React from 'react';
import { storiesOf } from '@storybook/react';
import Example from '../Example';

storiesOf('Example', module)
  .add('normal', () => (
    <Example />
  ));

然后就可以通过 npm startnpm run storybook 分别运行项目和 Storybook。

开发流程


引入 Storybook 后,在本地开发时,需要同时运行项目与 Storybook。然后组件开发,测试工作都先在 Storybook 中完成,再把组件接入项目系统中联调。流程如下:

image

在一个隔离的环境中开发组件,自然就能保证组件不与上层代码耦合。

除了上文提到的优点,引入 Storybook 还带来了额外的好处:

  1. 组件 debug 会变得简单。

当一个组件碰到问题时,先尝试在 Storybook 及业务系统中分别重现问题。 如果 Storybook 中无法重现,在业务系统中却能重现时,那么问题大概率是在组件的使用方式上。以此类推。
  1. 使用 Storybook 开发组件时编写的 stories 也能成为组件的使用示例,一定程度上缓解了业务代码缺少文档的问题。

About

No description or website provided.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published