Skip to content

Instantly share code, notes, and snippets.

@johnkpaul
Last active December 15, 2015 07:59
Show Gist options
  • Save johnkpaul/5227929 to your computer and use it in GitHub Desktop.
Save johnkpaul/5227929 to your computer and use it in GitHub Desktop.
A Module Loader Question

A Module Loader Question

I want to know if I can achieve one particular goal with any particular module loader. Let me tell you a story.

My Fantasy App

I work on a large client side JavaScript application for a company with a fremium business model. Let's call it Freely. Freely's free experience is composed of modules A, B and C in the application. Once the user hands over their credit card, they enter the paid experience, which is composed of modules B-Z.

Each of modules A-Z is roughly the same size, so the free experience requires roughly 1/9th of the entire codebase in order to function correctly. I don't want the client to need to download all of the modules becuase only 1/100th of all users will actually end up paying. (The conversion rate is another issue, but at Freely, we're more focused on other things).

I want a solution where I can specify in my build process

Split this app into modules A-C and D-Z and whenever D is required, only then send D-Z over the wire.

Is there any way that I can architect this application, using whatever build tools or module loaders exist, such that my code does not have to explcitly load modules D-Z into the browser when a user completes the payment process? Whenever some code is executed that depends on module D, modules D-Z get transported over the wire.

The goal here is that the code does not know that D is packed togehter with D-Z in one request, but rather the build system/configuration has that knowledge. I want this to be flexible enough that changing these splits is completely within configuration.

@jrburke
Copy link

jrburke commented Mar 24, 2013

The paths config allows pointing many module IDs to one file. So:

require.config({
  paths: {
    'D': 'D-Z',
    'E': 'D-Z',
    ...
  }
});

Then as long as modules A,B,C do not have a define() dependency on 'D', but instead use a dynamic `require(['D'], function (D) {}) to fetch it when appropriate, things work out without having to change the module source for A,B,C.

For the build config:

modules: [
  //pass create: true if A-C.js is not a real module before the build
  { name: 'A-C', create: true, include: ['A', 'B', 'C'] },
  { name: 'D-Z', create: true, exclude: ['A-C'], include: ['D', ...] }
]

By excluding A-C layer, D-Z will exclude any modules that are built into the A-C layer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment