Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom babel presets & plugins via environment variables #900

Closed
philiptzou opened this issue Oct 13, 2016 · 13 comments
Closed

Support custom babel presets & plugins via environment variables #900

philiptzou opened this issue Oct 13, 2016 · 13 comments

Comments

@philiptzou
Copy link

philiptzou commented Oct 13, 2016

Hello, I found an easy way to enable additional presets & plugins in my fork of react-scripts. I want to share it with others and the maintainer of this original repository may find this feature useful and add it to the main react-scripts.

Basically, what I did was just introducing two environment variables BABEL_PRESETS and BABEL_PLUGINS, which accept JSON encoded list of path strings. Users can enable any kind of presets/plugins by specify those two variables before they run npm start.

For example, I need to enable react-relay support. What I did is just execute this command before I start the development server:

export BABEL_PLUGINS="[\"`pwd`/plugins/relay-plugin.js\"]"

With my forked react-scripts (@philiptzou/react-scripts) and other related relay packages installed, the webpack server is able to handle Relay.QL syntax now.

I just noticed that we can use .env file to specify REACT_APP_ initial variables. It maybe a more elegant way to do this in the future.

@philiptzou philiptzou changed the title Support custom babel presets & plugins via environment variables? Support custom babel presets & plugins via environment variables Oct 13, 2016
@gaearon
Copy link
Contributor

gaearon commented Oct 13, 2016

Hi, thanks for the issue!

We have decided to punt on custom Babel plugins in the close future. This is more of an advanced use case, and it will be hard for us to guarantee compatibility with this while shipping new features.

We will likely reevaluate this position some time next year, but now is not the time yet.
See also discussion in #462.

@nylen
Copy link

nylen commented Nov 17, 2016

This is possible to achieve today, though definitely unsupported. Automattic/wp-api-console#45 (comment) is an example for a production build, and it looks like something similar would work for the dev server too.

@gaearon
Copy link
Contributor

gaearon commented Nov 20, 2016

It's frustrating people don't reach out to us first with their use cases. I'd be happy to get Automattic/wp-api-console#45 (comment) in.

@spudly
Copy link
Contributor

spudly commented Dec 2, 2016

My 2¢:

I would love to have the ability to add custom presets. At the moment, my only option is to fork the repo. I also understand why you would want to wait to implement something like this.

When you are ready to support something like this, I'd like it to just let me configure babel the way I do in all my other projects (using the babel key in package.json, or a .babelrc file).

Would you (eventually) accept a pull request that would make the webpack config file autodetect a .babelrc or package.json/babel key and (if detected), use that config instead of babel-preset-react-app?

@gaearon
Copy link
Contributor

gaearon commented Dec 5, 2016

What is the reason you don't want to use Webpack directly in this case?

@spudly
Copy link
Contributor

spudly commented Dec 5, 2016

Because I don't want to override the webpack config completely, just the Babel config.

That's why I suggest that we could just allow Babel to use the .babelrc if it exists. If it doesn't exist, it'll continue to use the default preset.

@philiptzou
Copy link
Author

philiptzou commented Dec 5, 2016

Using .babelrc is more gentle and friendly than my above solution. And we can still have the default settings for everyone who doesn't want or need customizations.

smmoosavi added a commit to monkey-patches/monkey-react-scripts that referenced this issue Mar 13, 2017
@danielkcz
Copy link

danielkcz commented Sep 18, 2017

Hey, @gaearon. Sorry for reviving the old issue. Strangely enough, I wasn't able to find anything new and relevant. Based on your #900 (comment) above is it already time to reevaluate this? :)

I am used to using babel plugin transform-export-extensions in almost every of my project. I am well aware it's in stage 1 for a very long time now, but I still want to use it.

Feels odd I would need to eject just to add one small plugin. So what is your stance on this after one year? :)

Btw Create-React-Native-App supports using .babelrc :) I know it's whole different story there, but I just felt that comparison is in place :)

