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

Is there a good reason why .babelrc at the top directory is not a default way to customize babel-loader config? #203

Closed
unconfident opened this issue Feb 17, 2018 · 12 comments

Comments

@unconfident
Copy link
Contributor

I mean, that's probably something that would be expected by many, wouldn't it? Especially considering that react-app-rewire-eslint enables .eslintrc support. Well, at least that's something I was confused about initially myself

The only related thing I found is #83 but that's more about Jest config. And it just seems weird to have it partially supported in some places but not the others and having to duplicate the same configuration options in two different places

What I'd like to propose is adding another function to the main package that would simillarly to injectBabelPlugin locate rules using babel-loader and switch babelrc option to true.
This way it will be both, explicit and backwards compatible

@timarney
Copy link
Owner

Going to add this to the 2.0 discussion and close this issue.

@harrysolovay
Copy link
Contributor

I tried writing out (in config-overrides) a function that would parse the root-level .babelrc, then use injectBabelLoader or other rewiring to register the config. I wasn't able to get it working... for some reason, reading the .babelrc file gave me HELL... still I think this could be a good solution for the time-being, if anyone wanted to take a shot at making a react-app-rewire-babelrc plugin, I think this is absolutely something people would be interested in.

@unconfident
Copy link
Contributor Author

Works fine for us and wasn't very difficult to accomplish:

/* config-overrides.js */
const { getBabelLoader } = require('react-app-rewired');

module.exports = function override(config, env) {
  const babelLoader = getBabelLoader(config.module.rules);

  if (babelLoader) {
    babelLoader.options = {
      babelrc: true,
      cacheDirectory: true,
    };
  }

  return config;
};

It then picks .babelrc from the top directory of the project automatically.

Protip: you obviously don't want original presets, plugins or other keys that may possibly be set by create-react-app to remain in the options object, and that's why you replace babelLoader.options completely. Otherwise it will get mixed with contents of your .babelrc config

Default babel-loader configuration with react-scripts@1.1.4 looks something like this:

{
  babelrc: false,
  presets: [ 
    '/path/to/your/project/node_modules/babel-preset-react-app/index.js'
  ],
  cacheDirectory: true 
}

@harrysolovay
Copy link
Contributor

@unconfident –– this is extremely helpful! THANK YOU!!!

@harrysolovay
Copy link
Contributor

Just tried this out and it's not working for me:

config-overrides.js

const { getBabelLoader } = require('react-app-rewired')

module.exports = (config, env) => {
  const babelLoader = getBabelLoader(config.module.rules)
  if(babelLoader) {
    babelLoader.options = {
      babelrc: true,
      cacheDirectory: true,
    }
  }
  return config
}

.babelrc

{
  "presets": [ "react-app", "env" ],
  "plugins": [
    ["module-resolver", {
      "root": "./",
      "alias": "./src"
    }],
    "react-require",
    "inline-react-svg",
    "babel-plugin-styled-components"
  ],
}

Any ideas on how I can get it working? THANK YOU!

@harrysolovay
Copy link
Contributor

Never mind, I got it working :) –– I'm pretty sure the module-resolver config was causing problems

@slorber
Copy link

slorber commented Aug 22, 2018

So, as far as I understand, this is the cleanest way to share babel config between yarn start and yarn test right? thanks!

@timarney that would be very useful for me in 2.0. I'm using emotion and need the emotion babel plugin to get proper jest snapshots (using css prop). I feel like creating a .babelrc that would be used just in tests would be very confusing

@harrysolovay
Copy link
Contributor

This should do the trick:

const { getBabelLoader } = require('react-app-rewired')
module.exports = (config) => {
  const babelLoader = getBabelLoader(config.module.rules)
  babelLoader.options.babelrc = true
  return config  
}

@unconfident
Copy link
Contributor Author

This will behave slightly weird and possibly differently for CRA and Jest if you do it like this. Please see "protip" part of my comment from two weeks ago

tl;dr: you want to replace whole options object instead of modifying it

@harrysolovay
Copy link
Contributor

What if you're already using another babel-related rewire?

@unconfident
Copy link
Contributor Author

unconfident commented Aug 22, 2018

Just don't and have everything you need in .babelrc like everyone else?

update: But I get your point. That said, if babelrc: true were to become a default in 2.0 I would prefer to not have babel-preset-react-app included in this "obscure" way and just have it specified in .babelrc instead with minimalistic loader configuration

@slorber
Copy link

slorber commented Aug 23, 2018

  • making a .babelrc the defauld would make it useless to have these rewire packages, and the storybook integration would work out of the box, no need for this:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants