Nx: .babelrc does not override correctly - info inside

Created on 30 Nov 2019  路  5Comments  路  Source: nrwl/nx

  • [x] I am running the latest version
  • [x] I checked the documentation and found no answer
  • [x] I checked to make sure that this issue has not already been filed
  • [x] I'm reporting the issue to the correct repository (not related to Angular, AngularCLI or any dependency)

Expected Behavior

A babel plugin should run by overriding the .babelrc.

Current Behavior

Style components babel plugin is not transforming anything.

I am using styled components and it states here that we can add a .babelrc file

https://www.styled-components.com/docs/tooling#babel-plugin

but it ALSO states that

NOTE
鈿狅笍 The plugin call order in your .babelrc file matters. If you're using the env property in your babel 
configuration, then putting this plugin into the plugins array won't suffice. Instead it needs to be 
put into each env's plugins array to maintain it being executed first. See this for more information.

I have placed a .babelrc inside my app and I know its being picked up by nrwl because if I make a mistake in the file then npm run start - complains.. So I know its being picked up.

My file is this

{
  "plugins": ["babel-plugin-styled-components"]
}

But I assume its being MERGED or something so technically this is NOT the only content of the .babelrc that is being provided.

Is this the case ?

There is a link here that states if we are using the ENV in the baberc then the plugin for each env should be provided - here is the link

https://github.com/styled-components/babel-plugin-styled-components/issues/78

and here is an example

{
    "env": {
        "development": {
            "plugins": [
                ["styled-components", { "ssr": true, "displayName": true, "preprocess": false } ]
            ],
            "presets": ["next/babel"]
        },
        "production": {
            "plugins": [
                ["styled-components", { "ssr": true, "displayName": true, "preprocess": false } ]
            ],
            "presets": ["next/babel"]
        }
    },
    "plugins": [
        ["styled-components", { "ssr": true, "displayName": true, "preprocess": false } ]
    ]
}

Are we merging the .babelrc - so behind the scenes there is a "env" section/s ?

If this is the case, would it not be possible to allow non-merging OR maybe how we can override, like webpack config in NRWL does it, - by writing a JS file and the current config being passed in so we can iterate over the existing config and add more things ?

Failure Information (for bugs)

react bug

Most helpful comment

Hi, I finally managed to get it working without using the macro plugin. The reason behind it is that the plugin must be the first one loaded... Can't use the .babelrc because babel-loader (webpack config) adds plugins before the .babelrc gets executed.

Here is what I ended up with, not really that difficult at all. Would be great if it could be documented somewhere - maybe it would help others.

module.exports = (config, options) => {
  const babelConfig = require("@nrwl/react/plugins/babel")(config)

  const babelRulePluginOptions = babelConfig.module.rules.find(r => r.loader === "babel-loader").options.plugins

  // Add styled-component plugin, the plugin must come before all others.
  const styledPlugin = [
    "babel-plugin-styled-components",
    {
      pure: true
    }
  ]
  babelRulePluginOptions.splice(0, 0, styledPlugin)

  return babelConfig
}

All confirmed as working!

All 5 comments

So i managed to get around it because styled components have a macro plugin which you can use if you don't have access to the .babelrc file. Its documented here https://www.styled-components.com/docs/tooling#babel-macro

But it would be nice if you could still override the .babelrc

I will leave this open as I think its a valid nice to have :-)

@jaysoo what do you think?

@vsavkin @jaysoo I managed to do the following.. created a webpack.config and imported the nrwl babel plugin ie..

module.exports = (config, options) => {
  const babelConfig = require("@nrwl/react/plugins/babel")(config)

  return babelConfig
}

I now have access to the full config on babelConfig variable... and I see this, so I presume i can now parse the tree and do what ever I need.

"module": {
    "rules": [
      {
        "test": {},
        "loader": "babel-loader",
        "exclude": {},
        "options": {
          "compact": false,
          "presets": [
            [
              "/Users/ian/Development/Personal/typescript/instant-accounts/node_modules/@nrwl/web/node_modules/@babel/preset-env/lib/index.js",
              {
                "configPath": "/Users/ian/Development/Personal/typescript/instant-accounts/apps/accounts-web/src",
                "useBuiltIns": "entry",
                "debug": false,
                "corejs": 3,
                "modules": false,
                "exclude": [
                  "transform-typeof-symbol"
                ],
                "targets": {
                  "esmodules": true
                }
              }
            ],
            [
              "@babel/preset-react",
              {
                "useBuiltIns": true
              }
            ],
            [
              "/Users/ian/Development/Personal/typescript/instant-accounts/node_modules/@babel/preset-typescript/lib/index.js"
            ]
          ],

Not the easiest thing to do BUT 100% possible - I am going to take a closer look now.

Hi, I finally managed to get it working without using the macro plugin. The reason behind it is that the plugin must be the first one loaded... Can't use the .babelrc because babel-loader (webpack config) adds plugins before the .babelrc gets executed.

Here is what I ended up with, not really that difficult at all. Would be great if it could be documented somewhere - maybe it would help others.

module.exports = (config, options) => {
  const babelConfig = require("@nrwl/react/plugins/babel")(config)

  const babelRulePluginOptions = babelConfig.module.rules.find(r => r.loader === "babel-loader").options.plugins

  // Add styled-component plugin, the plugin must come before all others.
  const styledPlugin = [
    "babel-plugin-styled-components",
    {
      pure: true
    }
  ]
  babelRulePluginOptions.splice(0, 0, styledPlugin)

  return babelConfig
}

All confirmed as working!

We'll look into this one soon. I think we should be able to get .babelrc support working since that is a pretty common way to override configuration.

Was this page helpful?
0 / 5 - 0 ratings