Webpack to Parcel

a create-react-app migration

Bry Zettler
Pandera Labs
6 min readFeb 5, 2018

--

Preface: This migration was done on an ejected create-react-app in which we added support for the following to the Webpack config: CSS Modules, Sass, and SVG. The source code consists of 27K LOC, 1762 Modules, and uses Webpack v3.10.0. it’s an internal tool that we focused on speed to delivery but sacrificed build performance and load times. Now it has caught up to us and we were looking to get the best performance improvements with the least amount of effort.

For everything we take for granted about what Webpack provides a modern web developer, we can all agree, configuring it easily becomes a major headache. That’s supposed to change with the next major version of Webpack v4, but until then, you still need to spend your time setting up the config and fine tuning it to pull out every possible optimization.

If you’re starting a new project or need to rapidly prototype something, this can very quickly become a pain point. One of the most popular react starter packs, create-react-app, exposes this pain. It goes to great lengths (and does it well) to abstract away all of the Webpack configuration so a user never needs to see it. Until you need to eject from its safety net in order to tweak the configuration.

Zero-Config With Parcel

Parcel promises to simplify that even further, less than 3 months old and with more than 17K stars on GitHub (during the writing of this post), it is as close to a zero-config bundler as you will get. It comes with multi-core support and built in caching for faster builds after the initial build. There is no need for a parcel.config file like there is with webpack.config. All you need for Parcel to work is an entry point, usually index.html with a reference to your index.js file.

Typical entry point

Parcel will then build and serve the app at its default port 1234.

Wanting to test Parcel out, I decided to migrate over an existing
create-react-app from Webpack.

The end results that I wanted to achieve were:
• Faster build times
• Smaller overall bundle size
• Fewer config files
• Maintain the npm start npm build and proxy that come with
create-react-app for convenience.

.rc Files

Although you don’t need a standalone parcel.config file. You still need to configure babel (for JSX and ES6 syntax), postcss (for CSS Modules and autoprefixer), and since we’re using sass we need to include node-sass and configure it.

Instead of combining all this configuration into a single file like weback.config Parcel just depends on their standalone files
.bablerc .postcssrc .sassrc. Once I included these three files and ran the Parcel CLI command the built & minified package, went from 16MB to 10MB, and the build time went from 59 seconds down to 30.72 seconds.

✔ Faster Build Times
✔ Smaller Overall Bundle size
✔ Less config files
(I was able to remove the webpack.config.[dev|prod].js files)

Also, that 30.72 seconds became 16.74 Seconds the second time I ran the command. The reduction in build time is due to Parcel’s cache that gets generated in the initial build. Every build onward from that point utilizes it and is significantly faster. If you ever want it to build without the cache you can pass it the — no-cache arg.

Scripting

One of the downsides of Parcel being less than 3 months old is the lack of documentation. The website gives you just enough to get up and going and generating builds with it. In order for me to maintain the convenience that is create-react-app npm start ,npm build , and its proxy, I needed to know how to write a script with Parcel. Fortunately the source code is very easy to navigate and understand.

This is basically what my scripts/build.js file became. Theres a lot more code that just uses chalk for colored output to the terminal, but that’s not needed to get the point across. The key here is new Bundler — it takes the path for the entry point as its first argument and an object of options for its second. This script will build the bundle and output it to paths.appBuild while generating a build cache to .parcelCache for the next built to utilize.

My scripts/start.js is a little more complicated as I wanted it to have all the same functionality that create-react-app has (e.g., opens browser, uses proxy from package.json).

I had to include express in order to get the proxy functionality I wanted. I used openBrowser from the react-dev-utils package. After I had those set up the only thing I had to do to get express and its proxy working with Parcel is to pass parcel along as a middleware.

Not the complete script, copying and using will result in issues.

The final script grabs the proxy from package.json, sets up a proxy middleware on express with it, bundles the build without a cache (since we’re in dev mode a cache isn't really necessary), and opens the browser to your desired port. In this example the port is hardcoded to 3000.

✔ Maintain the npm start npm build and proxy that come with
create-react-app for convenience.

Benchmarks and Comparisons

Webpack Build
Webpack Build Size
Parcel Build (Without Cache)
Parcel Build (With Cache)
Parcel Build Size

Parcel is still extremely new

Issues are being created and closed everyday. The ease of spin up and integration has me very excited to continue using it, and eventually do a comparison against Webpack v4 once it exits beta. If you’re starting a new project, have long build times, or just don’t want to deal with bundler configs ever again, then I highly suggest giving parcel a try. Its plug and play functionality with minor .rc file configuration is extremely refreshing amongst other web application bundlers.

Edit (02/05/2018):
In the initial draft of this post, the benchmark referencing Parcel build size was not taking sourcemaps into consideration. After enabling it the build difference is now 16MB to 10MB. Not as staggering of a difference but still significant. Changes in the article have been made to reflect this.

At Pandera Labs, we’re always exploring new ways to build products and iterate on our engineering processes, and we value sharing our findings with the broader community as our company and our technology evolve together. To reach out directly about the topic of this article or to discuss our offerings, visit us at panderalabs.com.

--

--