Webpack in 30 Minutes

Who's this for? 👪

  • Completely new to web development
  • XD Desktop-only engineers
  • Some experience with Node.js

Learning Goals ⚽️

  • ES Modules vs Webpack
  • Differences from XD modules
  • Introduction to Webpack concepts
  • Development workflow

You lost me at modules... 😵

<script> tag 

// https://learn.jquery.com/about-jquery/how-jquery-works/
<script src="jquery.js"></script>
<script>
// Your code goes here.
</script>
  • Creates global variable/namespace $ (a.k.a. window.jQuery)
  • Additional <script> tags are another HTTP request
  • Weak dependencies
  • Synchronous loading
  • and more...

Immediately-Invoked
Function Expression (IIFE)

var API = (function () {
  var $ = window.jQuery,
    myPrivateVar = 42,
    myAPI;
  // your code
  return myAPI;
}());
  • Doesn't pollute global namespace
  • Private variables via closure
  • Same weak dependencies as <script>

RequireJS

<!-- index.html -->
<script data-main="js/main" src="js/lib/require.js"></script>
/* js/main.js */
// http://requirejs.org/docs/jquery.html#modulename
requirejs.config({
  baseUrl: 'js/lib',
  paths: {
    jquery: 'jquery-1.9.0'
  }
});

requirejs(['yourcode']);

/* js/yourcode.js */
define(['jquery'], function(jquery) {
  // your code
});

XD require()

  • Custom implementation at sparkler-shell/js/lib/require.js
    • Module wrapper injects "global" module
  • Each file loaded at runtime, no bundling
  • Similar to Node.js modules

var Rectangle = require("Rectangle");

function BaseDecoration(decorationModel, parent) {
    this._groupRect = new Rectangle();
    this._addListeners();
}

BaseDecoration.prototype._addListeners = function () {
  // ...
};

// ...

module.exports = BaseDecoration;

ES Modules

// module-main.mjs
import sayHelloModule from "./module-sayHello.mjs";
sayHelloModule();

// module-sayHello.mjs
export default function() {
    const el = document.createElement("pre");
    el.textContent = "Hello, ES Module!";
    document.body.appendChild(el);
}

Why Webpack? 🤔

  • Webpack is a module bundler
  • Leverage Node.js and browser-centric JS libraries
  • Build configurations e.g. Debug/Release, Production/Stage
  • Optionally "chunk" modules for async loading
  • Loaders and plugins to extend functionality
  • Shim libraries (e.g. Node.js library used in-browser)

Basic Example

  • Webpack bundling vs. ES Modules at runtime
  • Network impact
  • Debug vs. Production

Loaders

  • eslint-loader to detect errors  when bundling
  • ts-loader to transpile TypeScript
  • css-loader for CSS Module Support
  • style-loader to inject <style> tag
  • file-loader resolve to a URL and emit the file

Plugins

  • html-webpack-plugin to generate HTML from template
  • compression-webpack-plugin gzip/brotli compression
  • workbox-webpack-plugin use Workbox framework to generate Service Worker code

Hot Module Replacement

  • Retain application state which is lost during a full reload.
  • Save valuable development time by only updating what's changed.
  • Instantly update the browser when modifications are made to CSS/JS in the source code, which is almost comparable to changing styles directly in the browser's dev tools.

The options are overwhelming!

  • Isolating slow-changing, 3rd party code into a vendor chunk to optimize caching
  • webpack.DefinePlugin as a "preprocessor" step
  • Single Page Application (SPA) optimizations to incrementally load JS bundles based on the URL (routing)
  • Zero-config alternative tools like rollup exist because webpack configuration can be complicated

Next Steps

  • Questions
  • After some initial setup, most engineers aren't likely to change the config
    • Similar frequency to changing XCode/CMake builds
  • Many engineers on the team with Webpack experience

Webpack in 30 minutes

By Jason San Jose

Webpack in 30 minutes

  • 120