前端项目配置装饰器

570 阅读4分钟

在现如今的前端开发实践中,装饰器成为了提升代码可读性与复用性的一抹亮色。尽管装饰器在JavaScript中目前仍然是一个处于提案阶段的功能,但已有许多项目愿意提前采用,着迷于其能够给日常的代码带来的绚丽多彩。然而,要在现代前端项目中使用装饰器,便需要在项目的构建系统中做一番精心的配置。本文旨在介绍如何在不同前端项目中配置装饰器,使得这一优雅的代码架构得以实现。

普通项目中配置装饰器

对于遵循传统构建方式的普通项目,Webpack和Babel的配合无疑是集成装饰器不可或缺的环节。首先,通过npx webpack --init命令初始化Webpack配置。这个命令会根据项目需求,生成基础的.babelrc文件和webpack.config.js文件以及初始的src/index.js文件,宛如初具轮廓的画布,等待着代码的点睛之笔。

安装所需的依赖@babel/core, @babel/preset-env, @babel/plugin-proposal-decorators,即Babel的核心库,环境预设以及装饰器插件:

yarn add -D @babel/core @babel/preset-env @babel/plugin-proposal-decorators

接着,打开.babelrc文件,在plugins数组中添加装饰器的配置。通过指定"legacy": true,启用旧版装饰器语法,此举如同为古老的文物做一次现代化的修复,既保留了古老的风韵,又适应了现代的使用。

"plugins": [
  ...,
  ["@babel/plugin-proposal-decorators", { "legacy": true }]
],

对于src/index.js的改造,则是直接展示装饰器的魅力所在:

function logDecorator(target, name, descriptor) {
  const originMethod = descriptor.value;
  descriptor.value = function (...args) {
    console.log('执行之前...');
    const rst = originMethod.apply(this, args);
    console.log('执行之后...');
    return rst;
  }
  return descriptor;
}

class MyTest {
  @logDecorator
  add(a, b) {
    const rst = a + b;
    console.log(rst);
    return rst;
  }
}

const ins = new MyTest();
ins.add(10, 20);

在上述代码中,logDecorator是定义好的装饰器,它在目标方法执行前后加入了日志记录,让方法执行过程一目了然。

CRA中配置装饰器

对于使用create-react-app脚手架创建的项目,装饰器的集成稍显不同。首先执行yarn eject,将隐藏的配置文件暴露,这是走向个性化定制Webpack配置的第一步。

随后安装装饰器所需的Babel插件:

yarn add -D @babel/plugin-proposal-decorators

打开暴露出来的webpack.config.js,在babel-loader的配置项中,加入装饰器的配置:

plugins: [
  ...,
  ["@babel/plugin-proposal-decorators", { "legacy": true }]
]

src/App.js中增加测试代码,验证装饰器是否生效。测试代码与普通项目中一致,目的是确保装饰器能够被正确解析和执行。

CRA生成的项目中内置了eslint的配置,为了修复可能会出现的针对装饰器语法的ESLint报错,首先需要清除package.json中自带的eslintConfig。然后在项目根目录下创建一个.eslintrc.js文件,并做如下配置:

yarn add -D @babel/eslint-parser

module.exports = {
  parser: "@babel/eslint-parser",
  extends: [
    "react-app",
    "react-app/jest"
  ]
};

回到webpack.config.js中,将disableESLintPlugin的值修改为true,禁用内部的ESLint插件,避免与自定义配置冲突。

React中使用装饰器替代高阶组件

在React中,装饰器提供了一个更加直观的方式来增强组件的功能。如同一件精心设计的外衣,装饰器包裹着React组件,无声地注入额外的属性或行为。

const withEnhancement = WrappedComponent => {
  return class extends React.Component {
    render() {
      return <WrappedComponent {...this.props} name={'zs'} age={18} />;
    }
  };
}

@withEnhancement
class App extends React.Component {
  render() {
    const { name, age } = this.props;
    return (<div>
      <p>name: {name}</p>
      <p>age: {age}</p>
    </div>);
  }
}

export default App;

在上述例子中,通过withEnhancement装饰器给App组件静默地注入了nameage属性,装饰器的使用使得高阶组件的落地变得更加优雅。

在React中使用doExpressions升级条件渲染

再谈条件渲染,传统的三元操作符虽然清晰,但有时会显得冗长。装饰器和Babel插件配合使用,能够让组件内部的条件渲染更加直观和弹性。

添加@babel/plugin-proposal-do-expressions插件:

yarn add -D @babel/plugin-proposal-do-expressions

然后在处理JSX的Babel配置options.plugins中增加此插件:

plugins: [
  ...,
  "@babel/plugin-proposal-do-expressions"
]

通过以上配置,便可以在React组件中轻松使用do表达式进行条件渲染,代码结构更紧凑,逻辑表达更加丰富。

总结

装饰器的引入为前端项目带来了更多的可能性,使得代码不仅仅拥有功能性,更增添了一份文艺的气息。无论在普通项目还是React项目中,配置装饰器都需要一定的步骤与技巧。经过本文的引导,相信各位前端工匠能够轻松将装饰器的华丽融入项目之中,无论是在提升代码的美观度、实用性,还是在简化复杂逻辑上,装饰器都能大放异彩。