Search code examples
reactjsstyled-componentsrollupjs

rollup, styled-components - "withComponent is not a function" error


Fairly new to rollup and have come across this problem. I've googled but I can't seem to find an answer but I am fairly sure it is due to the rollup config.

What I am trying to do

I have a React library I created that uses (among others) styled-components, including a number of components that extend other components created using styled-components via .withComponent.

Code example

Badge.js: -

import styled from "styled-components"

const Badge = styled.span`
  ...
`
export default Badge

Button.js: -

import Badge from "@my/library/Badge"
import styled from "styled-components"

export const Button = styled(Badge.withComponent("button"))`
  ...
`

rollup.config.js: -

import multiEntry from "rollup-plugin-multi-entry"
import babel from "rollup-plugin-babel"

export default {
  input: __dirname + "/src/*.js",
  plugins: [
    babel({}),
    multiEntry()
  ],
  output: {
    dir: __dirname + "/lib/",
    format: "esm",
  },
  preserveModules: true,
  external: ["@my/library", "styled-components"],
}

babel.config.js: -

module.exports = {
  presets: [
    '@babel/preset-env',
    '@babel/preset-react',
  ],
  plugins: [
    "@babel/plugin-proposal-class-properties",
    "babel-plugin-styled-components"
  ],
};

rollup produces the following code: -

Badge.js: -

import { taggedTemplateLiteral as _taggedTemplateLiteral } from './_virtual/_rollupPluginBabelHelpers.js';
import styled from 'styled-components';

function _templateObject() {
  var data = _taggedTemplateLiteral([
    ...
]);

  _templateObject = function _templateObject() {
    return data;
  };

  return data;
}

var Badge = styled.span(_templateObject(), function (props) {
    ...
});

Button.js: -

import styled from 'styled-components';
import Badge from '@my/library/Badge';

var Button = styled(Badge.withComponent("button"))(_templateObject(), function (props) {
  ...
});

The problem

When running webpack on my app, I get the following error message: -

var Button = (0, _styledComponents["default"])(_Badge["default"].withComponent("button"))(_templateObject(), function (props) {
                                                                 ^
TypeError: _Badge.default.withComponent is not a function

I have no idea why this is happening. I thought that having styled-components listed as an external would resolve this but it hasn't. Again, I am new to rollup. Any help greatly appreciated.


Solution

  • I don't know rollup but you can try with the new syntax of styled-components with prop as

    https://www.styled-components.com/docs/api#as-polymorphic-prop

    import Badge from "@my/library/Badge"
    import styled from "styled-components"
    
    export const Button = styled(Badge).attrs({
      as: "button"
    })`
      ...
    `
    
    

    You have to make sure that your component Badge is a styled-components. If not, you could transform it with styled. https://www.styled-components.com/docs/basics#styling-any-component

    if it doesn't help , try to add style-components in globals of output in config rollup

    const globals = {
      react: 'React',
      'styled-components': 'styled',
    }