Slide 1

Slide 1 text

From require.js to webpack

Slide 2

Slide 2 text

Why are you here? • Currently using webpack? • Currently using require.js? • Currently using browserify? • Not yet using any of these technologies?

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

AMD is great define([‘jquery’], function($) { $.get(‘/parties’).then(party); });

Slide 5

Slide 5 text

AMD is okay define([‘jquery’, ‘lodash’], function($, _) { $.get(‘/parties’).then(_.filter(onlyNiceParties)).then(party); });

Slide 6

Slide 6 text

THIS ALWAYS HAPPENS define([ ‘jquery’, ‘lodash’, ‘friends’, ‘chips’, ‘uber’, ‘music’, ‘records’, ’pillow’, ‘aGift’ ], function($, _, drinks, friends, cars, music, records, pillow, aGift) { $.get(‘/parties’).then(_.filter(party, goodOnes); });

Slide 7

Slide 7 text

browserify almost perfect

Slide 8

Slide 8 text

It didn't make sense to rewrite our entire app

Slide 9

Slide 9 text

webpack Just Worked • Moved build system over in a few hours • Supported all of AMD syntax without changing anything • Shims and aliases ported over without any headache • Build time was significantly shorter

Slide 10

Slide 10 text

Let me walk you through it...

Slide 11

Slide 11 text

Create a webpack.config.js file > touch webpack.config.js > vim webpack.config.js

Slide 12

Slide 12 text

Where does your code live? { resolve: { modulesDirectories: ["public/js"] // "baseUrl" } }

Slide 13

Slide 13 text

Migrate custom paths // require.js paths paths: { backbone: "lib/backbone-1.1.0", jquery: "lib/jquery-1.10.2", underscore: "lib/lodash.underscore-2.3.0", jqueryUI: "lib/jquery-ui.min" }

Slide 14

Slide 14 text

Paths become webpack aliases resolve: { alias: { backbone: "lib/backbone-1.1.0", jquery: "lib/jquery-1.10.2", underscore: "lib/lodash.underscore-2.3.0", jqueryUI: "lib/jquery-ui.min" } }

Slide 15

Slide 15 text

Migrate shims // require.js shim config shim: { "lib/jquery-1.10.2": { exports: "$" }, "lib/backbone-1.1.0": { deps: ["underscore", "jquery"], exports: "Backbone" } }

Slide 16

Slide 16 text

Backbone shim (webpack) loaders: [{ test: /backbone-1.1.0/, loaders: [ "imports?jquery,underscore", "exports?Backbone" ] }] Note: Many other shim examples can be found in the weppack wiki3 3 https:/ /github.com/webpack/docs/wiki/shimming-modules

Slide 17

Slide 17 text

Almost complete { modules: { loaders: [ /* shims, etc. */ ], }, resolve: { alias: { /* paths, etc. */ }, modulesDirectories: ["public/js"], } }

Slide 18

Slide 18 text

Preparing the Build { entry: "public/js/app.js", output: { path: "./public/js", filename: "[name].built.js" }, devtool: "source-map" }

Slide 19

Slide 19 text

// webpack.config.js module.exports = { entry: "./public/js/app.js", output: { path: "./public/js", filename: "[name].built.js" }, devtool: "source-map", modules: { loaders: [ /* shims, etc. */ ], }, resolve: { alias: { /* paths, etc. */ }, modulesDirectories: ["public/js"], } }

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

Update your Script tag Just replace the src and data-main: - +

Slide 22

Slide 22 text

!

Slide 23

Slide 23 text

Why do I want this? 1. Start using CJS syntax 2. Easy to add ES6 support 3. Let NPM manage your depdencies 4. Huge collection of plugins 5. Excellent debugging

Slide 24

Slide 24 text

1. Start adding CommonJS modules

Slide 25

Slide 25 text

Remember this? define([ ‘jquery’, ‘lodash’, ‘friends’, ‘chips’, ‘uber’, ‘music’, ‘records’, ’pillow’, ‘aGift’ ], function($, _, drinks, friends, cars, music, records, pillow, aGift) { $.get(‘/parties’).then(_.filter(party, goodOnes); });

Slide 26

Slide 26 text

var $ = require("jquery"); module.exports = function() { $("body").html("This looks ways better!"); }

Slide 27

Slide 27 text

It just works

Slide 28

Slide 28 text

2. Easy to add ES6 support

Slide 29

Slide 29 text

// webpack.config.js loaders: [{ test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" }] // .babelrc { presets: ["es2015"] }

Slide 30

Slide 30 text

// imports import $ from "jquery"; // template literals const text = ` multi-line strings are the best `; // export, let and arrow functions export let squares = [1, 2, 3].map(x => x * x);

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

3. Let NPM manage dependencies

Slide 33

Slide 33 text

Update Config resolve: { alias: { - backbone: "lib/backbone-1.1.0", - jquery: "lib/jquery-1.10.2", - underscore: "lib/lodash.underscore-2.3.0", jqueryUI: "lib/jquery-ui.min" }, - modulesDirectories: ["public/js"] + modulesDirectories: ["public/js", "node_modules"] }

Slide 34

Slide 34 text

Install NPM Modules > npm install backbone jquery underscore • Easy to get updates to your libraries • Discourages re-inventing the wheel • Encourages sharing/modularity

Slide 35

Slide 35 text

NPM is the information superhighway of JavaScript

Slide 36

Slide 36 text

4. Piles of cool plugins // webpack.config.js loaders: [{ // test: /\.js$/, // exclude: /node_modules/, // loader: "babel-loader" }, { test: /\.js$/, loader: "eslint-loader", exclude: /node_modules/ }]

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

5. Excellent Debugging

Slide 40

Slide 40 text

webpack --display-modules

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

webpack --display-modules --verbose

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

Why the hate?

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

Tips to not hate webpack

Slide 50

Slide 50 text

Use a Config Validator

Slide 51

Slide 51 text

Get to Know Source Maps

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

Remember This • keep your config as simple as possible • avoid writing webpack-specific code • no need to get rid of gulp/grunt

Slide 55

Slide 55 text

Thank You @xjamundx

Slide 56

Slide 56 text

Appendix

Slide 57

Slide 57 text

webpack 2 • Coming soon • Adds "tree shaking" which will optimize ES6 modules • Replaces require.ensure() with System.import() syntax for dynamically requiring modules • Some changes to loader and resolve config

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

No content

Slide 60

Slide 60 text

Async Requires // async require with known path works great require(["templates/a"], function(view) { // this will work }) // async require with a variable path has problem require(["templates/" + template], function(myFile) { // this will bundle all the things })

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

Smaller Dynamic Bundles switch (template) { case "a": require("templates/a", showView); break; case "b": require("templates/b", showView); break; // ... }

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

This one is 100x smaller!