DEV Community

Rafael De Leon
Rafael De Leon

Posted on

Picking a bundler for react-hook-use-cta

Prelude

The main takeaway is going to in installing, setting up package.json and .parcelrc. The rest is just details.

Selecting a bundler

The goal when selecting a bundler was to

  • have minimal and easy setup
  • generate files to be consumed by another bundling tool
  • not have bloated file size

I remembered reading about ParcelJS being good for bundling libraries meant for consumption. Sure enough, it is!

I went through Parcel's doc site to look at what I needed and it boiled down to the following:

Installing dev deps

npm i -DE parcel @parcel/bundler-library @parcel/transformer-typescript-types rimraf
Enter fullscreen mode Exit fullscreen mode

Note:
I like to use -E flag so that packages are installed with the exact version number. I had a past experience where not being exact cause my old team issues with inconsistent package versions being installed on different machines. This isn't really an issue when you commit package-lock.json but I like to be safe.

parcel is the core package.
@parcel/transformer-typescript-types is included for Typescript transpiling files.

The rest of the packages will be explain through out the article.

Changes to package.json

{
  "exports": {
    "import": "./dist/esm/index.mjs",
    "require": "./dist/cjs/index.js",
    "types": "./dist/types.d.ts"
  },
  "main": "dist/cjs/index.js",
  "module": "dist/esm/index.mjs",
  "sideEffects": false,
  "source": "src/index.ts",
  "types": "dist/types.d.ts",
  "scripts": {
    "build": "rimraf dist && parcel build --log-level verbose --no-cache"
  }
}
Enter fullscreen mode Exit fullscreen mode

"exports" helps module resolution find the relative path for:

  • "require" CJS compatible files
  • "import" modern JS compatible files.
  • "types" Typescript declarations files.

"source" is for ParcelJS know what file to bundle from.

Output file paths are designated through:

  • "main" for creating CJS bundle. Content root path to exports.require
  • "module" for modern bundles. Content root path to exports.import
  • "types" for Typescript declarations. Content root path to exports.types

"sideEffects": false tells webpack it can aggressively tree shake this package when it bundles it from a webpack project.

scripts.build was setup to call rimraf for removing the dist to ensure clean local builds, even if the folder doesn't exist yet.

With the exception of index.js, index.mjs, and types.d.ts(.map),
ParcelJS generates files with a unique hash that changes based on the file contents, and the filename it's related to. Example, useCTA.ts could generate as useCTA.ae11379d.js. This tells other bundlers caching mechanism to bundle new changes when rebuilding.

.parcelrc

{
  "extends": "@parcel/config-default",
  "bundler": "@parcel/bundler-library"
}
Enter fullscreen mode Exit fullscreen mode

"extends": "@parcel/config-default" is necessary to enable tree-shaking config.

"bundler": "@parcel/bundler-library" enables creating tree-shakable bundle

Start bundling

npm run build
Enter fullscreen mode Exit fullscreen mode

to see what ParcelJS generates in dist folder.

And that's it! Next, I'll go over publishing a library.

Top comments (0)