Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

让你的前端组件混沌一下? #45

Open
SugarTeam opened this issue Sep 11, 2020 · 0 comments
Open

让你的前端组件混沌一下? #45

SugarTeam opened this issue Sep 11, 2020 · 0 comments
Assignees
Labels
React React

Comments

@SugarTeam
Copy link
Contributor

什么是混沌

混沌即混沌工程,首先我们得知道混沌工程是什么。

混沌工程起源于Netflix公司,Netflix公司的工程师创建了一种验证服务可靠性的测试工具Chaos Monkey。使用这个工具,可以在我们的web系统中随机的制造一些麻烦,比如触发网络异常,流量激增,容器退出等异常,我们可以在这些异常发生时,观察我们的系统是否依旧按照我们预期的方式运行。假设在流量激增突破承载能力的场景下,我们的系统是否会触发熔断机制来保障功能稳定运行。该工具最大的作用是,让故障在造成重大损失之前暴露出来,给工程师提供足够的时间和机会来修复问题。随着时间的发展,混动工具演变成了一套方法论,用来指导工程师如何让系统提前暴露问题,及时修复问题。

目前国内很多大厂都有相关的混沌工程实践,不过多数都在后端领域实践,在前端中实践混沌工程的相对较少。那在前端中,如何将混沌的方法论和思想落地呢?

在这里插入图片描述

混沌组件

近期在逛github的时候,找到了一个让react组件混沌起来的开源库 react-chaos。这个组件的功能非常简单,它提供了一个高阶组件,该高阶组件的功能是通过一个随机数,让组件随机的Throw Exception出来。如果你的组件没有处理异常的代码,那组件在页面就不会渲染出来的,并且在控制台中会显示出相应的错误信息。出错时的效果如下图所示:

在这里插入图片描述
我们来看看他的源码

const withChaos = (
  WrappedComponent: React.ElementType,
  level: Level,
  errorMessage?: string,
  runInProduction?: boolean
): WithChaosReturn => {
  if (process.env.NODE_ENV === 'production' && !runInProduction) {
    console.warn(
      `You tried to use React Chaos in production. You probably didn't mean to do this. Chaos will not occur in production.`
    );
    return WrappedComponent;
  }

  if (process.env.NODE_ENV === 'production' && runInProduction) {
    console.warn('You are running React Chaos in production.');
  }
  return class extends React.Component {
    render() {
      return (
        <Chaos
          level={level}
          errorMessage={errorMessage}
          runInProduction={runInProduction}
        >
          <WrappedComponent {...this.props} />
        </Chaos>
      );
    }
  };
};

高阶组件withChaos会把传入的原始组件用Chaos组件wrap之后返回,Chaos除了实现混沌相关的逻辑外,没有其他的用途,下面是Chaos的源码

export function Chaos({
  children,
  level,
  errorMessage,
  runInProduction,
}: Args): JSX.Element | null {
  return createChaos(level, errorMessage, runInProduction) ? null : children;
}

Chaos组件中通过createChaos函数返回的值来判断是否渲染children组件

if (process.env.NODE_ENV === 'production' && !runInProduction) {
    /** Chaos will not occur in production. */
    return false;
  }

  if (typeof level !== 'number') {
    throw new Error(
      `Please provide a number level. You provided: ${typeof level}`
    );
  }

  const chaosLevel = level !== 5 ? convertChaosLevel(level) : 0.5;
  const chaosOn = Math.random() >= chaosLevel;
  if (chaosOn) {
    throw new Error(errorMessage);
  }
  return false;

createChaos函数的核心逻辑就是创建一个随机数来实现组件随机抛异常。

这个库功能和原理虽然简单,但它其实是混沌思想在前端的一个非常好的实践。它能让你检测出你的react组件是否对代码异常有比较完善的处理机制。

构建插件

如果想要让组件具有随机抛异常的功能,需要通过react-chaos的withChaos来将组件HOC一下。当你项目中组件非常多且想都增加这个功能的时候,如果每个组件都去手动withChaos然后返回,那工作量会比较大。所以我这边写了一个babel插件,可以在webpack构建的时候,自动的将react组件使用withChaos包裹并返回。

Github地址:

https://github.com/SugarTurboS/babel-plugin-react-chaos

这个插件所做的事情就是通过babel提供的操作AST的能力,将源代码转换为带有withChaos调用的代码

import React from 'react'

function Hello(){
    return (
        <div>Hello</div>
    )
}

export default Hello;

转换后

import React from 'react'
import withChaos from 'react-chaos'

function Hello(){
    return (
        <div>Hello</div>
    )
}

export default withChaos(Hello, |chaosLevel|);

通过这个插件,就能轻松的将react-chaos加入到项目中使用了。

@SugarTeam SugarTeam added the React React label Sep 11, 2020
@SugarTeam SugarTeam changed the title 让你的React组件混沌一下? 让你的前端组件混沌一下? Sep 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
React React
Projects
None yet
Development

No branches or pull requests

2 participants