<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andrew Walpole</title>
    <description>The latest articles on DEV Community by Andrew Walpole (@walpolea).</description>
    <link>https://dev.to/walpolea</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4614%2F04fefdad-fee4-43a3-b730-59e465d2f125.jpg</url>
      <title>DEV Community: Andrew Walpole</title>
      <link>https://dev.to/walpolea</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/walpolea"/>
    <language>en</language>
    <item>
      <title>Through the pipeline: An exploration of front-end bundlers</title>
      <dc:creator>Andrew Walpole</dc:creator>
      <pubDate>Sat, 13 Feb 2021 06:46:36 +0000</pubDate>
      <link>https://dev.to/walpolea/through-the-pipeline-an-exploration-of-front-end-bundlers-ea1</link>
      <guid>https://dev.to/walpolea/through-the-pipeline-an-exploration-of-front-end-bundlers-ea1</guid>
      <description>&lt;p&gt;This last week I spent a lot of time buried deep in the documentation of parcel, rollup, and esbuild. I've been on a quest. Mainly one that starts from a place of being fed up with webpack being slow and unwieldy to configure and manage. And I've been hearing and even playing around with these other bundlers a bit, well enough to know a happier path should exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  My bundling needs
&lt;/h2&gt;

&lt;p&gt;Let me lay out my specific need, because it is specific enough that no bundler was giving me everything I needed out of the box. And this is a good time to preface my forthcoming feedback with the notion that in playing with parcel, rollup, and esbuild, they ALL are wonderful, easy to quick-start bundlers if your use-case fits their default model or even handful of command-line argument options they provide.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I'm building and bundling &lt;code&gt;.js&lt;/code&gt; and &lt;code&gt;.scss&lt;/code&gt; files for Wordpress theme development.&lt;/li&gt;
&lt;li&gt;I need it to handle multiple main entry points (four that eventually turned into two):

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;js/main.js&lt;/code&gt; – is the front-end site entry point for javascript&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;css/style.scss&lt;/code&gt; – is the front-end site entry point for css styles&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;js/editor.js&lt;/code&gt; – is Gutenberg-specific javascript (not often used, but handy when you need it!)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;css/editor.scss&lt;/code&gt; – you guessed it, another Gutenberg-specific set of css for occasional visual block and block editor tweaks.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;These four entry files should bundle into to four build files: &lt;code&gt;build/main.min.js&lt;/code&gt;, &lt;code&gt;build/main.min.css&lt;/code&gt;, &lt;code&gt;build/editor.min.js&lt;/code&gt;, and &lt;code&gt;build/editor.min.css&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;While developing, I want any imported dependency &lt;code&gt;.js&lt;/code&gt; and &lt;code&gt;.scss&lt;/code&gt; file changes to trigger a rebuild and I want all those files plus &lt;code&gt;.php&lt;/code&gt; file changes to trigger livereload in the browser.&lt;/li&gt;
&lt;li&gt;I need to be able to install, import, and bundle 3rd party libraries via &lt;code&gt;npm&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;I need it to be faster than webpack has been (around 5-10 second development build times)&lt;/li&gt;
&lt;li&gt;Finally, I need all the usual good stuff: minification, sourcemaps, transpilation, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ok, so that lays out what I was looking for, and hopefully is priming googlebot for sending you here in the first place. From here on out, I'm going to get a lot terser, and jump directly to my pros, cons, and learning moments with each of the bundlers I checked out.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://parceljs.org/"&gt;Parcel&lt;/a&gt; 1.x (and a little bit of 2.x)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pros:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I started with parcel, I've used it in other (more modern stack) projects and it really does often just work, with minimal to no configuration.&lt;/li&gt;
&lt;li&gt;It's pretty fast and has a very pleasant set of command-line and node API configuration options that are well documented.&lt;/li&gt;
&lt;li&gt;It felt a bit awkward at first, but I ended up being fine with the &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;1.x is no longer being actively developed, in favor of 2.x (in beta as of this writing), and while there's a good ecosystem here, a handful of paths end in finding an old Github issue with something like, "this is not currently possible in parcel 1.x, but will be available in parcel 2.0"&lt;/li&gt;
&lt;li&gt;Assets, like fonts and images referenced in your css get bundled into your build directory automatically. I did not find a solution to stop this from happening.&lt;/li&gt;
&lt;li&gt;I ended my journey with 1.x when I found that changing css files was causing js files to stop working until I resaved them, still a big mystery as to what was going on.&lt;/li&gt;
&lt;li&gt;Also, in using multiple entry points, the editor build files always got a hash in the filename even when trying to turn it off, while the front-end files worked perfectly.&lt;/li&gt;
&lt;li&gt;I tried out 2.x for a bit in hopes to find solutions, but while promising to be more capable and extendable, I found many of the new features to be tough to use, and the documentation to be hard to follow.&lt;/li&gt;
&lt;li&gt;My 2.x journey ended when &lt;a href="https://twitter.com/walpolea/status/1359895036641509379"&gt;I took to tweeting&lt;/a&gt; at the creator for some guidance, only to find the thing I was trying to do was not possible. (I was trying to create a plugin to remove the hashing issue from the editor filenames, but it turns out you can't use a plugin without publishing it to something like npm, which I had no interest in doing.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Learnings:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I'm certain that I will reach for parcel for other projects, especially with the &lt;code&gt;parcel-bundler&lt;/code&gt; node API knowledge I got, I think it's a great API to tap into.&lt;/li&gt;
&lt;li&gt;It felt a bit awkward at first, but I did eventually give in to importing my scss into my respective js files, as that feature seems to be common across bundlers. This cut my entry points down from four to two, and now I was only dealing with javascript entry points.&lt;/li&gt;
&lt;li&gt;Here's my parcel build script before I moved on:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Bundler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parcel-bundler&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//entry files&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./js/main.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./js/editor.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;baseOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;outDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./build&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;minify&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;sourceMaps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;--watch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;publicUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;logLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;contentHash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bundler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Bundler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;baseOptions&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bundler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bundle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;a href="https://rollupjs.org/"&gt;Rollup.js&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I felt a bit defeated, but remained positive that I might find the answers in rollup!&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Similarly to parcel, rollup has a nice command-line and node API interface that I was able to get up and running with quickly.&lt;/li&gt;
&lt;li&gt;The core features are a bit limited, but it makes up for it with many available plugins that are easy to install and use.&lt;/li&gt;
&lt;li&gt;I was able to get rollup to do everything I wanted, but the build times started to stack up.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;My biggest con is how long it did take me to get to where I had everything I wanted working. I sifted through github issues and google searches for far too long.&lt;/li&gt;
&lt;li&gt;In the end, I decided to move on from rollup because I wasn't seeing a huge gain in bundling speed over webpack and it was a few seconds slower than I had gotten with parcel.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Learnings
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I'll let my &lt;code&gt;rollup.config.js&lt;/code&gt; do the talking:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// rollup.config.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rollup-plugin-node-resolve&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;commonJS&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rollup-plugin-commonjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;scss&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rollup-plugin-scss&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;babel&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@rollup/plugin-babel&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;terser&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rollup-plugin-terser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;livereload&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rollup-plugin-livereload&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fg&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fast-glob&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;//custom watching plugin to get rollup to rebuild when other files get changed&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;watcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;watch-external&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;buildStart&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fg&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;assets/js/**/*.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;assets/css/**/*.scss&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;**/*.php&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addWatchFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;//setup the plugins for both builds&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;plugins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nx"&gt;watcher&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//my custom file watcher&lt;/span&gt;
  &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;//related to resolving node_module references, I think.&lt;/span&gt;
  &lt;span class="nx"&gt;commonJS&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="c1"&gt;//this allowed things like: import jquery from 'jquery' to work&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node_modules/**&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="nx"&gt;babel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;babelHelpers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bundled&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="c1"&gt;//transpile!&lt;/span&gt;
  &lt;span class="nx"&gt;scss&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;outputStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;compressed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="c1"&gt;//minified scss&lt;/span&gt;
  &lt;span class="nx"&gt;terser&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;//for minifcation&lt;/span&gt;
  &lt;span class="nx"&gt;livereload&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;//for livereload&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;//notice, two entry points here, handled like a champ!&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;js/main.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//the style.scss is imported in this file&lt;/span&gt;
    &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build/main.min.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;iife&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//immediately invoked function expression - browser solution&lt;/span&gt;
      &lt;span class="na"&gt;inlineDynamicImports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;js/editor.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;//the editor scss is imported in this file, also&lt;/span&gt;
    &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build/editor.min.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;iife&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;inlineDynamicImports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;a href="https://esbuild.github.io/"&gt;esbuild&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;While rollup worked fine, I've been hearing about the new kid on the block, esbuild, and its ridiculous build times, so it was time to dive in.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Yet again, good documentation, good command-line and node experiences here.&lt;/li&gt;
&lt;li&gt;HOLY CATS, THIS THING SCREAMS! 150ms folks! From 8-10 seconds to 150ms! I honestly thought it was broken, but there they were, my build files were pristine.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;With multiple entry points, I had to concede being able to name the build files specifically. I had found workarounds in rollup for this, but I seem to be out of luck with esbuild. So instead of &lt;code&gt;build/main.min.js&lt;/code&gt; I'm left with just &lt;code&gt;build/main.js&lt;/code&gt;. I can deal.&lt;/li&gt;
&lt;li&gt;esbuild is young, and while it's working well, the ecosystem around it is a bit scrappy feeling. I have a hunch that had I not just done prior battle with parcel and rollup, I may have been scared off by esbuild at first glance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Learnings
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;esbuild just (like 12 days ago) got a &lt;code&gt;watchFiles&lt;/code&gt; flag, and it works, but it doesn't seem to let you watch files outside of the entry points&lt;/li&gt;
&lt;li&gt;I was able to cobble together &lt;code&gt;chokidar&lt;/code&gt; and &lt;code&gt;browserSync&lt;/code&gt; to create the watching and livereload solution I wanted.&lt;/li&gt;
&lt;li&gt;Here's my final esbuild build script:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//esbuilder.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;esbuild&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;esbuild&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sassPlugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;esbuild-plugin-sass&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chokidar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chokidar&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;browserSync&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;browser-sync&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Building...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;esbuild&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timerStart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Build code&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;js/main.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;js/editor.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;iife&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;bundle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;minify&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;outdir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;build/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sassPlugin&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
      &lt;span class="na"&gt;sourcemap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="c1"&gt;//this stops esbuild from trying to resolve these things in css, may need to add more types&lt;/span&gt;
      &lt;span class="na"&gt;external&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*.woff&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*.jpg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;*.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timerEnd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Done! Built in &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;timerEnd&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;timerStart&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ms.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;//watch it?&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;--watch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//chokidar will watch theme files for changes to trigger rebuild&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;watcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chokidar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;js/**/*.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;css/**/*.scss&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;**/*.php&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Watching files... &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;//first build&lt;/span&gt;
  &lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;//build on changes&lt;/span&gt;
  &lt;span class="nx"&gt;watcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;change&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;//browserSync will trigger livereload when build files are updated&lt;/span&gt;
  &lt;span class="nx"&gt;browserSync&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;init&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;//TODO: make these values passed in by `npm run dev`&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3334&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;localhost:3333&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;assets/build/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//no watch flag, just build it and be done&lt;/span&gt;
  &lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Bonus! &lt;a href="https://github.com/rsms/estrella"&gt;estrella&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Estrella is somewhat of a wrapper around esbuild. And while I found esbuild pretty easy to work with, estrella cranks up the simplicity-factor to 11. I liked working with estrella, and I think if you're interested in esbuild but are finding it a bit intimidating, it could be the starting point you need!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The conclusion is that I enjoyed learning about all of these bundlers, they work well, and under much less specific circumstances, all would do pretty well as a bundler choice. In the end, the speed of esbuild is significant enough that it truly changes the development experience in a way that maybe we weren't complaining about before, but might begin to in the future now that we know what's possible.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>bundlers</category>
      <category>frontend</category>
      <category>buildtools</category>
    </item>
    <item>
      <title>The Future of Computation is Robust</title>
      <dc:creator>Andrew Walpole</dc:creator>
      <pubDate>Mon, 20 May 2019 20:42:23 +0000</pubDate>
      <link>https://dev.to/walpolea/the-future-of-computation-is-robust-1pp6</link>
      <guid>https://dev.to/walpolea/the-future-of-computation-is-robust-1pp6</guid>
      <description>&lt;p&gt;Most of the progress made in computer science and technology stands on the platform of correctness and efficiency. Correctness, hardware and software determinism; the idea that if we want to live in a digital world, the hardware can’t fail, the software can’t fail. No bugs in the hardware. Period. And when there’s a bug in the code, fix it quick, or you might as well scrap it all. Efficiency; go faster, do more, squeeze out every single trivial compute cycle. And we adorn you with adulation for being the elite among us.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EbfQgLSE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AZikCx06GriXViN1WB8JfOw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EbfQgLSE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AZikCx06GriXViN1WB8JfOw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Centralized processing — the CPU — necessary to manage and maintain correctness; computation only happens with the perfect linear path of execution, and we make sure it’s efficient. Random-access memory, the ability to organize information with teleportation — incredibly efficient.&lt;/p&gt;

&lt;p&gt;But today, Moore’s law is straining under the weight of its own progress, hardware is pushed to the very limits of material science, making it more fragile than ever, software still has bugs, and the security repercussions of the entire system is having increasingly devastating consequences on our socio-economic world. And yet, we still want to go faster, do more.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The history here is rich and complex, so excuse me for leaving any semblance of that out, but getting to the point is important, and if need be, digging into the details later is not a fruitless effort, I encourage it. I, myself, need to do more of it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This architectural foundation was established long ago, and it was quick to deliver in capability and growth. So much so, that many stopped questioning it. But in not questioning it, we miss the opportunity to ask if there’s another way to compute. And there is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--j3LcKEHy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ACEicKYAy1JPgT7FEb7cyCA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--j3LcKEHy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ACEicKYAy1JPgT7FEb7cyCA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  There’s an uncharted world of computer science and we’ve found a door to it.
&lt;/h3&gt;

&lt;p&gt;A place where centralized processing doesn’t exist. It’s replaced with distributed processing that removes the bottle-neck and allows for indefinite hardware and software scalability. This alone is a concept that unlocks a path worthy of traveling down. It’s a place with no concept of RAM. Instead, it’s much like our own physical world — spatially architected — limiting (from the perspective of efficiency), but importantly so. A centralized manager of process execution is replaced by distributed, randomly-executing actors, that compute by way of cause and effect. And if their cause doesn’t affect, perhaps they just try again; their best-effort actions working together to achieve a localized computational goal. A world where bugs are constant, and yet it does little to stifle progress and execution. Where hardware can blow up, and the system perseveres.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uwpz088T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ATlUoNtohwEe95c4wuANYQA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uwpz088T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2ATlUoNtohwEe95c4wuANYQA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the world of robust-first and best-effort computing. A place where efficiency and correctness still play a role, but not &lt;strong&gt;&lt;em&gt;the&lt;/em&gt;&lt;/strong&gt; role. A place where robustness, durability, thick-skin — call it what you will — enters into the platform as a first-class concept, bringing with it incredible sturdiness to our ability to compute and to grow our technology into the future, much further and safer than ever thought possible.&lt;/p&gt;

&lt;p&gt;When you see the software that runs here, as rudimentary as it may be today, it looks much less like any construct of software you have built in your head, instead, it looks like life. And in fact, living systems principles play a major foundational role in how you make computation happen robustly in this system. For any AI enthusiasts out there, whether you’re an expert in building complex neural networks or just a fan of these concepts that you may one day hope to understand, this world feels like a step in a new direction that, in its simplicity, unlocks a door to understanding our own world and the living systems within it.&lt;/p&gt;

&lt;p&gt;There’s more — a lot more — to it all. But, this post is not a comprehensive explainer. It’s barely a teaser. And in fact, herein lies the last point, maybe the most important point to make. The answers to your questions, many of them don’t even exist yet. And so, there is an incredible opportunity for us all, one that is rare. To journey into a world of computer science that is undeclared and undocumented. A place where the simplest observations matter, where experimentation is the only work to do in order to have a chance of colonizing this new world.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zWKy9omf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AaRUKOLIQ6Z2q9OzgYX7Nog.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zWKy9omf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AaRUKOLIQ6Z2q9OzgYX7Nog.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Right now there is a small group of us, led by the person who has spent the most time in this new world, Dr. of Computer Science and Associate Professor Emeritus, David Ackley. And, perhaps like you, we’re not the most intellectually equipped to go there, but there’s something about it that we can’t stop thinking about. Like an adventure to be seized that fuels our excitement for the possible. Please consider joining us, please consider asking about possibly joining us. If any of these ideas resonate or intrigue you, you’re qualified, you’re hired, we would love to have you.&lt;/p&gt;

&lt;p&gt;So what now? The following is a link dump that can help you learn more about the Robust-First Computing movement.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We congregate in our &lt;a href="https://gitter.im/t2tile/Lobby"&gt;Gitter Chat Room&lt;/a&gt; — come say hi, ask questions!&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/channel/UC1M91QuLZfCzHjBMEKvIc-A"&gt;The T2 Tile Project&lt;/a&gt; is Dr. Ackley’s weekly vlog and journey into building an indefinitely scalable hardware platform on top of robust-first concepts. A long, but incredibly worth-while rabbit-hole.&lt;/li&gt;
&lt;li&gt;A very notable video from the T2 Tile project, affectionately known as &lt;a href="https://www.youtube.com/watch?v=z_2MHScD9rg"&gt;the Christmas rant&lt;/a&gt;, does a great job of pointing out what it is and why this new type of computing may be &lt;em&gt;very&lt;/em&gt; worthwhile from many perspectives.&lt;/li&gt;
&lt;li&gt;You can also find many useful talks diving in into the depths of the Robust-First ecosystem and concepts on his personal &lt;a href="https://www.youtube.com/user/DaveAckley/videos"&gt;Youtube Channel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A few notable starting points are, &lt;a href="https://www.youtube.com/watch?v=7hwO8Q_TyCA"&gt;Robust-First Computing: Beyond Efficiency&lt;/a&gt; and &lt;a href="https://www.youtube.com/watch?v=helScS3coAE"&gt;Demon Horde Sort&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;If you want to see what this all looks like. My biggest contribution to the project thus far has been the website, &lt;a href="https://mfm.rocks/"&gt;mfm.rocks&lt;/a&gt; which is a loosely-interpreted simulation of Dr. Ackley’s Moveable Feast Machine. It doesn’t follow all of the the rules perfectly, but is enough to show you how computation might happen in this decentralized, actor-based world. This project is open-source and I welcome &lt;a href="https://github.com/walpolea/MFM-JS/"&gt;contributions&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://robust.cs.unm.edu/doku.php"&gt;The Robust-First Wiki&lt;/a&gt; dives into the constructs of the current software and some hardware of this new architecture. It can also lead you to running the MFM on your own machine.&lt;/li&gt;
&lt;li&gt;You can find more research and links at &lt;a href="https://www.cs.unm.edu/~ackley/"&gt;Dr. Ackley’s website&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you got this far, thanks for reading. If you have any thoughts or questions, I would love to see them show up in the comments! I’ll leave you with the Robust-First Computing Team Creed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E8IwTGRS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AHlhBx5DN-2W8z5PA7jVjqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E8IwTGRS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AHlhBx5DN-2W8z5PA7jVjqw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;




</description>
      <category>robustfirst</category>
      <category>tech</category>
      <category>computation</category>
      <category>computerarchitecture</category>
    </item>
  </channel>
</rss>
