Create a React Library Accessible from git repository and npm registry using webpack

January 31, 2024
 
How to create, build, test and utilize a library of React components using Babel with webpack
In this article we will be creating a React component library using webpack. The library will contain reusable components that can be installed into other React applications from either the npm registry or directly from git. For developers that are not allowed to publish their code to the npm registry, such as myself, we will review how to install the library directly from git.

This is the second article in a 2 part series:
In part 1, we simply used Babel to compile the React components into distributable JavaScript code that could be used as a library. In this article we'll enhance our distribution by providing code optimization and asset management for images using webpack.

Setup package.json

Our starting point will be to setup our project to utilize npm by creating the package.json file at the root of your source code.

Create a new directory for your library
mkdir cg-react-webpack-lib
cd cg-react-webpack-lib

Create package.json
npm init

Install Babel as your JavaScript compiler
npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/preset-react babel-loader
If you walked through the first article using only Babel you may notice we are now adding the babel-loader package to use with webpack.

Install webpack
npm install --save-dev webpack webpack-cli

Install React
npm install --save-dev react

Install CSS Loader
npm install --save-dev style-loader css-loader

Note: we installed our dependencies as a development dependency (—save-dev) so that they are not included in the build.

Create Library Components

Now that your project is setup to support npm we can create our components. You can follow along to build the project yourself, which is recommended, or you can download here:
https://CodeGorilla@bitbucket.org/CodeGorilla/cg-react-webpack-lib.git

The project will have the following structure:


Create src/components folder

Create code-gorilla-package.css in src/components folder
.code-gorilla-div {
  color: #ffffff;
  background-color: #007bff;
  font-family: Herculanum;
  font-size: 16px;
  border: 2px solid #adff2f;
  border-radius: 5px;
  padding: 10px;
  margin: 5px;
  text-align: center;
}

Create CodeGorillaArticle.js in src/components folder.
import React from 'react';
import './code-gorilla-package.css';

const CodeGorillaArticle = () => {
    return (
        <div id="code-gorilla-article" class='code-gorilla-div'>
            <h1>Congratulations! </h1>
            <p>Your react component library is working!</p>
            <p>Go to <a href="https://www.code-gorilla.com/">Code-Gorilla.com</a> to read the full article!</p>
        </div>
    )
}

export default CodeGorillaArticle;

Create OtherArticle.js in components folder. This is to demonstrate multiple components in your library.
import React from 'react';
import './code-gorilla-package.css';

const OtherArticle = () => {
    return (
        <div id="code-gorilla-article" class='code-gorilla-div'>
            <h1>Another Component!</h1>
            <p>Your react component library is working!</p>
            <p>Learn more about the Babel JavaScript compiler <a href="https://babeljs.io/">https://babeljs.io/</a></p>
        </div>
    )
}

export default OtherArticle;

Create index.js in src folder. This will expose the src/components externally.
import CodeGorillaArticle from "./components/CodeGorillaArticle";
import OtherArticle from "./components/OtherArticle";

export { CodeGorillaArticle, OtherArticle };

Configure Babel

Because webpack will still be using Babel to compile the JavaScript we should configure it to support React. Just as before, we will create a babel.config.js file in the root folder of the project as follows:
module.exports = {
    presets: [
        "@babel/preset-env", 
        "@babel/preset-react"
    ]
};
To learn more about configuration Bable: https://babeljs.io/docs/usage#configuration

Configure webpack

To configure webpack for the build, we will create a webpack.config.js file in the root folder of the project as follows:
const path = require('path');

module.exports = {
    entry: './src/index.js',
    mode: 'production',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'cg-react-webpack-lib.js',
        globalObject: 'this',
        library: {
            name: "cg-react-webpack-lib",
            type: "umd"
        },
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: ['babel-loader']
              },
            {
                test: /\.css$/i,
                use: ['style-loader', 'css-loader'],
            },
        ],
    },
    externals: {
        react: 'react'
    },
};
Here is a breakdown of the webpack.config.js contents:
  • entry tells webpack where the source code main entry point is.
  • output/filename determines the name of the output bundle.
  • output/library/name determines the name of the library that will be published.
  • output/library/type determines how the library can be used. Universal Module Definition (UMD) type will bundle the code to work with CommonJS, AMD and script tag.
  • module/rules/test uses regex patterns to identify file filters that apply to the loader used while bundling the code.
  • module/rules/exclude identifies folders that may match the file filter that should be excluded from the loader.
  • module/rules/use determines the loader that is used on the identified files.
  • externals identifies modules being used in your library that you do not want to bundle into your library. They will be identified as dependencies by the application using your library.

Build Distribution Code

Once all of the code is created we’ll want to compile it into JavaScript.

Build Script
To do this we will update the package.json to support the build as follows:
"scripts": {
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
The test script placeholder should already exist from the npm init. We will be adding the build script. The results of the build will place the distribution code into a newly created “dist” folder.


Main Entry Point
Finally, you should update the “main” value in the package.json to provide the path to the distribution so that applications installing the code will know where the components are at.
"main": "dist/cg-react-webpack-lib.js",

Run Build
Build the distribution files, this will create the dist folder and put the compiled JavaScript into it.
npm run build

Your library is now fully built and ready to use. Before we publish to the npm registry or git we can test locally, which is what we will be doing in the following steps.

Create Application

Now we will be creating a simple React application that will utilize our library.

Create a new directory for your library
mkdir cg-react-webpack-app
cd cg-react-webpack-app

Create the react application:
npx create-react-app cg-react-webpack-app
cd cg-react-webpack-app

Locally Install Library for Testing

Before we attempt to use the library from the npm repository or git, we can install the library locally as follows:
npm install path/to/cg-react-webpack-lib
The path/to/cg-react-webpack-lib value should be replaced with your directory location for the library created above.

Another alternative would be to create a link that can be accessed globally by going into the root of the library directory and executing the following:
npm link

Modify Application to use Library Components

In src folder, delete everything except:
  • index.js
  • App.js

Update App.js

Replace the contents of App.js with the following:
import { CodeGorillaArticle } from 'cg-react-webpack-lib';

function App() {
  return (
    <div className="App">
     <p>Display the component:</p>
     <CodeGorillaArticle />
    </div>
  );
}

export default App;

Run Application using Local Library
npm start

Once the application is running, it should launch and web browser to display the following:

Git Commit and/or Publish

At this point the library has been tested and ready to commit and/or publish. You should now commit your code to your git repository.

If you have an npm account and have permission to publish your code you can do it now with:
npm publish

If you do not have permission, or if you simply don’t want to publish to the npm registry, you can still use the library directly from git, which is what we will be doing in the next step, where we will be building a React application to utilize our new library.

Install Library from Git

After confirming that everything is working locally we can now install from git.

First we should uninstall our local library:
npm uninstall cg-react-webpack-lib

Now, we can finally install our library from git using the git+ prefix on your git repository. I have committed this code as a public git repository, so you could also install using my code using the following command:
npm install git+https://CodeGorilla@bitbucket.org/CodeGorilla/cg-react-webpack-lib.git

Install from NPM registry

If you published your library to the npm registry you can simply install using the unique name that you published with. I have published the library from this article into the npm registry, which you could try as follows:
npm install cg-react-webpack-lib

Conclusion

So if you’re writing multiple React applications and you find yourself copying and pasting the same code into each project, you can now place them into a library and simply install it into your new projects. And the added bonus is that as you’re improving your library by fixing patches and just making it more awesome, your applications are automatically being updated when they are rebuilt.

References

 
Return to articles