Search code examples
javascriptjquerywebpackrequirejs

Extend an application with webpack like requireJs


Existing App: My application is using require.js. Benefit of my application is that other people can extend my application via writing 3rd party plugins using require.js

For example: (a 3rd party plugin registration) // registering a new plugin { url:'#new-page-url', js:'plugin-folder/new-page-url.js' } So when #new-page-url is hit anywhere, requirejs consumes js file from plugin-folder/new-page-url.js

Please note that after I compile my application, it does not include third party source as they can be fetched on the fly with requriejs

Question: I have been looking into webpack and since it compiles everything before distribution (bundle.js as starting file).How can a third party plugin work on the fly like above example ?


Solution

  • Please note that after I compile my application, it does not include third party source as they can be fetched on the fly with requriejs

    Yes, that's the problem.

    I'm in a situation similar to yours where a large application of mine written as a collection of AMD modules can load editing modes at runtime, which are also AMD modules. The modes are not generally bundled with the application.

    AFAIK it is not possible to replicate only with Webpack the possibility of doing the equivalent of a RequireJS' require([a]) where a is a variable whose value cannot be known at build time but is determined at run time. (And for the benefit of readers who may not be familiar with RequireJS, I'll add that yes, I do mean the first argument to be [a] and not just a. RequireJS makes a distinction between the two.)

    Webpack needs to know at build time which modules it is going to bundle together. ("Needs to know" means it needs to know the name and find the module's source.) So it does not support dynamically loading modules that only get to be known at runtime. If you read the documentation, or tutorial, you'll run into discussions of dynamic loading with Webpack but these do not allow doing the equivalent of the require([a]) case. Webpack can split a bundle into chunks and load chunks as needed but for this to work, Webpack still needs to know ahead of time the whole set of modules it is ever going to need. This does not allow loading at runtime a module that was unknown at build time. There's also require.context, but while it allows you to determine at run time which specific module you want, the set from which the module comes is determined at build time. If at build time you know that you're going to be using one of A, B, C, that's fine. But if you don't know at build time the name of your module, or cannot feed its source to Webpack, you're out of luck.

    This being said, it should be possible to build your application's core with Webpack and have this core perform direct calls to a module loader like RequireJS or SystemJS. This is the direction I'm moving into with my own application but I've not crossed that bridge yet.