Why bother with the dependency list in CommonJS require.ensure ()?

From the Webpack documentation ( https://webpack.imtqy.com/docs/api-in-modules.html#require-ensure ):

Download additional dependencies upon request. The dependency array lists the modules that should be available. When they appear, a callback is called. If the callback is an expression of a function, the dependencies in this source part are retrieved and also loaded on demand. One request is launched on the server, unless all modules are already available.

If dependencies in the source part are also retrieved and loaded on demand, then why put anything in the dependency list at all?

I saw such examples that are very confusing ( https://github.com/webpack/webpack/tree/master/examples/extra-async-chunk ):

require.ensure(["./a"], function(require) { require("./b"); require("./d"); }); 

"b" and "d" are not in the list of dependencies, but they will load on demand just like "a". So what's the difference?

+5
source share
3 answers

The example in the documents you linked shows one of the ways that the behavior is different. When you specify a dependency, it explicitly creates a new fragment, places the dependency in it, and adds any other dependencies referenced by the callback. When you do not specify a dependency, any dependencies in the callback are added to the "current" (last?) Fragment, a new fragment is not created.

+2
source

In short: you do not have to worry.

Origin of the problem

Tobias Coppers, author of Webpack, was asked a similar question on Gitter :

Raul Ferra : Is there any advantage between these two forms?

 require.ensure(['jquery','Backbone','underscore'], function(require){ var jQuery = require('jquery'), Backbone = require('Backbone'), _ = require('underscore'); }; 

and this one

 require.ensure(['jquery'], function(require){ var jQuery = require('jquery'), Backbone = require('Backbone'), _ = require('underscore'); }; 

Tobias Koppers : no difference ... even the generated source is equal. But the spec says that the dependency should be in an array.

Webpack require.ensure been implemented as proposed by CommonJS Modules / Async / A , which states:

"require.ensure" takes an array of module identifiers as the first argument and a callback function as the second argument.

The specification does not indicate whether there will be loadable asynchronously loaded modules that are not listed, but there is an example code that requires only the module specified in the array:

 require.ensure(['increment'], function(require) { var inc = require('increment').inc; var a = 1; inc(a); // 2 }); 

Thus, in my opinion, asynchronous loading of require d, but not the listed modules, is a feature of Webpack and a deviation from the specification. This feature makes the first argument meaningless in most cases and raises questions.

Use cases

1. Follow the specification

One option for using the first argument is to specify all the dependencies for clarity and specification. But this is completely optional.

2. Pull the modules into specific pieces

You have two split points in different parts of the application. The first separation point depends on the module a , the second depends on the modules a and b . To eliminate the risk of loading a twice, you can decide to place both modules in one piece:

 // First split point require.ensure(['b'], (require) => { require('a'); }); 
+1
source

The answer is in the docs:

Download additional dependencies upon request. The dependency array lists the modules that should be available. When they appear, a callback is called. If the callback is an expression of a function, the dependencies in this source part are retrieved and also loaded on demand. One request is launched on the server, unless all modules are already available.

So, if some array dependencies do not exist, then the web package will stop, not even calling the callback. But I never met a use case when it was useful, usually just passing an empty array every time

-2
source

Source: https://habr.com/ru/post/1245109/


All Articles