问题
The MobX docs tell me I must "use the transform plugin transform-decorators-legacy and make sure it is first in the plugins list", in order for the decorators to work. The MobX boilerplate project suggests I need a .babelrc
like:
{
"presets": [
"react",
"es2015",
"stage-1"
],
"plugins": ["transform-decorators-legacy", "react-hot-loader/babel"]
}
How do I do that with a create-react-app generated project? Any attempt to use @
decorators errors. There is no .babelrc
even after the project is 'ejected'.
回答1:
You can not use decorator syntax unless you eject. However, you can use MobX without @
since it is just a syntax sugar.
Dan Abramov has articulated the reason for this
Our position is simple: we add transforms that are either stable enough (like async/await) or heavily used by Facebook (like class properties). Only that lets us be confident in suggesting them, because if something changes in the standard, we’ll write and release a codemod to migrate away from them.
Since we don’t currently use decorators, we don’t take it upon ourselves to provide a migration path if the standard becomes incompatible. Additionally decorators aren’t even officially supported by Babel (-legacy is there for a reason). And when they are configured slightly incorrectly people blame React.
You also might want to look into create-react-app-mobx
Related discussions:
- https://github.com/facebookincubator/create-react-app/issues/214
- https://github.com/mobxjs/mobx/issues/521
- https://github.com/facebookincubator/create-react-app/issues/411
回答2:
There's an alternative now that was not available at the time of the accepted answer. It's custom-react-scripts. It will let you enable decorators, SASS and other niceties in your CRA app. And it does so without ejecting.
There's a nice medium article explaining the ideas behind it.
回答3:
You can use https://www.npmjs.com/package/react-app-rewire-mobx
React App Rewired will give you access to the config than you just need to setup the package.
npm install react-app-rewired --save
// create a file named config-overrides.js
/* config-overrides.js */
const rewireMobX = require('react-app-rewire-mobx');
module.exports = function override(config, env) {
config = rewireMobX(config, env);
return config;
}
Note: This saves you from ejecting. CRA does not support modifying the config https://github.com/facebookincubator/create-react-app/issues/99#issuecomment-234657710.
回答4:
Now, you can push require.resolve('babel-plugin-transform-decorators-legacy')
in node_modules/babel-preset-react-app/index.js plugins array
回答5:
This is the best solution I've found without ejecting. Replace create-react-scripts.
https://www.npmjs.com/package/custom-react-scripts
If you have a new project start by using this in your terminal:
create-react-app my-app --scripts-version custom-react-scripts
Then cd into my-app directory and create a .env file. Edit the .env file to this:
REACT_APP_BABEL_STAGE_0=true
REACT_APP_DECORATORS=true
Your app will now support decorators.
If you have an existing app and want to add this. Add the .env like above then:
npm i custom-react-scripts --save
remove react-scripts in your package.json. Do not change the scripts from react-scripts start to create-react-scripts start. Leave the scripts as is.
now add your mobx stuff with decorators and enjoy less boilerplate code.
my final package.json
{
"name": "mobx-test",
"version": "0.1.0",
"private": true,
"dependencies": {
"custom-react-scripts": "^0.2.1",
"mobx": "^3.4.0",
"mobx-react": "^4.3.5",
"react": "^16.2.0",
"react-dom": "^16.2.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
}
oh and if you are using vscode you will want to hide the warnings about unsupported decorators. To do that add a tsconfig.json file to your project with this
{
"compilerOptions": {
"experimentalDecorators": true,
"allowJs": true
}
}
来源:https://stackoverflow.com/questions/39262103/using-mobx-observable-decorators-with-create-react-app