【问题标题】:Configuring RequireJS at runtime在运行时配置 RequireJS
【发布时间】:2015-11-25 03:06:42
【问题描述】:

是否可以在运行时修改 requirejs(或任何 AMD 加载程序)配置?

例如,我有两个日志模块:一个简单地包装 console.log,另一个记录到服务器。我希望模块只需要日志(require(['log'], function(log) { ... });)而不关心它使用的是哪个记录器。

我可以在 require 的主配置中将 'log' 设置为一个包,这可以正常工作。但我更愿意根据几个条件在 main.js 中设置此选项。比如:

if( ... ) {
    require.config({
        packages: [
            { name: 'log', location: 'app/base/utils/consolelog' }
        ]
    });
}

但这似乎不起作用。有没有办法做到这一点,或者我是否将 requirejs 的功能作为依赖注入框架?

干杯

【问题讨论】:

  • 它到底是怎么不工作的?当您删除 if 时会发生什么?应该可以在运行时像这样配置 requireJS,只要你的 require 配置在任何依赖项被拉入之前完成。

标签: javascript dependency-injection requirejs


【解决方案1】:

任何依赖注入框架的通用工具是,您有一种简单的方法来配置它将在运行时解析哪种依赖容器,并且它只构建一次并在应用程序的生命周期内保持静态。

这样做是为了避免在应用程序中的某个时刻出现依赖关系可能发生变化的情况。有这样一种想法,即您的一个或所有应用程序源可能需要在它们使用来自容器的一些或任何依赖项之前请求许可,而不是仅仅在容器上运行,这是一个糟糕的想法,它有很多缺点。主要缺点是您知道,accounts.all().each().withdraw(billing.MONTHLY_SERVICE_FEE).return() 中的任何引用都可能在任何时候无明显原因地表现不同。如果Accounts 发生变化而new Accounts().all() 没有返回任何帐户,或者billing.MONTHLY_SERVICE_FEE 突然更改并且您向一些帐户收取X 金额而向其他帐户收取Y,那就不好了。

所以,简短的回答是否定的,你不能动态配置 RequireJS。 RequireJS 将始终只加载一个模块一次,因此回调返回值始终是一个静态对象,或者如果您愿意,当您查看模块源时,您知道它是 define() 将只被评估一次文档的生命周期。

有几种非常简单的方法可以帮助您在运行时抽象出对象的特定实现。您只需创建几个带有回调的模块,这些模块返回具有相同公共接口但行为不同的对象,然后您可以静态或动态解决要返回的对象。

// core/logging/base.js
define(function() {
  var static;
  var base =  {
      _log: undefined,
      create: function(name) {},
      // ..
  }

  return base;
});

// core/logging/client.js
define(function(['core/logging/base'], function(base) {
  var client = extend(base, {_log: console.log});
  return client;
});

// core/logging.js
define(['core/logging/server', 'core/logging/client', 'core/conf/settings'], 
  function(server, client, environment) {
  if(settings.LOGGER === 'server') {
    return server;
  } else {
    return client;
  }
};

// app/foo.js
define(['core/logging'], function(logging) {
  var log = logging.createLog('foo');
  log.info('bar');
  // > INFO foo: bar
  // or...
  // POST http://server/log {type: 2, name: 'foo', message: 'bar'}
}

您可以通过多种方法来设计此类支持,但这种方法因其简单性而吸引人,并且适用于您的特定情况。通常,您可以在模块中静态执行此解析,也可以通过 getter 函数在任何块中动态执行此解析,并且模块回调本身也可以返回构造函数或函数,而不仅仅是对象。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-24
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多