@anon-r-7
Copy link

@gaearon +1 For babelrc support; this seems like it might be standard functionality. I'd like to be able to use the following babel plugins:

"transform-class-properties",
"syntax-decorators",
"transform-decorators-legacy"

And a use case for transform-decorators-legacy: let's say you are using three wrappers on a given component, as such:

import React from 'react'
...

class Component {...}
export default connect((state) => {
  someProp: state.someProp,
  otherProp: state.otherProp,
}, ReactForm(Radium(Component)))

This starts to get really difficult to read -- and also forces us to include these statements near the bottom. It's much cleaner to use the new babel decorator, like so:

import React from 'react'
...
@connect((state) => {
  someProp: state.someProp,
  otherProp: state.otherProp,
})
@ReactForm()
@Radium()

class Component {...}
export default class Component

A much cleaner solution, and it includes our wrappers near the top where we know what's going on from the get go. So now we can call a given action like so:

someFunction() {
  const { dispatch } = this.props.dispatch
  dispatch(someReduxAction())
    .then(() => { this.someFunctionAfterDispatch() })
}

Using dispatch to call our actions is a much cleaner approach in general, and we get the added benefit of getting to call then() on the dispatch. It also makes our code easier to read. Rather than having this.props everywhere for all our actions, we can look for our actions with the dispatch action. But this is only possible, to my knowledge, with something like a decorator -- which to my knowledge, is only available with transform-decorators-legacy, which to my knowledge is only available through .babelrc plugins object.

Feel free to shoot some holes in this. My example isn't intended to be exhaustive -- just wanted to give one very clear example of how having access to this functionality helps improve a project dramatically with a very lightweight implementation of babelrc config.

@anon-r-7
Copy link

anon-r-7 commented Sep 19, 2017

@FredyC An alternate solution until .babelrc configuration is available is to install the babel package manually and specify it in your package.json babel object. Like so:

npm install --save babel-plugin-name-of-plugin

And in package.json under babel add the following:

"plugin"": [ "name-of-plugin" ], @

@danielkcz
Copy link

danielkcz commented Sep 20, 2017

@ryanostrom Regarding a need for decorators, consider approach I've described in my short article. Decorators are not really needed not even mentioning they tightly couple your component to some other stuff and make it harder to test. But this issue is hardly placed to talk about that. Feel free to comment on my article instead.

I don't understand why are you calling for support of .babelrc when you are convinced that adding it to package.json works the same way. I tried it and doesn't work for me. If it would work this issue would not be necessary.

@anon-r-7
Copy link

anon-r-7 commented Sep 20, 2017

@FredyC thanks for the additional info, I'll take a look at your article.

I just tested this functionality yesterday and did find that adding it in package.json does work if you install the corresponding babel package via npm as well. I find it a cumbersome solution because it requires that you install an individual npm package for each and every babel plugin that you want -- whereas with babelrc it's a little more automatic. And I'm not convinced that every configuration that you get in babelrc would also work in package.json (although I haven't thoroughly tested). Here's a snippet from my package.json file:

  "babel": {
    "plugins": [
      "transform-class-properties",
      "syntax-decorators",
      "transform-decorators-legacy"
    ],
    "presets": [
      "react-app"
    ]
  },
  "devDependencies": {
    "babel-plugin-syntax-decorators": "^6.13.0",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
  }

@danielkcz
Copy link

danielkcz commented Sep 20, 2017

I find it a cumbersome solution because it requires that you install an individual npm package for each and every babel plugin that you want -- whereas with babelrc it's a little more automatic.

I don't understand. Automatic how? How would specifying something in .babelrc know what version of a plugin you want to install and use? :) I think you have been misled somewhere along the path ;) Or you just got lucky because some other dependency has installed plugins you have specified there. Either way, every babel plugin needs to be installed with NPM (or Yarn).

@lock lock bot locked and limited conversation to collaborators Jan 21, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants