Skip to content

Instantly share code, notes, and snippets.

@DBosley
Forked from xjamundx/blog-webpack-2.md
Created April 27, 2017 16:09
Show Gist options
  • Save DBosley/65b2983b300f1ec108bd43585c1adeba to your computer and use it in GitHub Desktop.
Save DBosley/65b2983b300f1ec108bd43585c1adeba to your computer and use it in GitHub Desktop.

Revisions

  1. @xjamundx xjamundx revised this gist Jul 10, 2015. 1 changed file with 1 addition and 8 deletions.
    9 changes: 1 addition & 8 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -117,15 +117,8 @@ A few things to note:
    1. The `test` is a regular expression which matches against the *full file path*, so be careful to be specific!
    2. In order to use these loaders you need to install them `npm install exports-loader imports-loader`

    `*` Yes, both of these libraries provide AMD versions now, but when we started using them with require.js they did not.

    More Info:

    - http://requirejs.org/docs/api.html#config-shim
    - http://webpack.github.io/docs/shimming-modules.html
    - http://webpack.github.io/docs/using-loaders.html
    - https://github.com/webpack/imports-loader
    - https://github.com/webpack/exports-loader
    Pretty much all of the common use cases you might bump into are covered in the [webpack guide to shimming modules](http://webpack.github.io/docs/shimming-modules.html).

    #### The Fun Part: NPM

  2. @xjamundx xjamundx revised this gist Jul 10, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -274,7 +274,7 @@ This is a goldmine of information. Which modules took up the most space? How did

    When we first started this process we noticed moment.js was pulling in 900kb of files. In the minified output it was still around 100kb. After poking around a bit we came across this stackoverflow article: [How to prevent Moment.js from Loading Locales with Webpack](http://stackoverflow.com/questions/25384360/how-to-prevent-moment-js-from-loading-locales-with-webpack).

    In short, becuase you're now in a CJS module system, Moment.js thinks it's safe to load all of its locale information. How should it know you're targetting someone's Windows XP box? Thankfully there's a webpack plugin that will strip out those extra requests prety easily.
    Becuase you're now in a CommonJS environment Moment thinks it's safe to load all of its locale information. How should it know you're targetting someone's Windows XP box? Thankfully there's a webpack plugin that will strip out those extra requests prety easily.

    ```js
    {
  3. @xjamundx xjamundx revised this gist Jul 10, 2015. 1 changed file with 3 additions and 48 deletions.
    51 changes: 3 additions & 48 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -262,54 +262,9 @@ Run webpack with that flag and you'll see:
    2. How much space it's taking up
    2. The filename and module format that included it

    Here is some sample output from a recent build:
    ```
    ~/dev/sample-app (master) $ webpack --display-reasons --display-modules
    Hash: 7b470fa455efe1fa9722
    Version: webpack 1.9.12
    Time: 3667ms
    Asset Size Chunks Chunk Names
    app.js 1.74 MB 0 [emitted] app
    1.1.js 35.1 kB 1 [emitted]
    2.2.js 970 kB 2 [emitted]
    outlook.js 856 kB 3 [emitted] outlook
    [0] ./entry/toaster.js 2.13 kB {3} [built]
    [16] ./router.js 2.13 kB {0} [built]
    cjs require router [0] ./app.es6 17:14-31
    [17] ./view/global.js 2.55 kB {0} [built]
    cjs require view/global [16] ./router.js 5:21-43
    [18] ./lib/neff.js 602 bytes {0} [built]
    cjs require neff [0] ./app.es6 33:12-27
    cjs require neff [17] ./view/global.js 7:11-26
    cjs require neff [119] ./view/header.es6 27:12-27
    amd require neff [131] ./widgets/sessionTimer.js 25:0-152:2
    amd require neff [134] ./widgets/ajaxError.js 25:0-185:2
    [23] ./constants.js 769 bytes {0} [built]
    cjs require constants [16] ./router.js 7:16-36
    [24] ./routes/transfer.js 3.12 kB {0} [built]
    cjs require routes/transfer [16] ./router.js 8:20-46
    [25] ./routes/helper.js 3.68 kB {0} [built]
    cjs require routes/helper [24] ./routes/transfer.js 4:21-45
    [26] ./widgets/theoverpanel.js 10 kB {0} [built]
    cjs require widgets/theoverpanel [25] ./routes/helper.js 7:20-51
    cjs require widgets/theoverpanel [69] ./view/transfer/layouts.es6 100:27-58
    amd require widgets/theoverpanel [102] ./widgets/addressDropdown.js 1:0-130:2
    amd require widgets/theoverpanel [131] ./widgets/sessionTimer.js 25:0-152:2
    amd require widgets/theoverpanel [134] ./widgets/ajaxError.js 25:0-185:2
    [27] /Users/jamuferguson/dev/paypal/p2pnodeweb/~/jquery/dist/jquery.js 284 kB {0} {3} [built]
    cjs require jquery [0] ./app.es6 7:14-31
    cjs require jquery [9] /Users/jamuferguson/dev/paypal/p2pnodeweb/~/forklifter/dist/ajax.js 16:14-31
    cjs require jquery [11] /Users/jamuferguson/dev/paypal/p2pnodeweb/~/forklifter/dist/renderer.js 9:8-25
    amd require jquery [12] ./components/consumerweb-client-error-logger/error.js 4:0-57:2
    amd require jquery [14] /Users/jamuferguson/dev/paypal/p2pnodeweb/~/backbone/backbone.js 17:4-21:6
    cjs require jquery [16] ./router.js 3:8-25
    amd require jquery [19] ./components/component-search/spotlight.js 1:0-201:2
    amd require jquery [21] ./components/component-search/spotlightSuggestionsView.js 1:0-91:2
    cjs require jquery [24] ./routes/transfer.js 3:8-25
    cjs require jquery [25] ./routes/helper.js 3:8-25
    cjs require jquery [26] ./widgets/theoverpanel.js 8:8-25
    ...
    ```
    Here is the partial output from a recent build:

    ![reasons](https://cldup.com/NoxK1aPvp1-3000x3000.png)

    This is a goldmine of information. Which modules took up the most space? How did that get included in this bundle? All answered with this information!

  4. @xjamundx xjamundx revised this gist Jul 10, 2015. 1 changed file with 4 additions and 6 deletions.
    10 changes: 4 additions & 6 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -75,13 +75,11 @@ More info:

    #### A Loader for Every Shim

    The next thing, which took some special care, was fixing up our shim config. This was slightly harder than it looked, because it's easy to forget what the shim's are actually doing. Let's revist that for a moment.
    The next thing, which took some special care, was fixing up our shim config. This was slightly harder than it looked, because it's easy to forget what the shim's are actually doing. Let's revisit that for a moment.

    Per the require.js docs shims let you:
    A require.js shim takes modules that are not AMD-compatible and makes them AMD comptible by wrapping them in a little bit of code which will pull in the appropriate dependencies.

    > Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value.
    Basically they take modules that are not AMD-compatible and make them AMD comptible by wrapping them in a little bit of code which will pull in the appropriate dependencies. Let'e examine exactly what's happening with part of our old require.js `shim` config.
    Let'e examine exactly how that works with the follow simple example:

    ```js
    {
    @@ -114,7 +112,7 @@ Let's see how we would get the same setup using webpack loaders:
    }
    ```

    Not too hard, but a few thing to note:
    A few things to note:

    1. The `test` is a regular expression which matches against the *full file path*, so be careful to be specific!
    2. In order to use these loaders you need to install them `npm install exports-loader imports-loader`
  5. @xjamundx xjamundx revised this gist Jul 10, 2015. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -138,8 +138,8 @@ will work out of the box without any special loaders or `alias`ing.

    That's the magic of webpack.

    If you get your dependencies from NPM you don't need any of that. They will *just work* and you can go on building great apps, *not*
    spending time carefully maintaining each dependency in your config files. Let NPM manage that for you!
    If you get your dependencies from NPM you don't need any of that. They will *just work* and you can go on building great apps *not*
    spending time carefully maintaining each dependency in your config files.

    To add support for NPM to webpack, just make sure this is included in your webpack config:

  6. @xjamundx xjamundx revised this gist Jul 10, 2015. 1 changed file with 1 addition and 19 deletions.
    20 changes: 1 addition & 19 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -355,22 +355,4 @@ To add minification all you need to do is add this config:

    Webpack has been great to work with and I think the whole team basically loves it now. I hope this little guide helps your team avoid the hurldes we ran into. If you need any help feel free to leave a note or checkout the [excellent webpack chat room on gitter](https://gitter.im/webpack/webpack).

    All the best!

    #### Addendum

    ##### Require.js to Webpack Thesaurus

    Webpack and require.js have a lot of similar concepts, but sometimes they don't use the same words to explain them. I'll do my best in this table to provide equivalent definitions.

    | Require.js Version | Webpack Version |
    |---|---|
    | [plugin](http://requirejs.org/docs/plugins.html) | [loader](http://webpack.github.io/docs/loaders.html) |
    | `require.config()` or [config.js](http://requirejs.org/docs/api.html#config) | webpack.config.js |
    | `paths` config | `alias` config |
    | `shim` config | [expose/export loaders](http://webpack.github.io/docs/shimming-modules.html) |
    | [r.js](https://github.com/jrburke/r.js/) | [webpack](http://webpack.github.io/) |
    | `define([])` | `module.exports` |
    | `require(['abc'])` | `require('abc')` |
    | `require([viewName])` | use with caution |
    | `modules` | `entry` |
    -- Jamund
  7. @xjamundx xjamundx revised this gist Jul 10, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -335,7 +335,7 @@ In short, becuase you're now in a CJS module system, Moment.js thinks it's safe

    These can cause your builds to appear huge. They are great and can really help with debugging, but make sure you know what you're doing with them and make sure you're not counting them against your total bundle size. Most browsers only download these if the developer console is open, so they don't affect your customers.

    However a few caveats if you use `eval` or `eval-source-map` the source-maps are bundled directly into your JS, so make sure not to use those styles of source maps in your production build.
    However, if you set your source-map type to `eval` or `eval-source-map` the source-maps are bundled directly into your JS. Do not use this type of source map in your production build.

    More info here: http://webpack.github.io/docs/configuration.html#devtool

  8. @xjamundx xjamundx revised this gist Jul 10, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -321,7 +321,7 @@ This is a goldmine of information. Which modules took up the most space? How did

    When we first started this process we noticed moment.js was pulling in 900kb of files. In the minified output it was still around 100kb. After poking around a bit we came across this stackoverflow article: [How to prevent Moment.js from Loading Locales with Webpack](http://stackoverflow.com/questions/25384360/how-to-prevent-moment-js-from-loading-locales-with-webpack).

    In short, becuase you're now in a CJS module system, Moment.js thinks it's safe to load all of its locale information. How should it know you're targetting someone's Windows XP box? Anyway, thankfully there's a webpack plugin that will handle that pretty easily.
    In short, becuase you're now in a CJS module system, Moment.js thinks it's safe to load all of its locale information. How should it know you're targetting someone's Windows XP box? Thankfully there's a webpack plugin that will strip out those extra requests prety easily.

    ```js
    {
  9. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -315,7 +315,7 @@ outlook.js 856 kB 3 [emitted] outlook

    This is a goldmine of information. Which modules took up the most space? How did that get included in this bundle? All answered with this information!

    By default all of the files in NPM are excluded from the output. If you want to add that simply add the `--display-modules` flag to your query (as above) and now you can see exactly every file that requires `jquery` (`node_modules` is shortened to `~`). It's pretty awesome and it helped us find a little issue with moment.js.
    **Note:** By default all of the files in NPM are excluded from the output. If you want to add that simply add the `--display-modules` flag to your query (as above) and now you can see exactly every file that requires `jquery` (`node_modules` is shortened to `~`). It's pretty awesome and it helped us find a little issue with moment.js.

    #### Moment.js and the Ignore Plugin

  10. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -239,7 +239,7 @@ I recommend reading [Pete Hunt's excellent webpack how-to on the subject of asyn

    ### The trouble with our CDN

    One of the last things that got us was our CDN. Everything worked fine in local development mode, but when we got to our live testing environments we noticed that it was trying to pull additional bundles off of the webserver by default and not the CDN where our JS was being pulled down from. require.js handles this automatically by parsing the URL from the `<script>` on the page. Webpack is less magic. If you have a non-standard place where you want it to pull down additional dynamic bundles you need to tell it:
    One of the last things that got us was our CDN. Everything worked fine in local development mode, but when we got to our live testing environments we noticed that it was trying to pull additional bundles off of the webserver by default and not the CDN where our JS actually lives in production. require.js handles this automatically by parsing the URL from the `<script>` on the page. Webpack doesn't have this magic. If you have a non-standard place where you want it to pull down additional dynamic bundles you need to tell it:

    ```
    __webpack_public_path__ = document.body.getAttribute('data-js-path') + '/apps/';
  11. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -185,7 +185,7 @@ At first my instict was to replace this with the webpack [entry](http://webpack.

    There is another approach that worked better for us:

    - Using async `require()` to create split points in your application and let webpack create the bundles automatically. I'll go into that in just a minute, but first a look at some code.
    - Using async `require()` to create split points in our app and then letting webpack create the bundles automatically.

    #### The Routing Code: Old and New

  12. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -185,7 +185,7 @@ At first my instict was to replace this with the webpack [entry](http://webpack.

    There is another approach that worked better for us:

    Use async `require()` to create split points in your application and let webpack create the bundles automatically. I'll go into that in just a minute, but first a look at some code.
    - Using async `require()` to create split points in your application and let webpack create the bundles automatically. I'll go into that in just a minute, but first a look at some code.

    #### The Routing Code: Old and New

  13. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -157,7 +157,7 @@ The heart of our app is this fancy router. When a new route comes in we would dy

    This was by far the most challenging piece, mostly because my misunderstanding of how different the splitting/bundling technique is between webpack and require.js.

    `*` This has changed somewhat recently...
    `*` This has changed for us somewhat recently, but hopefully the lesson will still be valuable for you!

    #### Goodbye Manual Splitting

  14. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -99,7 +99,7 @@ Basically they take modules that are not AMD-compatible and make them AMD compti
    Here we are applying shims for both [underscore](http://underscorejs.org/) and [backbone](http://backbonejs.org/)*. For underscore the shim will wrap the library and then return the value of the `_` variable for any scripts using it as a dependency. The backbone case is slightly more complicated:

    1. It wraps the library and exports the value of the `Backbone` variable.
    2. It makes sure that when evaluated backbone has access to both jquery and underscore
    2. It makes sure that when evaluated backbone has access to both `jquery` and `underscore`

    Let's see how we would get the same setup using webpack loaders:

  15. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -66,7 +66,7 @@ module.exports = {
    }
    ```

    This is an easy way to get started, but quickly you'll realize that there's even something better: pulling down dependencies directly from NPM.
    Hey that was pretty easy!

    More info:
    - http://requirejs.org/docs/api.html#config-paths
  16. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 6 additions and 2 deletions.
    8 changes: 6 additions & 2 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,12 @@
    This is the follow up to a post I wrote recently called From [Require.js to Webpack - Party 1 (the why)](http://j-query.blogspot.com/2015/06/from-requirejs-to-webpack-part-1-reasons.html) which was published in [my personal blog](http://www.jamund.com).

    In that post I talked about 3 main reasons for moving from rquire.js to webpack: Common JS support, NPM support and a healthy loader/plugin ecosystem. Here I'll instead talk about some of the technical challenges that we faced from moving from our old build system to another one. Despite the clear benefits in developer experience (DX) the setup was fairly difficult and I'd like to cover some of the challanges we faced to make the transition a bit easier.
    In that post I talked about 3 main reasons for moving from require.js to webpack:

    I'm going to break this up into small chunks for easier consumption.
    1. Common JS support
    2. NPM support
    3. a healthy loader/plugin ecosystem.

    Here I'll instead talk about some of the technical challenges that we faced during the migration. Despite the clear benefits in developer experience (DX) the setup was fairly difficult and I'd like to cover some of the challanges we faced to make the transition a bit easier.

    ### From `paths` to `alias` to NPM

  17. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -115,7 +115,7 @@ Not too hard, but a few thing to note:
    1. The `test` is a regular expression which matches against the *full file path*, so be careful to be specific!
    2. In order to use these loaders you need to install them `npm install exports-loader imports-loader`

    * Yes, both of these libraries provide AMD versions now, but when we started using them with require.js they did not.
    `*` Yes, both of these libraries provide AMD versions now, but when we started using them with require.js they did not.

    More Info:

  18. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -58,7 +58,7 @@ module.exports = {
    "underscore": "lib/lodash.underscore-2.3.0",
    "jqueryUI": "lib/jquery-ui.min"
    }
    }
    }
    }
    ```

  19. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -349,7 +349,9 @@ To add minification all you need to do is add this config:

    ### Conclusion

    At this point you're probably sick of reading about webpack. Hopefully I've been able to answer some of your questions and you can avoid some of the trouble we ran into during this migration. Like I said, webpack has been great to work with and I think the whole team basically loves it now. I hope you have the same experience!
    Webpack has been great to work with and I think the whole team basically loves it now. I hope this little guide helps your team avoid the hurldes we ran into. If you need any help feel free to leave a note or checkout the [excellent webpack chat room on gitter](https://gitter.im/webpack/webpack).

    All the best!

    #### Addendum

  20. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 7 additions and 4 deletions.
    11 changes: 7 additions & 4 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -149,8 +149,12 @@ To add support for NPM to webpack, just make sure this is included in your webpa

    ### Migrating the Router

    The heart of our app is this fancy router. When a new route comes in we would dynamically pull in the view associated with that path, instantiate it and re-render the main app view with the new page. It works pretty well. The main nav and everything are part of the main app, but each tab in the navbar had its own separate JS bundle and we'd only pull that in on an as-needed basis`*`.

    This was by far the most challenging piece, mostly because my misunderstanding of how different the splitting/bundling technique is between webpack and require.js.

    `*` This has changed somewhat recently...

    #### Goodbye Manual Splitting

    So we've talked a lot about our require.js config. Now we're going to talk about our r.js config. All of the special information needed to create our r.js build. Here's the bulk of it:
    @@ -177,7 +181,7 @@ At first my instict was to replace this with the webpack [entry](http://webpack.

    There is another approach that worked better for us:

    Use `require.ensure()` or to create split points in your application and let webpack create the bundles automatically. We'll call this approach async require and we'll get into it now.
    Use async `require()` to create split points in your application and let webpack create the bundles automatically. I'll go into that in just a minute, but first a look at some code.

    #### The Routing Code: Old and New

    @@ -190,11 +194,10 @@ function handleRouteChange(path) {
    });
    }
    ```
    When a new route came in we would dynamically pull in the view associated with that path, instantiate it and re-render the main app view with the new page. It was pretty great. It was simple and it worked well. The main nav and everything were part of the main app, but each tab in the navbar had its own separate JS bundle and we'd only pull that in on an as-needed basis.

    The first thing I tried to do when moving this to webpack was just leaving it. It seemed to work! The problem is that it only created a single bundle _for all of the views_. This means a signicantly larger payload for the browser.

    Here's the actual webpack solution:
    Here's our improved webpack solution:

    ```js
    function loadPage(PageView) {
    @@ -217,7 +220,7 @@ function handleRouteChange(path) {
    }
    ```

    The key is defining the split points carefully. Each time you use the AMD-style `require([])` or `require.ensure()` webpack will see what you passed in there and go and create a bundle with every possible match. That works great if you pass in a single file, but when you use a variable, it might end up bundling up your entire view folder. That's why you need to use something like a `switch` statement to make sure that you declare your split points on a route-by-route basis.
    Each time you use the AMD-style `require([])` or `require.ensure()` webpack will see what you passed in there and go and create a bundle with every possible match. That works great if you pass in a single file, but when you use a variable, it might end up bundling up your entire view folder. That's why you need to use something like a `switch` statement to make sure that you declare your split points on a route-by-route basis.

    You should probably grumble about this a bit, but just remember because you do this you don't need any `module` or `entry` logic in your config. It will create all the bundles you need automatically, mostly automatically anyway :)

  21. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 2 additions and 4 deletions.
    6 changes: 2 additions & 4 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -363,7 +363,5 @@ Webpack and require.js have a lot of similar concepts, but sometimes they don't
    | [r.js](https://github.com/jrburke/r.js/) | [webpack](http://webpack.github.io/) |
    | `define([])` | `module.exports` |
    | `require(['abc'])` | `require('abc')` |
    | `require([viewName])` | `require.ensure(viewName)`* |
    | `modules` | `entries` |

    * Dynamic requires are slightly more complicated in webpack, but I like that they're much more explicit. See above for more info.
    | `require([viewName])` | use with caution |
    | `modules` | `entry` |
  22. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -348,9 +348,9 @@ To add minification all you need to do is add this config:

    At this point you're probably sick of reading about webpack. Hopefully I've been able to answer some of your questions and you can avoid some of the trouble we ran into during this migration. Like I said, webpack has been great to work with and I think the whole team basically loves it now. I hope you have the same experience!

    ### Addendum
    #### Addendum

    #### Require.js to Webpack Thesaurus
    ##### Require.js to Webpack Thesaurus

    Webpack and require.js have a lot of similar concepts, but sometimes they don't use the same words to explain them. I'll do my best in this table to provide equivalent definitions.

  23. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -20,7 +20,7 @@ The first thing you need to do is tell webpack where your JS files are. Require.

    This is super easy to setup in webpack by adding the following to your config:

    ```
    ```js
    {
    resolve: {
    modulesDirectories: ['public/js']
    @@ -145,6 +145,7 @@ To add support for NPM to webpack, just make sure this is included in your webpa
    modulesDirectories: ['public/js', 'node_modules']
    }
    }
    ```

    ### Migrating the Router

  24. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 38 additions and 2 deletions.
    40 changes: 38 additions & 2 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -8,12 +8,27 @@ I'm going to break this up into small chunks for easier consumption.

    The first thing you do when you're converting from require.js to webpack is you take your whole require.js configuration file and convert it to a `webpack.config.js` file.

    In practice for us this meant addressing two main areas:
    In practice for us this meant addressing three areas:

    1. Tell webpack where you keep your JS files
    1. The enormous `paths` list in our require.js config
    2. All of the `shim` config

    I'll address both, but in case you want to hear the spoiler the solution to both is generally `npm`.
    #### Module Path Resolution

    The first thing you need to do is tell webpack where your JS files are. Require.js could usually infer this based on the `<script>` tag you used to set it up or you might have configured it using the `baseUrl` option.

    This is super easy to setup in webpack by adding the following to your config:

    ```
    {
    resolve: {
    modulesDirectories: ['public/js']
    }
    }
    ```

    If you forget to set this webpack will probably assume `node_modules`.

    #### Migrating Require.js `paths` to webpack `alias`

    @@ -110,6 +125,27 @@ More Info:
    - https://github.com/webpack/imports-loader
    - https://github.com/webpack/exports-loader

    #### The Fun Part: NPM

    So now that you've migrated all of your `shim` and `paths` config, let me suggest something: **delete it**.

    Now go to NPM and install `underscore`, `jquery`, `backbone`, `react`. Whatever else you're using is probably there and probably
    will work out of the box without any special loaders or `alias`ing.

    That's the magic of webpack.

    If you get your dependencies from NPM you don't need any of that. They will *just work* and you can go on building great apps, *not*
    spending time carefully maintaining each dependency in your config files. Let NPM manage that for you!

    To add support for NPM to webpack, just make sure this is included in your webpack config:

    ```js
    {
    resolve: {
    modulesDirectories: ['public/js', 'node_modules']
    }
    }

    ### Migrating the Router

    This was by far the most challenging piece, mostly because my misunderstanding of how different the splitting/bundling technique is between webpack and require.js.
  25. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -180,7 +180,9 @@ function handleRouteChange(path) {
    }
    ```

    The key is defining the split points carefully. Each time you use the AMD-style `require([])` or `require.ensure()` webpack will see what you passed in there and go and create a bundle with every possible match. That works great if you pass in a single file, but when you use a variable, it might end up bundling up your entire view folder. So be careful.
    The key is defining the split points carefully. Each time you use the AMD-style `require([])` or `require.ensure()` webpack will see what you passed in there and go and create a bundle with every possible match. That works great if you pass in a single file, but when you use a variable, it might end up bundling up your entire view folder. That's why you need to use something like a `switch` statement to make sure that you declare your split points on a route-by-route basis.

    You should probably grumble about this a bit, but just remember because you do this you don't need any `module` or `entry` logic in your config. It will create all the bundles you need automatically, mostly automatically anyway :)

    #### Entry or Async Require

  26. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 130 additions and 17 deletions.
    147 changes: 130 additions & 17 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -38,11 +38,12 @@ And it translates very straightforwardly into a webpack config of the following:
    module.exports = {
    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"
    }
    "backbone": "lib/backbone-1.1.0",
    "jquery": "lib/jquery-1.10.2",
    "underscore": "lib/lodash.underscore-2.3.0",
    "jqueryUI": "lib/jquery-ui.min"
    }
    }
    }
    ```

    @@ -76,7 +77,6 @@ Basically they take modules that are not AMD-compatible and make them AMD compti
    }
    }
    ```
    Here we are applying shims for both [underscore](http://underscorejs.org/) and [backbone](http://backbonejs.org/)*. For underscore the shim will wrap the library and then return the value of the `_` variable for any scripts using it as a dependency. The backbone case is slightly more complicated:

    1. It wraps the library and exports the value of the `Backbone` variable.
    @@ -97,7 +97,7 @@ Let's see how we would get the same setup using webpack loaders:

    Not too hard, but a few thing to note:

    1. The `test` is a regular expression which matches against the full file path, so be careful to be specific!
    1. The `test` is a regular expression which matches against the *full file path*, so be careful to be specific!
    2. In order to use these loaders you need to install them `npm install exports-loader imports-loader`

    * Yes, both of these libraries provide AMD versions now, but when we started using them with require.js they did not.
    @@ -110,10 +110,87 @@ More Info:
    - https://github.com/webpack/imports-loader
    - https://github.com/webpack/exports-loader

    ### Migrating the router
    ### Migrating the Router

    This was by far the most challenging piece, mostly because my misunderstanding of how different the splitting/bundling technique is between webpack and require.js.

    #### Goodbye Manual Splitting

    So we've talked a lot about our require.js config. Now we're going to talk about our r.js config. All of the special information needed to create our r.js build. Here's the bulk of it:

    ```js
    {
    baseUrl: 'public/js',
    mainConfigFile: 'public/js/config.js',
    dir: '.build/js',
    modules: [
    { name: 'config' },
    { name: 'view/summary/index', exclude: ['config'] },
    { name: 'view/activity/index', exclude: ['config'] },
    { name: 'view/transfer/index', exclude: ['config'] },
    { name: 'view/wallet/index', exclude: ['config'] },
    { name: 'view/settings/index', exclude: ['config'] },
    ]
    }
    ```

    The bulk of this file was concerned with all of the different bundles we were making. With webpack that all goes away (mostly).

    At first my instict was to replace this with the webpack [entry](http://webpack.github.io/docs/configuration.html#entry) concept. I spent *a lot* of time going down the wrong path worrying about entries.

    There is another approach that worked better for us:

    Use `require.ensure()` or to create split points in your application and let webpack create the bundles automatically. We'll call this approach async require and we'll get into it now.

    #### The Routing Code: Old and New

    Here is the gist of the old require.js code:

    ```js
    function handleRouteChange(path) {
    require(['/views/' + path], function(PageView) {
    app.setView(new PageView());
    });
    }
    ```
    When a new route came in we would dynamically pull in the view associated with that path, instantiate it and re-render the main app view with the new page. It was pretty great. It was simple and it worked well. The main nav and everything were part of the main app, but each tab in the navbar had its own separate JS bundle and we'd only pull that in on an as-needed basis.

    The first thing I tried to do when moving this to webpack was just leaving it. It seemed to work! The problem is that it only created a single bundle _for all of the views_. This means a signicantly larger payload for the browser.

    Here's the actual webpack solution:

    ```js
    function loadPage(PageView) {
    app.setView(new PageView());
    }
    function handleRouteChange(path) {
    switch (path) {
    case 'settings':
    require(['/views/settings'], loadPage);
    break;
    case 'transfer':
    require(['/views/transfer'], loadPage);
    break;
    case 'wallet':
    require(['/views/wallet'], loadPage);
    break;
    default:
    // you could either require everything here as a last resort or just leave it...
    }
    }
    ```

    The key is defining the split points carefully. Each time you use the AMD-style `require([])` or `require.ensure()` webpack will see what you passed in there and go and create a bundle with every possible match. That works great if you pass in a single file, but when you use a variable, it might end up bundling up your entire view folder. So be careful.

    #### Entry or Async Require

    Let me do my best to explain when you want an `entry` and when you want to rely on webpack to do the splitting for you:

    1. Use an `entry` if you want to include a new `<script>` tag in a page.
    2. Use `require.ensure()` or another form of async require if you want webpack to dynamically pull in additional modules.

    I recommend reading [Pete Hunt's excellent webpack how-to on the subject of async loading](https://github.com/petehunt/webpack-howto#9-async-loading) for more information.

    ### The trouble with our CDN

    One of the last things that got us was our CDN. Everything worked fine in local development mode, but when we got to our live testing environments we noticed that it was trying to pull additional bundles off of the webserver by default and not the CDN where our JS was being pulled down from. require.js handles this automatically by parsing the URL from the `<script>` on the page. Webpack is less magic. If you have a non-standard place where you want it to pull down additional dynamic bundles you need to tell it:
    @@ -138,12 +215,12 @@ At this point we were pretty excited about everything, now that it was basically
    Run webpack with that flag and you'll see:

    1. Every module that was added to your bundle
    2. What file refered it
    3. The module format of the parent file
    2. How much space it's taking up
    2. The filename and module format that included it

    Here is some sample output from a recent build:
    ```
    ~/dev/sample-app (master) $ webpack --display-reasons
    ~/dev/sample-app (master) $ webpack --display-reasons --display-modules
    Hash: 7b470fa455efe1fa9722
    Version: webpack 1.9.12
    Time: 3667ms
    @@ -175,15 +252,30 @@ outlook.js 856 kB 3 [emitted] outlook
    amd require widgets/theoverpanel [102] ./widgets/addressDropdown.js 1:0-130:2
    amd require widgets/theoverpanel [131] ./widgets/sessionTimer.js 25:0-152:2
    amd require widgets/theoverpanel [134] ./widgets/ajaxError.js 25:0-185:2
    [27] /Users/jamuferguson/dev/paypal/p2pnodeweb/~/jquery/dist/jquery.js 284 kB {0} {3} [built]
    cjs require jquery [0] ./app.es6 7:14-31
    cjs require jquery [9] /Users/jamuferguson/dev/paypal/p2pnodeweb/~/forklifter/dist/ajax.js 16:14-31
    cjs require jquery [11] /Users/jamuferguson/dev/paypal/p2pnodeweb/~/forklifter/dist/renderer.js 9:8-25
    amd require jquery [12] ./components/consumerweb-client-error-logger/error.js 4:0-57:2
    amd require jquery [14] /Users/jamuferguson/dev/paypal/p2pnodeweb/~/backbone/backbone.js 17:4-21:6
    cjs require jquery [16] ./router.js 3:8-25
    amd require jquery [19] ./components/component-search/spotlight.js 1:0-201:2
    amd require jquery [21] ./components/component-search/spotlightSuggestionsView.js 1:0-91:2
    cjs require jquery [24] ./routes/transfer.js 3:8-25
    cjs require jquery [25] ./routes/helper.js 3:8-25
    cjs require jquery [26] ./widgets/theoverpanel.js 8:8-25
    ...
    ```

    This is a goldmine of information. Which modules took up the most space? How did that get included in this bundle? All answered with this information!

    By default all of the files in NPM are excluded from the output. If you want to add that simply add the `--display-modules` flag to your query and now you can see exactly every file that requires `jquery`. It's pretty awesome and it helped us find a little issue with moment.js.
    By default all of the files in NPM are excluded from the output. If you want to add that simply add the `--display-modules` flag to your query (as above) and now you can see exactly every file that requires `jquery` (`node_modules` is shortened to `~`). It's pretty awesome and it helped us find a little issue with moment.js.

    #### Moment.js and the Ignore Plugin

    One piece of advice for people using moment.js.
    When we first started this process we noticed moment.js was pulling in 900kb of files. In the minified output it was still around 100kb. After poking around a bit we came across this stackoverflow article: [How to prevent Moment.js from Loading Locales with Webpack](http://stackoverflow.com/questions/25384360/how-to-prevent-moment-js-from-loading-locales-with-webpack).

    In short, becuase you're now in a CJS module system, Moment.js thinks it's safe to load all of its locale information. How should it know you're targetting someone's Windows XP box? Anyway, thankfully there's a webpack plugin that will handle that pretty easily.

    ```js
    {
    @@ -193,13 +285,33 @@ One piece of advice for people using moment.js.
    }
    ```

    With the all of this our file size was very similar to the size of our require.js bundle and the build time went from over `50s` to under `10s`.
    #### Source maps

    These can cause your builds to appear huge. They are great and can really help with debugging, but make sure you know what you're doing with them and make sure you're not counting them. Most browsers only download these if the developer console is open, so they don't affect your customers.
    These can cause your builds to appear huge. They are great and can really help with debugging, but make sure you know what you're doing with them and make sure you're not counting them against your total bundle size. Most browsers only download these if the developer console is open, so they don't affect your customers.

    However a few caveats if you use `eval` or `eval-source-map` the source-maps are bundled directly into your JS, so make sure not to use those styles of source maps in your production build.

    More info here: http://webpack.github.io/docs/configuration.html#devtool

    #### Minification

    To add minification all you need to do is add this config:

    ```js
    {
    plugins: [
    new webpack.optimize.UglifyJsPlugin({minimize: true})
    ]
    }
    ```

    ### Conclusion

    At this point you're probably sick of reading about webpack. Hopefully I've been able to answer some of your questions and you can avoid some of the trouble we ran into during this migration. Like I said, webpack has been great to work with and I think the whole team basically loves it now. I hope you have the same experience!

    ### Addendum

    ### Require.js to Webpack Thesaurus
    #### Require.js to Webpack Thesaurus

    Webpack and require.js have a lot of similar concepts, but sometimes they don't use the same words to explain them. I'll do my best in this table to provide equivalent definitions.

    @@ -213,5 +325,6 @@ Webpack and require.js have a lot of similar concepts, but sometimes they don't
    | `define([])` | `module.exports` |
    | `require(['abc'])` | `require('abc')` |
    | `require([viewName])` | `require.ensure(viewName)`* |
    | `modules` | `entries` |

    * Dynamic requires are slightly more complicated in webpack, but I like that they're much more explicit. See above for more info.
  27. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 8 additions and 4 deletions.
    12 changes: 8 additions & 4 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -131,7 +131,7 @@ If we'd used webpack to handle our total build process we could let webpack appl
    At this point we were pretty excited about everything, now that it was basically all working, but we noticed that the file sizes were a bit higher, maybe even *a lot* higher than our old require.js builds.
    ### Enter Display Reasons
    #### Enter Display Reasons
    `webpack --display-reasons` is the most helpful things ever.
    @@ -177,11 +177,11 @@ outlook.js 856 kB 3 [emitted] outlook
    amd require widgets/theoverpanel [134] ./widgets/ajaxError.js 25:0-185:2
    ```
    ### Source maps
    This is a goldmine of information. Which modules took up the most space? How did that get included in this bundle? All answered with this information!
    These can cause your builds to appear huge. They are great and can really help with debugging, but make sure you know what you're doing with them and make sure you're not counting them. Most browsers only download these if the developer console is open, so they don't affect your customers.
    By default all of the files in NPM are excluded from the output. If you want to add that simply add the `--display-modules` flag to your query and now you can see exactly every file that requires `jquery`. It's pretty awesome and it helped us find a little issue with moment.js.
    ### Moment.js and the Ignore Plugin
    #### Moment.js and the Ignore Plugin
    One piece of advice for people using moment.js.
    @@ -195,6 +195,10 @@ One piece of advice for people using moment.js.
    With the all of this our file size was very similar to the size of our require.js bundle and the build time went from over `50s` to under `10s`.
    #### Source maps
    These can cause your builds to appear huge. They are great and can really help with debugging, but make sure you know what you're doing with them and make sure you're not counting them. Most browsers only download these if the developer console is open, so they don't affect your customers.
    ### Require.js to Webpack Thesaurus
    Webpack and require.js have a lot of similar concepts, but sometimes they don't use the same words to explain them. I'll do my best in this table to provide equivalent definitions.
  28. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 4 additions and 3 deletions.
    7 changes: 4 additions & 3 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -84,7 +84,7 @@ Here we are applying shims for both [underscore](http://underscorejs.org/) and [
    Let's see how we would get the same setup using webpack loaders:
    ``js
    ```js
    {
    module: {
    loaders: [
    @@ -141,8 +141,9 @@ Run webpack with that flag and you'll see:
    2. What file refered it
    3. The module format of the parent file
    Here is some sample output from a recent build:
    ```
    ~/dev/paypal/p2pnodeweb (xb-demo) $ webpack --display-reasons
    ~/dev/sample-app (master) $ webpack --display-reasons
    Hash: 7b470fa455efe1fa9722
    Version: webpack 1.9.12
    Time: 3667ms
    @@ -151,7 +152,7 @@ Time: 3667ms
    1.1.js 35.1 kB 1 [emitted]
    2.2.js 970 kB 2 [emitted]
    outlook.js 856 kB 3 [emitted] outlook
    [0] ./entry/outlook.js 2.13 kB {3} [built]
    [0] ./entry/toaster.js 2.13 kB {3} [built]
    [16] ./router.js 2.13 kB {0} [built]
    cjs require router [0] ./app.es6 17:14-31
    [17] ./view/global.js 2.55 kB {0} [built]
  29. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 172 additions and 1 deletion.
    173 changes: 172 additions & 1 deletion blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -4,6 +4,112 @@ In that post I talked about 3 main reasons for moving from rquire.js to webpack:

    I'm going to break this up into small chunks for easier consumption.

    ### From `paths` to `alias` to NPM

    The first thing you do when you're converting from require.js to webpack is you take your whole require.js configuration file and convert it to a `webpack.config.js` file.

    In practice for us this meant addressing two main areas:

    1. The enormous `paths` list in our require.js config
    2. All of the `shim` config

    I'll address both, but in case you want to hear the spoiler the solution to both is generally `npm`.

    #### Migrating Require.js `paths` to webpack `alias`

    Initially the conversion process is really straight forward.

    Start with a config like this:

    ```js
    requirejs.config({
    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"
    }
    });
    ```

    And it translates very straightforwardly into a webpack config of the following:

    ```js
    module.exports = {
    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"
    }
    }
    ```
    This is an easy way to get started, but quickly you'll realize that there's even something better: pulling down dependencies directly from NPM.
    More info:
    - http://requirejs.org/docs/api.html#config-paths
    - http://webpack.github.io/docs/configuration.html#resolve-alias
    #### A Loader for Every Shim
    The next thing, which took some special care, was fixing up our shim config. This was slightly harder than it looked, because it's easy to forget what the shim's are actually doing. Let's revist that for a moment.
    Per the require.js docs shims let you:
    > Configure the dependencies, exports, and custom initialization for older, traditional "browser globals" scripts that do not use define() to declare the dependencies and set a module value.
    Basically they take modules that are not AMD-compatible and make them AMD comptible by wrapping them in a little bit of code which will pull in the appropriate dependencies. Let'e examine exactly what's happening with part of our old require.js `shim` config.
    ```js
    {
    shim: {
    "underscore": {
    exports: "_"
    },
    "backbone": {
    deps: ["jquery", "underscore"],
    exports: "Backbone"
    }
    }
    }
    ```
    Here we are applying shims for both [underscore](http://underscorejs.org/) and [backbone](http://backbonejs.org/)*. For underscore the shim will wrap the library and then return the value of the `_` variable for any scripts using it as a dependency. The backbone case is slightly more complicated:
    1. It wraps the library and exports the value of the `Backbone` variable.
    2. It makes sure that when evaluated backbone has access to both jquery and underscore
    Let's see how we would get the same setup using webpack loaders:
    ``js
    {
    module: {
    loaders: [
    { test: /underscore/, loader: 'exports?_' }
    { test: /backbone/, loader: 'exports?Backbone!imports?underscore,jquery' }
    ]
    }
    }
    ```

    Not too hard, but a few thing to note:

    1. The `test` is a regular expression which matches against the full file path, so be careful to be specific!
    2. In order to use these loaders you need to install them `npm install exports-loader imports-loader`

    * Yes, both of these libraries provide AMD versions now, but when we started using them with require.js they did not.

    More Info:

    - http://requirejs.org/docs/api.html#config-shim
    - http://webpack.github.io/docs/shimming-modules.html
    - http://webpack.github.io/docs/using-loaders.html
    - https://github.com/webpack/imports-loader
    - https://github.com/webpack/exports-loader

    ### Migrating the router

    This was by far the most challenging piece, mostly because my misunderstanding of how different the splitting/bundling technique is between webpack and require.js.
    @@ -21,7 +127,72 @@ https://github.com/webpack/docs/wiki/configuration#outputpublicpath

    If we'd used webpack to handle our total build process we could let webpack apply the hash automatically, but since we're still only using it for our JS build, we need to handle this programmatically. Probably one of my least favorite things about the setup. Not terribly hard, just hard to remember and definitely threw us for a pretty big loop.

    ###
    ### Build Size & Time

    At this point we were pretty excited about everything, now that it was basically all working, but we noticed that the file sizes were a bit higher, maybe even *a lot* higher than our old require.js builds.

    ### Enter Display Reasons

    `webpack --display-reasons` is the most helpful things ever.

    Run webpack with that flag and you'll see:
    1. Every module that was added to your bundle
    2. What file refered it
    3. The module format of the parent file
    ```
    ~/dev/paypal/p2pnodeweb (xb-demo) $ webpack --display-reasons
    Hash: 7b470fa455efe1fa9722
    Version: webpack 1.9.12
    Time: 3667ms
    Asset Size Chunks Chunk Names
    app.js 1.74 MB 0 [emitted] app
    1.1.js 35.1 kB 1 [emitted]
    2.2.js 970 kB 2 [emitted]
    outlook.js 856 kB 3 [emitted] outlook
    [0] ./entry/outlook.js 2.13 kB {3} [built]
    [16] ./router.js 2.13 kB {0} [built]
    cjs require router [0] ./app.es6 17:14-31
    [17] ./view/global.js 2.55 kB {0} [built]
    cjs require view/global [16] ./router.js 5:21-43
    [18] ./lib/neff.js 602 bytes {0} [built]
    cjs require neff [0] ./app.es6 33:12-27
    cjs require neff [17] ./view/global.js 7:11-26
    cjs require neff [119] ./view/header.es6 27:12-27
    amd require neff [131] ./widgets/sessionTimer.js 25:0-152:2
    amd require neff [134] ./widgets/ajaxError.js 25:0-185:2
    [23] ./constants.js 769 bytes {0} [built]
    cjs require constants [16] ./router.js 7:16-36
    [24] ./routes/transfer.js 3.12 kB {0} [built]
    cjs require routes/transfer [16] ./router.js 8:20-46
    [25] ./routes/helper.js 3.68 kB {0} [built]
    cjs require routes/helper [24] ./routes/transfer.js 4:21-45
    [26] ./widgets/theoverpanel.js 10 kB {0} [built]
    cjs require widgets/theoverpanel [25] ./routes/helper.js 7:20-51
    cjs require widgets/theoverpanel [69] ./view/transfer/layouts.es6 100:27-58
    amd require widgets/theoverpanel [102] ./widgets/addressDropdown.js 1:0-130:2
    amd require widgets/theoverpanel [131] ./widgets/sessionTimer.js 25:0-152:2
    amd require widgets/theoverpanel [134] ./widgets/ajaxError.js 25:0-185:2
    ```
    ### Source maps
    These can cause your builds to appear huge. They are great and can really help with debugging, but make sure you know what you're doing with them and make sure you're not counting them. Most browsers only download these if the developer console is open, so they don't affect your customers.

    ### Moment.js and the Ignore Plugin

    One piece of advice for people using moment.js.

    ```js
    {
    plugins: [
    new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/]), // saves ~100k from build
    ]
    }
    ```

    With the all of this our file size was very similar to the size of our require.js bundle and the build time went from over `50s` to under `10s`.

    ### Require.js to Webpack Thesaurus

  30. @xjamundx xjamundx revised this gist Jul 9, 2015. 1 changed file with 19 additions and 0 deletions.
    19 changes: 19 additions & 0 deletions blog-webpack-2.md
    Original file line number Diff line number Diff line change
    @@ -4,6 +4,25 @@ In that post I talked about 3 main reasons for moving from rquire.js to webpack:

    I'm going to break this up into small chunks for easier consumption.

    ### Migrating the router

    This was by far the most challenging piece, mostly because my misunderstanding of how different the splitting/bundling technique is between webpack and require.js.

    ### The trouble with our CDN

    One of the last things that got us was our CDN. Everything worked fine in local development mode, but when we got to our live testing environments we noticed that it was trying to pull additional bundles off of the webserver by default and not the CDN where our JS was being pulled down from. require.js handles this automatically by parsing the URL from the `<script>` on the page. Webpack is less magic. If you have a non-standard place where you want it to pull down additional dynamic bundles you need to tell it:

    ```
    __webpack_public_path__ = document.body.getAttribute('data-js-path') + '/apps/';
    ```

    More info can be found here:
    https://github.com/webpack/docs/wiki/configuration#outputpublicpath

    If we'd used webpack to handle our total build process we could let webpack apply the hash automatically, but since we're still only using it for our JS build, we need to handle this programmatically. Probably one of my least favorite things about the setup. Not terribly hard, just hard to remember and definitely threw us for a pretty big loop.

    ###

    ### Require.js to Webpack Thesaurus

    Webpack and require.js have a lot of similar concepts, but sometimes they don't use the same words to explain them. I'll do my best in this table to provide equivalent definitions.