DEV Community

Cover image for Bootstrapping a React library with Parcel Bundler
José Muñoz
José Muñoz

Posted on

Bootstrapping a React library with Parcel Bundler

Photo by Jøn on Unsplash

Often while working on a project I get to create some neat components that I would like to re-use in the future and keep it in a presentable repo for anyone interested. Most of these side-projects end up in a repo graveyard or not even get split from their original project. Configuring webpack and babel to transpile and expose a UMD module and a demo page can be a daunting task. Although Webpack 4 has introduced config-less operation, today I want to share my experience with Parcel-bundler.

Parcel runs config-less by default, and it is a very fast and flexible bundler that works seamlessly with Babel 7. I want to show you how easy it is to achieve that painless library setup.

Folder Structure

First, we need to create our root folder with the name of our project and initialize it with yarn (or NPM if that's what you're into).

mkdir my-awesome-component 
cd my-awesome-component
yarn init
Enter fullscreen mode Exit fullscreen mode

Once the folder has been initialized we need to add a couple of things


mkdir lib
mkdir example/src
Enter fullscreen mode Exit fullscreen mode

These folders will hold both our source code and the example we're going to write.
These are not the only folders we are going to work with but for now, this is all we need.

Dependencies

I'm only going to talk about the general dependencies you would need to accomplish an environment that provides most of the functionality you get from CRA with a minimal setup using babel 7 and Parcel.

NOTE: At the time writing this Parcel 1.10 is in beta, so I'll be using the beta since the current stable build does not support babel 7.

On the most basic level, we need babel to: transpile to ES5, polyfill generators, and support the object-spread syntax. We are also going to add parcel as our bundler.

 yarn add --dev @babel/cli @babel/core @babel/plugin-proposal-object-rest-spread @babel/plugin-transform-regenerator @babel/plugin-transform-runtime parcel-bundler@^1.10
Enter fullscreen mode Exit fullscreen mode

If you use lodash.js or moment.js you may want to add the babel plugins to shave off those extra KBs from your bundle as well.

Since we are talking about React in here, I'm going to add the obligatory dependencies. Note that react-dom is added to be used in our demo and not necessarily on our library.

yarn add react react-dom prop-types
Enter fullscreen mode Exit fullscreen mode

Configuring Babel 7

Parcel provides a default babel config and it will do most of the things for you. However, you can define your own .babelrc and Parcel will pick it up and add it to their config. Parcel will automatically add some presets like env and react so we don't need to set that up if you check the babel dependencies we didn't even need to include a preset, so we are here just to set up our plugins. I'm using atom, feel free to use your favorite editor!

 atom .babelrc
Enter fullscreen mode Exit fullscreen mode

then add

{
  "plugins": [
    "@babel/transform-runtime",
    "@babel/transform-regenerator",
    "@babel/proposal-object-rest-spread"
  ]
}
Enter fullscreen mode Exit fullscreen mode

and that was it for Babel!

The Scripts

Now the fun part begins. We need to set up the scripts that are going to bring our project to life! open your package.json and head to the scripts section.

 atom package.json
Enter fullscreen mode Exit fullscreen mode

We need a start script that watches our source for changes and compiles it live to /dist (or however you want to call it I'm going for the default).

We need a build script that compiles and minifies our bundle and makes it ready for shipping.

we need a start-demo script which watches the source of our example in examples/src

We need a build-demo so our demo can also be bundled and get ready to be served on github pages

We also need a publish-demo script so we can push the bundle to GitHub.

{
  "start": "parcel watch lib/index.js",
  "build": "parcel build lib/index.js --global my-awesome-component",
  "start-demo": "parcel example/src/index.html --out-dir examples/dist --open",
  "build-demo": "parcel build example/src/index.html --out-dir examples/dist --public-url ./",
  "publish-demo": "gh-pages -d examples/dist",
}
Enter fullscreen mode Exit fullscreen mode

NOTE: the --global option denotes the UMD package name, so you need to provide the name your NPM package is going to have. Also, make sure your examples' index.html has a script tag referencing your index.jsx and parcel will take care of the rest

Extra

Source maps are generated by default using Parcel, and they can be a powerful tool to analyze and optimize your bundle size. Let's take advantage of them.

Source-map-explorer is a CLI that generates a report based on your existing source maps, we are going to use this tool to generate a visual representation of our bundle.

 yarn add --dev source-map-explorer
Enter fullscreen mode Exit fullscreen mode

now let´s add a script to generate the HTML representation of our source map.

"view-source-map": "source-map-explorer --html dist/index.js dist/index.map > source.html && open source.html" 
Enter fullscreen mode Exit fullscreen mode

now you can open source.html on your browser and figure out where you can shave off those extra KBs.

NOTE: If you are running windows you need to remove open to launch the generated html to your default browser

Conclusion

With the configuration we've discussed here, you can throw in something you cooked up in CRA with minimal changes and publish it as its own library with a nice demo hosted on GitHub pages. I hope this can encourage other devs to start using parcel and get their ideas published faster. Thanks for reading if you got this far, please leave a comment to share your thoughts!

Top comments (2)

Collapse
 
tidelake profile image
Jesse Crockett

i had to remove 'open' on ubuntu 18

Collapse
 
josemunoz profile image
José Muñoz

Hi Jesse, I have a repo with all the boilerplate, please feel free to use it github.com/jdmg94/minimum-parcel-lib