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:
- use a single config file that lists each feature (we actually already use this),
- use the config file to auto-generate a module that
require
s each folder asynchronously. (Basically, the "module" is a factory that the app can use to load each feature.) - 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);
}
//...