3

Problem

This is how the app behaves:

  • every folder corresponds to a dynamic "feature" in the app.
  • features are independent of each other. (Inside each folder, none of the files have dependencies on other folders. However, each folder may use the same common libraries like jquery.)
  • not all features are needed all the time
  • within each folder, the files are not necessarily dependent on each other (but it makes sense to bundle them together because that's how a "feature" works)
  • the number of features is not fixed ... so a manual process where you have to manually update various configurations/files each time you add/remove a feature is NOT ideal

Desired Solution

Given what I described, what seems to make sense is to create chunks for each feature/folder and then load each chunk asynchronously (on demand) as needed by the app.

The problem is that this doesn't seem easy with webpack. I'd like to be able to do this

 require.ensure([], function() {
     var implementation = require('features/*/'+feature);
     //...

where each feature (folder) goes in one chunk. Unfortunately, if I'm understanding require.context correctly, that's not possible.

An alternative?

A possible alternative is the following:

  1. use a single config file that lists each feature (we actually already use this),
  2. use the config file to auto-generate a module that requires each folder asynchronously. (Basically, the "module" is a factory that the app can use to load each feature.)
  3. add an entry point to the auto-generated module (force the chunks to be built).

So to summarize, add a build step that generates a factory that asynchronously load features. The problem is that this seems unnecessarily complex and I'm wondering if there's an better way to implement the solution. Or am I on the wrong track? is there a completely different solution?

Code

Folder structure

 features
     sl.graded.equation
          graded.equations.js
          graded.equation.edit.js
          graded.equation.support.js
     sl.griddable
          griddable.js
          griddable.edit.js
     //...

Config file

{
   "sl.graded.equation": [ //basically lists the feature "entry points" (not every file)
    "sl.graded.equation",
    "sl.graded.equation.edit"
   ],
   "sl.griddable": [
     "sl.griddable",
     "sl.griddable.edit"
   ]
   //...
}

Auto-generated factory

module.exports = function(feature, callback) {
    switch(feature) {
        //we can get fancy and return a promise/stream
        case 'sl.graded.equation': 
           require.ensure([], function() {
                var a = require('sl.graded.equation');
                var b = require('sl.graded.equation.edit');
                callback(a,b);
            }
     //...
U Avalos
  • 6,538
  • 7
  • 48
  • 81
  • Perhaps you should have a closer look to this resource: https://github.com/webpack/webpack/tree/master/examples/multi-part-library. Unfortunately I am not sure if it's possible to nest the chunks deeper than a single level. – dotcs Sep 11 '15 at 06:02
  • @chromate so what you're suggesting is turn each feature into a library? – U Avalos Sep 11 '15 at 16:24
  • @UAvalos: Any solution in sight? I have this exact same problem in two different facets of my code base. One which is very similar to what you have above, secondarily I'd love to apply it to load 3rd party libraries on demand without relying on error-prone manual configuration. – bjornl Nov 12 '15 at 13:58
  • I ended up using a manually-generated factory. Every time, we added a feature, we added a line in the factory. It's been a while and I'm not sure if webpack has provided an alternative. – U Avalos Nov 13 '15 at 05:53

0 Answers0