Remove html attribute in production build

There are a few babel plugins that might fit the bill for this:

  • babel-plugin-react-remove-properties
  • babel-plugin-remove-attribute
  • babel-plugin-remove-object-properties

Edit from comments

Attributes are automatically ignored if their value is undefined. You can use that to your advantage and use some kind of configuration (possibly process.env.NODE_ENV?) and a Higher-Order Component to set a prop for the data-app-feature value only if not in production.

HOC

const appFeature = (Component, appFeature) => (props) => {
  const isRunningInProduction = configuration.isProduction // or however you want to set this
  return <Component appFeature={ isRunningInProduction ? appFeature : undefined } {...props}  />
}

Component

const ExampleComponent = ({appFeature}) => {
  return <div class="Component__item___2jdnc" data-app-feature={appFeature}></div>
}

export default appFeature(ExampleComponent, "example-id")

This answer is purely for the people who use webpack for production/development builds of the application. Do the following in webpack.prod.config. Ignore in webpack.dev.config

  • Install plugin by running npm installbabel-plugin-react-remove-properties
  • Add it in babel loader configuration as follows

      {
        test: /\.(js|jsx)$/,
        use: [{
          loader: 'babel-loader',
          options: {
            plugins: [
              ["react-remove-properties", {"properties": ["data-test-id"]}]
            ]
          }
        }],
        exclude: /node_modules/,
      }
    
  • data-test-id is the attribute we are going to use in selenium test cases to get the elements. According to the question, it is data-app-feature

The same thing we can do using below plugins.

  • babel-plugin-remove-object-properties
  • babel-plugin-remove-attribute

I ran into the same issue while using styled-components. This is the solution I found to be most straight forward to me without using a HOC or Babel plugins.

I created a function which checks for a specific environment and then returns the value you pass to it, or undefined. If the attribute value is undefined the attribute wont be included.

export const ifDev = val => (process.env.NODE_ENV === "development" ? val : undefined);

Then in your components:

import { ifDev } from './dev';

<div className="sc-fMiknA" data-app-feature={ifDev("element-id")}></div>

Now I can find elements in browser tests while using generated class names and the attributes won't be included in production builds.