DEV Community

Keyur Paralkar
Keyur Paralkar

Posted on

What I learned from publishing my First NPM React package

Introduction

I published my first React UI Wrapper on NPM. You can find the package below:

https://www.npmjs.com/package/react-horizontal-scroll-grid

It is a simple Ui wrapper which helps you to create horizontal scroll view. I was inspired by Netflix, Amazon and other online video streaming apps to create this package. For Example consider the Netflix app, it has this sleek horizontal scroll with movie/TV show titles in it.

I bumped into many ups and downs while creating this package. I would like to share the same with everyone.

Approach

Step 1: CRA to rescue

Since I am a newbie to react so my first step for creating this package was to use create-react-app. So for any react-developer this is the most common step:

npx create-react-app <project-name>
Enter fullscreen mode Exit fullscreen mode

The above command created a ready-to-go react project within minutes. Later I realized this was the worst thing I did. Later on this in Pitfalls section.

Step 2: Writing code logic

The code logic behind the package is pretty straight forward. Before diving into code logic I am assuming that you guys have knowledge of css-grids. The HScrollGrid is the UI Component name in our package that is wrapped around couple of <li> HTML tags. Below is the code logic for HScrollGrid:

class HScrollGrid extends React.Component{
    constructor(props){
        super(props);

        this.hscrollRef = React.createRef();
    }

    componentDidMount(){
        let n = this.hscrollRef.current ? this.hscrollRef.current.children.length : 0;
        let gW = `${this.props.gridWidth}px`;
        let gH = `${this.props.gridHeight}px`;
        let cW = `${this.props.cardWidth}px`;
        let cardBgColor = this.props.backgroundColor ? this.props.backgroundColor : 'transparent';

        if(this.hscrollRef.current){
            this.hscrollRef.current.style.setProperty('--total', n);
            this.hscrollRef.current.style.setProperty('--gridWidth', gW);
            this.hscrollRef.current.style.setProperty('--gridHeight', gH);
            this.hscrollRef.current.style.setProperty('--cardWidth', cW);
            this.hscrollRef.current.style.setProperty('--cBgCol', cardBgColor);
        }
    }
    render(){
        return(
            <ul className="hscroll-grid" data-testid="test-ul" ref={this.hscrollRef}>
                {this.props.children}
            </ul>
        );
    }
}
Enter fullscreen mode Exit fullscreen mode

I am using css-variables in the react component to pass in the values back to css properties. The advantage I have over here is, now I can dynamically pass the props of the component to css properties. Below is the css code for grid layout. Notice how I have used the css-variables pass down via the HScrollGrid component as a prop:

ul.hscroll-grid{
    width:var(--gridWidth);
    height: var(--gridHeight);

    display:grid;
    grid-template-columns: repeat(var(--total), var(--cardWidth)) 10px;
    grid-column-gap: 20px;

    overflow-x:scroll;
    overflow-y:hidden;
}   

li{
    width: var(--cardWidth);
    height: var(--gridHeight);
    background-color: var(--cBgCol);
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;

    box-shadow: 0 4px 8px 0 rgba(0,0,0,0.1);
    transition: 0.3s;
}

li:hover{
    box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}
Enter fullscreen mode Exit fullscreen mode

Pitfalls

  • The first mistake I did was to choose CRA for creating an npm package. As I am aware, that a package should have least amount of dependencies on other packages. Over here since we have used CRA therefore it comes with a lot of pre-installed dependencies that are not required.
    I faced some serious issues related to package broken error on different systems and environments. To solve this I googled a lot of things related to the keyword dependencies and dev-dependencies. Found the following two to be most relevant:

    1. Remove additional(not required) dependencies manually which are found under dependencies key of package.json file.
    2. To do: npm run eject

    I ended up with the former approach i.e. Remove additional dependencies. I did not use the latter approach because I ran into breaking the entire code :(

  • Second mistake was choosing CRA: npm run build command minified all the code present in all component files and clubbed them together. I found this to be quite annoying because I just wanted to transpile all my HScrollGrid component code into es5 so that it is support by majority of the browsers. And also I just wanted this single component file to be processed whenever I ran build command. To solve this I had the following sub-approaches:

    • Either I do npm run eject and modify webpack.config.js. OR
    • I edit the build command to make use of babel-cli command to transpile my component files into one lib folder.

    I choose the latter option because it was less time consuming. I know this is a dirty fix and not at all recommended but I was too excited to roll out my first NPM Package :)

Publishing to NPM

After all the dirty fixes and chaos I manged to pull off the package. I tested it first locally and then published it on NPM.

Publishing a package on NPM was easy. You need to get yourself registered on npm. Post that you will need to login via CLI in your local system:

npm login
Enter fullscreen mode Exit fullscreen mode

After publishing all your commits to your repository you can simply enter following command to publish the package on NPM:

npm publish
Enter fullscreen mode Exit fullscreen mode

Final thoughts

It was an awesome experience in publishing the first NPM public package. I am planning to focus on building more packges.

This journey taught me lots of new things such as: CRA-boiler plate code, cons of using CRA, creating production grade code, understanding and editing various config files such as: webpack.config.js, package.json etc.

Feel free to contact me about the problems. I will try to help as much as I can 😉

Linkedin Badge

Mail Badge

Twitter Badge

Github Badge

Top comments (0)