You've run into a limitation of RequireJS's support for the CommonJS syntax. Here's the deal. When RequireJS defines a module, it looks at the factory function (the callback) you gave to define
. It looks for this pattern:
/[^.]s*requires*(s*["']([^'"s]+)["']s*)/g
This matches require
calls like var foo = require('foo');
For each such call, it adds the required module to the list of dependencies of your module. So, for instance, something like:
// The `require` parameter must be present and is filled with something useful
// by RequireJS.
define(function (require) {
var foo = require('foo');
var bar = require('bar');
...
});
Is treated like this:
define(['require', 'foo', 'bar'], function (require) {
var foo = require('foo');
var bar = require('bar');
...
});
If you look carefully at the regular expression above, you'll see it will match only require
calls that have a single parameter which is a literal string. So things like require("something" + somevar)
won't work. RequireJS completely ignores them when doing this transformation.
The issue would not be fixable by changing the regular expression. RequireJS is at its heart a system for loading modules asynchronously. The form of the require
call with a single string literal is sugar to allow porting more easily modules designed according to the CommonJS pattern, and for those who prefer this style (even if they are not porting anything). This type of call looks synchronous without actually being synchronous. To support cases where the name passed to it is computed, RequireJS would have to predict what the value would be.
If you want to have complete freedom to load whatever module you want in your code without knowing ahead of time what the name may be, then you have to use an asynchronous require
call (require([computed_value], function(mod) {...})
) which means your code must be asynchronous. If you have a limited set of modules you want to load and it is acceptable to always load them all, then you could require them all with literal strings:
define(function (require) {
require("filters/isAdmin");
require("filters/b");
require("filters/c");
require("filters/d");
...
});
RequireJS would do the transformation above and further require
calls using computed values that resolve to one of the names you required early in your module would not fail.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…