create-react-app 里使用 mobx 装饰器语法

  • create-react-app 目前还没有内置的装饰器支持。要解决这个问题,你可以使用 eject 命令 或使用 react-app-rewired。

使用 create-react-app mobx-project 命令创建一个名为 mobx-project 的项目,npm i mobx mobx-react 安装依赖。
修改 App.js:

import React, { Component } from 'react';
import {observable, computed} from "mobx";
import {observer, Provider} from "mobx-react";

class Store {
    @observable price = 10;
    @observable amount = 2;

    @computed get total() {
        return this.price * this.amount;
    }
}
...

直接这样写,使用 npm start 启动项目时报 Support for the experimental syntax 'decorators-legacy' isn't currently enabled.

使用 react-app-rewired

  1. npm install react-app-rewired --save-dev 使用方法参考antd
  2. package.json 修改:
 "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
    "eject": "react-scripts eject"
  },
  1. npm i -D @babel/plugin-proposal-decorators customize-cra
  2. 在项目根目录创建一个 config-overrides.js 用于修改默认配置
const {override, addDecoratorsLegacy, disableEsLint} = require("customize-cra");

module.exports = override(
      addDecoratorsLegacy(),
      disableEsLint()
    )

使用 addDecoratorsLegacy 方法时必须先安装 @babel/plugin-proposal-decorators 的依赖,源码:


const addDecoratorsLegacy = () => config =>
  addBabelPlugin(["@babel/plugin-proposal-decorators", { legacy: true }])(
    config
  );

失败一: 支持 babel7 装饰器的实现:(并不起作用)

//.babelrc
{
    "presets": ["@babel/preset-env"],
    "plugins": [
        ["@babel/plugin-proposal-decorators", { "legacy": true }],
        ["@babel/plugin-proposal-class-properties", { "loose": true }]
    ]
}
"devDependencies": {
    "@babel/core": "^7.1.0",
    "@babel/plugin-proposal-class-properties": "^7.1.0",
    "@babel/plugin-proposal-decorators": "^7.1.0",
    "@babel/preset-env": "^7.1.0"
}

失败二:使用 babel-plugin-import

 yarn add babel-plugin-import
const { injectBabelPlugin } = require('react-app-rewired');
module.exports = function override(config, env) {
    // do stuff with the webpack config...
    config = injectBabelPlugin(['@babel/plugin-proposal-decorators', { "legacy": true }], config)   //{ "legacy": true }一定不能掉,否则报错
    return config;
};

报错: injectBabelPlugin is not a function
原因:react-app-rewired 2.0 移除了下面的函数

From README:
Version 2.0 removes the rewire helper functions
All helper functions:

  • injectBabelPlugin
  • compose
  • getBabelLoader
  • getLoader
  • babelLoaderMatcher
  • loaderNameMatches
    have been removed with commit 0848602

解决方法是使用 customize-cra 库的 addBabelPlugins 方法代替:
addBabelPlugins(plugins)

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

module.exports = override(
      addDecoratorsLegacy(),
      disableEsLint()  
 )

disableEsLint() 必须,否则报 Parsing error: Using the export keyword between a decorator and a class is not allowed. Please use 'export @dec class' instead.


https://babeljs.io/docs/en/babel-plugin-proposal-decorators

  • 启用ES7的修饰器语法
  • babel 升级到7.X采坑总结

你可能感兴趣的:(create-react-app 里使用 mobx 装饰器语法)