Search code examples
javascriptnext.jsstyled-componentsrollupjsframer-motion

Why am I getting styled is not a function when building my component library with Rollup?


I have an internal component library that is using React, styled-components, framer-motion, Rollup and Storybook. I have a NextJS website that consumes the library and when I try to use it I am getting the following error:

TypeError: styled is not a function

Bellow is the code from the built library which the error points to.

var React = require('react');
var styled = require('styled-components');
var framerMotion = require('framer-motion');

const ButtonElm = styled(framerMotion.motion.button)`
    padding: ${props => props.padding};
    border-radius: ${props => props.theme.radii.default};
    font-size: ${props => props.fontSize};
    ${props => (props.bold ? "font-weight: bold" : null)};
    text-align: center;
    cursor: pointer;
    width: auto;
    display: inline-block;
    text-decoration: none;
`;

I am not sure how to address this bug at all and while I have tried some ways of changing the build configuration, nothing has worked so far. I am not sure what exactly is causing the issue.

Thank you for your help in advance.


Solution

  • I managed to solve the bug with the help of a GitHub issue on the RollupJS repository (this one).

    I did it by adding a property of interop: "auto" to the rollup.config.mjs configuration file and more specifically the CommonJS output file. It ended up looking something like this:

    output: [
            {
                file: packageJson.main,
                format: "cjs",
                sourcemap: true,
                interop: "auto",
            },
            ...
        ],
    

    This changed the build file in the following way:

    var React = require('react');
    var styled = require('styled-components');
    
    var styled__default = _interopDefault(styled);
    
    const ButtonElm = styled__default.default(framerMotion.motion.button)`
        padding: ${props => props.padding};
        border-radius: ${props => props.theme.radii.default};
        font-size: ${props => props.fontSize};
        ${props => (props.bold ? "font-weight: bold" : null)};
        text-align: center;
        cursor: pointer;
        width: auto;
        display: inline-block;
        text-decoration: none;
    `;
    

    which ended up fixing the error. I believe it had to do with the default import of styled-components not being handled properly, resulting in an error. I was getting an object with a default property when running console.log(typeof styled);