Reputation: 789
I am using require.js to load my dependencies on a project. Something like
var deps = [];
if( some condition )
deps = [dep1, dep2, ...]
else
deps = [other1, other2, ...]
define(deps, function(arg1, arg2, ....){
});
This is working fine for me. The problem is when i have minified my code, i am getting following problem:
Uncaught Error: Mismatched anonymous define() module: function (e,t.....
Please help me out any one who knows the solution. Thanks in advance.
Upvotes: 0
Views: 2132
Reputation: 151401
RequireJS' optimizer cannot perform dependency analysis on dependencies that are generated at run time. It would at least have the capability to execute your code in a way that would mirror what happens at run time, and there would still be cases that it would not be able to handle. So for RequireJS' dependency analysis to be successful, your dependencies must be literal arrays of strings. In any other situation, RequireJS will fail to perform the analysis, and it will fail silently.
In your case, this has two consequences:
The optimizer does not actually give a name to your module. This explains the Mismatched anonymous define() module
.
One of the functions of the optimizer is to give modules their final names. So a module which you put in main.js
, for instance, when it is not yet optimized would be transformed so that it is defined as define("main", ...
. The optimizer adds the name to the start of the define
call. (It does so only if the module has not yet been named.)
How can you tell your module is not named by the optimizer? Besides the error message, which is a major clue, if you look at what r.js
produces, you'll find your module defined as define(deps,function
. Notice how the first argument of your module is not its name.
You'll also see a stub following it. The stub looks like this define("main",function(){})
. This stub should only be present if the code of the module is not an actual AMD-style module. For instance, modules for which you must use a shim
configuration would have these stubs. Your module, however, does not need this stub.
At any rate, the optimizer is completely confused and does not name your module properly.
The optimizer does not find the dependencies of your module.
mfarouk has already mentioned how to modify your build so that the second consequence above is taken care of. I'll just mention that the general rule is this: you must explicitly put in the include
for your module the union of all modules that the optimizer misses. It would look like this:
modules: [
...,
{
name: "mymodule",
include: [dependency1, dependency2, ...]
},
...
]
where dependency1
, etc. are the dependencies in your deps
array.
To take care of the first consequence, you need additional customization. I would suggest using the onBuildRead
option of the optimizer:
onBuildRead: function (moduleName, path, contents) {
if (moduleName !== "main")
return contents;
return contents.replace(/define\(deps/,
'define("' + moduleName + '",deps');
}
This function is invoked when the optimizer reads each module. When it reads main
, the define
call is modified to add the module name. The optimizer will then see that the module is already named, will leave the name alone, and won't generate a spurious stub.
Upvotes: 1
Reputation: 654
r.js will detect deps to include from the array, but if the deps are dynamic like your case , it will not be detected
for dynamic deps, you may configure the build.js file to include this the dynamic deps you will require along with your module
assume below code
main.js
var x = 1;
var deps=[];
if(x > 0){
deps = ['.\mod1'];
}
else{
deps = ['.\mod2'];
}
define(deps, function(x){
return x * 10;
});
mod1.js
define([], function(){
return 5;
});
mod2.js
define([], function(){
return 10;
});
r.js will not include mod1 and mod2 with main as they are not clear deps, so we have to instruct r.js that mod1 and mod2 are likely deps for main, we do this in build.js
build.js
({
paths: {
},
shim: {
},
baseUrl: "app",
removeCombined: true,
findNestedDependencies: true,
inlineText: true,
optimizeAllPluginResources: true,
stubModules: ['text'],
dir: "app-dist",
modules: [
{
name: "main",
include: ["mod1","mod2"]
}
]
})
by this setting, we instruct r.js to include mod1 and mod2 along with main.js
hope this was clear
Upvotes: 1