This is the follow up to a post I wrote recently called From Require.js to Webpack - Party 1 (the why) which was published in my personal blog.
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.
I'm going to break this up into small chunks for easier consumption.
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.
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.
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 | loader |
require.config() or config.js |
webpack.config.js |
paths config |
alias config |
shim config |
expose/export loaders |
| r.js | webpack |
define([]) |
module.exports |
require(['abc']) |
require('abc') |
require([viewName]) |
require.ensure(viewName)* |
- Dynamic requires are slightly more complicated in webpack, but I like that they're much more explicit. See above for more info.