Create NPM Package using React

Create NPM Package using React

Loading

Ever wonder how libraries like Tailwind CSS and Material UI are created and released? It’s lot easier than you think, I assure you. We’ll go over how to take our react-toast-alert component and publish it to NPM in this guide.

Publishing your own library can help you attract freelance clients or get a job by adding value to your portfolio. It’s a useful ability that makes a strong impression on potential employers.

Step-1 Setting up the Project

I have a pre built React with TypeScript Toast component. You can get the full code of building this component here.

Create a new folder for your project.

Copy thesrc folder from your toast component and delete all global files and create an index.ts file exporting our component.

 import useNotification from "./hooks/useNotification";
 export default useNotification;

It will look something like this –

Install necessary dependencies like React, TypeScript, and tslib.npm i react typescript @types/react tslib –save-dev

 npm i react typescript @types/react tslib --save-dev

Compiling TypeScript Files

Create a tsconfig.json file by running:

npx tsc -init

Here is the essential configuration we need in tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": ["src"]
}

Explanation of Key Options

  • “target”: “es5”: Ensures compatibility with older browsers.
  • “lib”: [“dom”, “dom.iterable”, “esnext”]: Includes necessary libraries.
  • “allowJs”: true: Allows processing of JavaScript files.
  • “skipLibCheck”: true: Skips type checks for libraries.
  • “esModuleInterop”: true: Enables ES module interoperability.
  • “allowSyntheticDefaultImports”: true: Allows default imports.
  • “strict”: true: Enables strict type-checking.
  • “forceConsistentCasingInFileNames”: true: Enforces consistent file name casing.
  • “noFallthroughCasesInSwitch”: true: Prevents fall-through cases in switch statements.
  • “module”: “esnext”: Uses ESNext module system.
  • “moduleResolution”: “node”: Uses Node.js module resolution.
  • “resolveJsonModule”: true: Resolves JSON modules.
  • “isolatedModules”: true: Isolates each module.
  • “noEmit”: true: Prevents emitting JavaScript files.
  • “jsx”: “react-jsx”: Uses React JSX factory.

Bundling Using Rollup

Now that we have compiled our code, we need to bundle it for different environments.

Install Rollup:

 npm i rollup

Install additional plugins:

 npm i @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-typescript rollup-plugin-peer-deps-external @rollup/plugin-terser rollup-plugin-dts --save-dev

List

  • @rollup/plugin-node-resolve: Resolves dependencies in your code.
  • @rollup/plugin-commonjs: Allows use of CommonJS modules.
  • @rollup/plugin-typescript: Enables TypeScript support.
  • rollup-plugin-peer-deps-external: Manages peer dependencies.
  • @rollup/plugin-terser: Minifies JavaScript code.
  • rollup-plugin-dts: Generates type declarations

Createrollup.config.js:

  1. Add following keys to package.json
    {
      ...
      "main": "dist/index.js",
      "module": "dist/index.mjs",
      "types": "dist/index.d.ts",
      ...
    }

Writing the config (rollup.config.js) –

    import resolve from "@rollup/plugin-node-resolve";
    import commonjs from "@rollup/plugin-commonjs";
    import typescript from "@rollup/plugin-typescript";
    import dts from "rollup-plugin-dts";
    import terser from "@rollup/plugin-terser";
    import peerDepsExternal from "rollup-plugin-peer-deps-external";

    const packageJson = require("./package.json");

    export default [
      {
        input: "src/index.ts",
        output: [
          {
            file: packageJson.main,
            format: "cjs",
            sourcemap: true,
          },
          {
            file: packageJson.module,
            format: "esm",
            sourcemap: true,
          },
        ],
        plugins: [
          peerDepsExternal(),
          resolve(),
          commonjs(),
          typescript({ tsconfig: "./tsconfig.json" }),
          terser(),
        ],
        external: ["react", "react-dom"],
      },
      {
        input: "src/index.ts",
        output: [{ file: packageJson.types }],
        plugins: [dts.default()],
      },
    ];
  1. format: "cjs": Output as CommonJS module.
  2. format: "esm": Output as ES module.
  3. external: Excludes specified dependencies from the bundle.

Build Script:

 {
   ...
   "scripts": {
     "rollup": "rollup -c --bundleConfigAsCjs",
     ...
   }
 }

Explanation of the Build Script

  • “rollup”: This is the name of the script. You can run it using npm run rollup.
  • “rollup -c –bundleConfigAsCjs”: This command runs Rollup with the specified options:
    • -c: Tells Rollup to use a configuration file (rollup.config.js by default).
    • --bundleConfigAsCjs: Ensures the output is bundled as a CommonJS module.
  1. Handling CSS:
    • Install the postcss plugin:
    npm i rollup-plugin-postcss

Update rollup.config.js:

import postcss from "rollup-plugin-postcss";

...
plugins: [
  ...
  postcss(),
],
external: [/\.css$/]
...

Here’s our final rollup configuration file –

    import resolve from "@rollup/plugin-node-resolve";
    import commonjs from "@rollup/plugin-commonjs";
    import typescript from "@rollup/plugin-typescript";
    import dts from "rollup-plugin-dts";
    import terser from "@rollup/plugin-terser";
    import peerDepsExternal from "rollup-plugin-peer-deps-external";

    import postcss from "rollup-plugin-postcss";

    const packageJson = require("./package.json");

    export default [
      {
        input: "src/index.ts",
        output: [
          {
            file: packageJson.main,
            format: "cjs",
            sourcemap: true,
          },
          {
            file: packageJson.module,
            format: "esm",
            sourcemap: true,
          },
        ],
        plugins: [
          peerDepsExternal(),
          resolve(),
          commonjs(),
          typescript({ tsconfig: "./tsconfig.json" }),
          terser(),
          postcss(),
        ],
        external: ["react", "react-dom"],
      },
      {
        input: "src/index.ts",
        output: [{ file: packageJson.types }],
        plugins: [dts.default()],
        external: [/\.css$/],
      },
    ];

Publish to NPM

Finally, you can publish your package to NPM by following these steps:

  1. Log in to NPM:
 npm login

Publish the package:

 npm publish

And that’s it! You’ve successfully created and published a React TypeScript component to NPM.

Related Posts
Leave a Reply

Your email address will not be published.Required fields are marked *