【问题标题】:How to get MobX Decorators to work with Create-React-App v2?如何让 MobX 装饰器与 Create-React-App v2 一起工作?
【发布时间】:2026-01-04 04:40:01
【问题描述】:

目前未启用对实验性语法“decorators-legacy”的支持

我尝试在.babelrc 中添加decorators-legacy babel 插件和@babel/plugin-proposal-decorators{ legacy: true },但没有效果。

有人设法让 MobX 装饰器与 CRA2 一起工作吗?

【问题讨论】:

  • 你的项目是包含原生网络和 react-native 应用的 monorepo 吗?

标签: reactjs decorator babeljs create-react-app mobx


【解决方案1】:

首先,安装依赖:

yarn add react-app-rewired customize-cra @babel/plugin-proposal-decorators

其次,在根目录下创建config-overrides.js,内容如下:

const {
    addDecoratorsLegacy,
    override,
    disableEsLint
} = require("customize-cra");

module.exports = {
    webpack: override(
        addDecoratorsLegacy(),
        disableEsLint()
    )
};

你现在应该可以使用 mobx + 装饰器了。

如果你还没有安装 mobx,请运行: yarn add mobx mobx-react。 现在你可以使用装饰器了。

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,最终使用了 mobx4,其中 装饰器可以在没有装饰器语法的情况下使用

    class Store {
      //...
      @action empty() {
        this.data = []
      }
    
      @action add(e) {
        this.data.push(e)
      }
    }
    

    可以改写为

    class Store {
          //...
           empty() {
            this.data = []
          }
    
          add(e) {
            this.data.push(e)
          }
        }
    
    decorate(Store, {
      add: action,
      empty: action
    })
    

    您可以从 CRA2 开箱即用地使用此功能,而无需担心转换装饰插件。感谢 Michel Weststrate 提供的这些东西

    https://medium.com/@mweststrate/mobx-4-better-simpler-faster-smaller-c1fbc08008da

    【讨论】:

      【解决方案3】:

      选项 1:在 CRA v2 中使用装饰器

      如果你引用Mobx documentation,你可以通过Typescript 让 Mobx 装饰器与 CRAv2 一起工作:

      只有在 create-react-app@^2.1.1 中使用 TypeScript 时才支持开箱即用的装饰器。

      但是,在某些情况下,将 Mobx 与其他 React 框架一起使用时,您可能仍会遇到问题。在这种情况下:

      选项 2:不要使用装饰器

      详细的分步指南记录在 here

      如果您之前将观察者反应组件定义为:

      @observer
      export default class MyComponent extends React.Component
      

      改成:

      const MyComponent = observer(class MyComponent extends React.Component{
        /* ... */
      });
      
      export default MyComponent;
      

      如果您以前有:

      @observable myElement = null;
      

      您需要将其更改为:

      myElement;
      

      然后:

      decorate(MyComponent, {
        myElement: observable,
      })
      

      希望这会有所帮助!

      【讨论】:

      • 选项 2 有效,也使它看起来更清晰!
      【解决方案4】:

      我使用 Babel 7 和 Mobx(使用装饰器工作)做了一个 example project 的 React App 2.0,没有弹出! :

      我用来创建这个项目的链接:

      https://github.com/timarney/react-app-rewired/issues/348

      https://github.com/arackaf/customize-cra#addbabelpluginsplugins

      https://www.leighhalliday.com/mobx-create-react-app-without-ejecting

      【讨论】:

      • 终于有人发布了一个工作示例!我之前已经浪费了很多时间,非常感谢!
      • 您在此处和您的存储库中经常出现拼写错误。这是 BABEL,不是 BABLE。
      【解决方案5】:

      您不必使用更多包或更改配置。

      1- 在商店中使用装饰——用于可观察的、计算的:

      
      import { observable, decorate } from "mobx"
      
      class ToDoStore {
          todos= ["cat","dog"]
      }
      decorate(ToDoStore, {
          todos: observable,
        });
      
      const store = new ToDoStore()
      

      2- 对于观察者 - 使用跟随类样式:

      import React from "react"
      import { observer } from "mobx-react"
      
      const TodoList = observer(class TodoList extends React.Component {
          render() {
              const {todos} = this.props.store;
              const todoL = todos.map(todo => (<li>{todo}</li>))
              return (
                  <div>
                  <h1>ToDo List</h1>
                  <ul>{todoL}</ul>
                  </div>
              );
          }
      })
      export default TodoList
      

      【讨论】:

        【解决方案6】:

        如果你使用 babel 7,你必须在 babelrc 中添加一些配置。安装对装饰器的支持:

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

        并在你的 .babelrc 文件中启用它:

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

        或者您可以使用 MobX 内置实用程序,例如:

        import { observable, computed, action, decorate } from "mobx";
        
        class Timer {
          start = Date.now();
          current = Date.now();
        
          get elapsedTime() {
            return this.current - this.start + "milliseconds";
          }
        
          tick() {
            this.current = Date.now();
          }
        }
        decorate(Timer, {
          start: observable,
          current: observable,
          elapsedTime: computed,
          tick: action
        });
        
        

        我遇到了同样的问题,我使用了 mobx-utility 并且一切都完全适合我。

        【讨论】:

        • “插件”下的代码块是唯一对我有帮助的东西(reactnative 0.61.5)。谢谢!
        【解决方案7】:

        在使用 CRA2 时,要使用 MOBX5,您必须执行以下操作。

        npm install -save mobx mobx-react
        

        现在在您的商店文件中添加以下行。

        import {decorate, observable} from "mobx"
        import {observer} from "mobx-react"
        

        现在你可以使用这样的东西了。

        class Store {
          //...
        }
        
        decorate(Store, {
          list: observable
        })
        
        const appStore = new Store()`
        

        【讨论】:

        • 谢谢。除了提到它的 MobX 4 博客文章之外,我似乎找不到合适的教程。你知道有什么好的资源吗?谢谢!
        【解决方案8】:

        如果你想避免样板代码,虽然其他答案是正确的,但可以在 CRA2 中使用装饰器而不使用 https://github.com/timarney/react-app-rewired/https://github.com/arackaf/customize-cra 弹出

        【讨论】:

          【解决方案9】:

          npm 运行弹出

          将粗线添加到 /config/webpack.config.dev.js 的第 162 行附近。确保在 /config/webpack.config.prod.js 上执行相同的操作,否则应用将无法构建

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

          【讨论】: