当配置依赖于RequireJS时,使用RequireJS配置模块

7

如果我在文档中漏掉了这个问题,请原谅。基本上,我想使用RequireJS模块配置功能。我想集中管理包中给模块提供的配置值。

以下是文档中的示例:

requirejs.config({
    config: {
        'bar': {
            size: 'large'
        },
        'baz': {
            color: 'blue'
        }
    }
});

//bar.js, which uses simplified CJS wrapping:
define(function (require, exports, module) {
    //Will be the value 'large'
    var size = module.config().size;
});

//baz.js which uses a dependency array,
define(['module'], function (module) {
    //Will be the value 'blue'
    var color = module.config().color;
});

我的问题是,我的配置信息会更加复杂,并且本身具有依赖关系。我希望做到:

requirejs.config({
    config: {
        'bar': {
            path: path.dirname(module.uri)
            key: crypto.randomBytes(64)
        },
    }
});

我的配置文件中的变量需要使用requireJS进行求值。

对我来说,RequireJS配置(加载模块所需的配置)和用户模块配置之间应该有一种逻辑分离。但是我目前很难找到这个分离点 :(

4个回答

6

对于这种解决方案,我会让模块依赖于一个“config”模块,您可以使用路径配置更换不同的模块。因此,如果“bar”需要一些配置,“bar.js”将如下所示:

define(['barConfig'], function (config) {
});

然后barConfig.js可以包含其他依赖项:

define(['crypto'], function (crypto) {
    return {
      key: crypto.randomBytes(64)
    }
});

如果您需要为生产环境和开发环境设置不同的配置,可以使用路径配置将barConfig映射到其他值:

requirejs.config({
  paths: {
    barConfig: 'barConfig-prod'
  }
});

2
我认为正确的做法是创建一个配置模块...
// config.js
define(['module', 'path', 'crypto'], function(module, path, crypto) {
    return {
        path: path.dirname(module.uri)
        key: crypto.randomBytes(64)
    };
}); 

然后在其他模块中使用它...
// bar.js
define(['config'], function (config) {
    var key = config.key;
});

你可以根据自己的需求将其变得更加复杂!编辑:你可以为这个特殊类污染全局命名空间...
define(['module', 'path', 'crypto'], function(module, path, crypto) {
    window.config = {
        path: path.dirname(module.uri)
        key: crypto.randomBytes(64)
    };
}); 

将其添加到顶级 require 调用中:

require(['config', 'main']);

那么您可以在不总是将其添加到定义中的情况下使用它:
// bar.js
define([], function() {
    var key = config.key;
});

是的,这就是我目前所拥有的,但这意味着我需要从每个模块中要求“config”。这也意味着我无法以集中的方式为不同的模块指定不同的配置。我真的很希望能够利用requireJS的配置功能,但也许这是不可能的。 - willcode.co
看看我的修改,如果你在各处使用某个东西,全局变量是合适的。 - Felix
啊,没错!有时候很难分辨 :p 你的解决方案只是用更复杂的方式将“config”替换为“module”。无论何处需要配置设置,你都必须在定义中使用“module”。你可以使用我的解决方案,但将“window.config = {...}”更改为“module.config = {...}”(在nodejs中,“module”实际上是全局命名空间吗?) - Felix

0

经过进一步思考,我想出了一个解决方法。虽然不是特别美观,但似乎确实可行。

我只需两次执行 requireJS(...),第一次创建配置,第二次使用配置加载应用程序模块即可。

requireJSConfig = 
    baseUrl: __dirname
    nodeRequire: require

# Create the require function with basic config
requireJS = require('requirejs').config(requireJSConfig)  
requireJS ['module', 'node.extend', 'crypto', 'path'], (module, extend, crypto, path) ->
    # Application configuration 
    appConfig =
        'bar':
            path:   path.dirname(module.uri)
            key:    crypto.randomBytes(64) # for doing cookie encryption

    # get a new requireJS function with CONFIG data
    requireJS = require('requirejs').config(extend(requireJSConfig, config: appConfig))
    requireJS ['bar'], (app) ->
        ###
            Load and start the server
        ###
        appServer = new app()

        #  And start the app on that interface (and port).
        appServer.start()

而在bar.coffee中

# bar.coffee
define ['module'], (module) ->
    # config is now available in this module
    console.log(module.config().key)

0
借鉴@jrburke的想法,我发现以下模式非常有用:在调用require.config()之前,在main.js中定义一个配置模块及其依赖项。

main.js

define('config', ['crypto'], function (crypto) {
  return {
    'bar': {
      key: crypto.randomBytes(64)
    },
  };
});

requirejs.config({
  deps: ['app'],
});

app.js

require(['config'], function (config){

  // outputs value of: crypto.bar.key
  console.log(config.bar.key);
});

Plnkr演示:http://plnkr.co/edit/I35bEgaazEAMD0u4cNuj


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接