You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Babel在JavaScript类注解中保留类属性列表?

如何通过Babel在注解中获取类的属性列表?

可以做到,类的实例属性(比如示例中的property = "hello")在原生JavaScript运行时不会直接暴露在类本身,需要借助Babel插件在编译阶段收集属性信息,并传递给装饰器(注解)使用。

具体实现步骤

  1. 配置Babel基础插件
    先安装处理装饰器和类属性的必要依赖:

    npm install @babel/core @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties --save-dev
    

    然后在babel.config.json中启用插件:

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

    这里启用legacy模式是为了兼容常见的装饰器使用方式,loose模式让类属性编译后更易被收集。

  2. 编写自定义Babel插件收集类属性
    这个插件会在编译时遍历类的属性节点,收集属性名后注入到装饰器的参数中:

    // your-custom-plugin.js
    module.exports = function() {
      return {
        visitor: {
          ClassDeclaration(path) {
            const classProps = [];
            // 遍历类体,收集所有实例属性名
            path.node.body.body.forEach(node => {
              if (node.type === 'ClassProperty') {
                classProps.push(node.key.name);
              }
            });
    
            // 找到类上的装饰器,注入属性列表
            const decorators = path.node.decorators;
            if (decorators?.length) {
              decorators.forEach(decorator => {
                if (decorator.expression.type === 'CallExpression') {
                  // 给装饰器调用添加属性列表参数
                  decorator.expression.arguments.push({
                    type: 'ArrayExpression',
                    elements: classProps.map(name => ({
                      type: 'StringLiteral',
                      value: name
                    }))
                  });
                }
              });
            }
          }
        }
      };
    };
    

    将自定义插件加入Babel配置:

    {
      "plugins": [
        "./your-custom-plugin.js",
        ["@babel/plugin-proposal-decorators", { "legacy": true }],
        ["@babel/plugin-proposal-class-properties", { "loose": true }]
      ]
    }
    
  3. 修改装饰器接收属性列表
    现在装饰器可以拿到额外传入的属性列表参数:

    const anno = function () {
        return function (Class, descriptor, properties) {
          console.log('类的属性列表:', properties); // 输出: ["property"]
          return Class;
        }
    };
    
    @anno()
    class App {
       property = "hello";
    }
    

注意事项

  • 装饰器的参数顺序会受Babel装饰器模式影响,legacy模式和新规范模式的参数结构不同,需要根据实际测试调整。
  • 若要收集静态属性,只需在插件中判断node.static属性即可。

内容的提问来源于stack exchange,提问作者dooxe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 19:15:31