Skip to content

Instantly share code, notes, and snippets.

@murraco
Created May 18, 2019 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save murraco/90290d2e4f56320c278351a9ef2f940c to your computer and use it in GitHub Desktop.
Save murraco/90290d2e4f56320c278351a9ef2f940c to your computer and use it in GitHub Desktop.

JavaScript Bundlers

Shared Dependencies

We can start by setting up our package.json file by adding Babel, which will be used, in some capacity, by each of the three tester build tools:

  • babel-loader
  • babel-plugin-external-helpers
  • babel-preset-env
  • babel-preset-stage-0

Babel provides transpilation support for translating newer ES6 and ES7 syntax into web-browser compliant ES5. Babel provides this support for other JavaScript dialects through babel-presets along with polyfills and shims.

Once we've added Babel, we need to supplement our project with the following .babelrc in our project root:

{
  "presets": ["env", "stage-0"]
}

Parcel

Parcel was recently released and provides an incredibly light-weight, almost configuraiton-free, build tool. We add the following parcel dependencies to our package.json:

  • parcel-bundler

The core difference here between Parcel and Webpack 4 is that we directly set the index.js file into the script.scr of our index.html or view rather than the compiled bundle.

In other words, we would put:

<script src="../reactAppSrc/index.js"></script>

Rather than:

<script src="built/vendor.min.js"></script>
<script src="built/built.min.js"></script>

We can then run the following command to transpile our dependencies:

$ parcel index.html

For production builds:

$ parcel build public/parcel.index.html

The magic behind Parcel is that it will automatically build a dependency and script tree, then proceed to transpile, minify, and bundle those assets as needed without any human configuration required.

Parcel also caches its build processes, vastly decreasing build time on subsequent runs.

Rollup

Rollup represents another recent addition and alternative. Users who've used webpack will find Rollup's configuration familiar and easy to set up:

We add the following Rollup dependencies:

  • rollup
  • rollup-plugin-babel
  • rollup-plugin-uglify

For Development:

$ rollup -c rollup/rollup.dev.config.js --external all
import babel from 'rollup-plugin-babel'

export default {
  entry: 'reactAppSrc/rollup.index.js',
  dest: 'public/built/main.min.js',
  format: 'iife',
  plugins: [
    babel({
      babelrc: false,
      exclude: 'node_modules/**',
      presets: [
        'react',
        [
          'es2015',
          {
            'modules': false
          }
        ]
      ],
      'plugins': [
        'external-helpers'
      ]
    })
  ],
};


For Production:

```bash
$ rollup -c rollup/rollup.prod.config.js --external all
import babel from 'rollup-plugin-babel'
import uglify from 'rollup-plugin-uglify'

export default {
  entry: 'reactAppSrc/rollup.index.js',
  dest: 'public/built/main.min.js',
  format: 'iife',
  sourceMap: 'inline',
  plugins: [
    babel({
      babelrc: false,
      exclude: 'node_modules/**',
      presets: [
        'react',
        [
          'es2015',
          {
            'modules': false
          }
        ]
      ],
      'plugins': [
        'external-helpers'
      ]
    }),
    uglify()
  ],
}

Webpack 4

Webpack dependencies:

  • webpack
  • webpack-cli

The release of Webpack 4 continues to see significant improvements and simplified configuration:

'use strict'

const path = require('path')
const webpack = require('webpack')

module.exports = {
  mode: 'production',
  entry: './reactAppSrc/index.js',
  output: {
    path: path.resolve(__dirname, '../public/built/'),
    filename: '[name].min.js',
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader'
      }
    ]
  },
  plugins: []
}

Here, we just need to switch the mode attribute by running one of the following two commands:

$ webpack --config webpack/webpack.dev.config.js --progress --profile --colors
$ webpack --config webpack/webpack.prod.config.js --progress --profile --colors

Other Considerations

  • Parcel's caching feature sees dramatically decreases in time consumption after the initial run. For frequent, small changes, in smaller projects Parcel is a great choice.
  • Rollup provides much simpler configuration over Webpack 4 and has a host of pre-configured plugins that are a breeze to incorporate into your project. Rollup's also the fastest of the build tools period.
  • Rollup also provides convenient source maps, which can aid in debugging.
  • Webpack 4 has gotten a lot easier to use and particularly through the convenient mode attribute (which will enforce minification when set to 'production' automatically now).

Takeaways

Overall, Parcel's a fantastic choice for small projects since it requires zero configuration.

Webpack 4 represents a great improvement in the tradition of a tried and true workhorse. It's also largely interchangeable with Webpack 3 configuration which simplifies migration.

The big winner is Rollup which represents the next generation of build tools in terms of its performance (build time), intermediate configuration (less complicated than Webpack but more involved than Parcel), and optional but out-of-the-box features likes source maps, and not using a .babelrc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment