0

我正在尝试迁移一个站点以使用 RequireJS 来管理它的 JS 依赖项。我也想将一些库捆绑在一起。

目前我们正在构建一个base.min.js包含下划线、jquery、bootstrap 和骨干网。它们在我们的整个网站上都被使用,因此将它们一起服务是有意义的。

尽管如此,我认为我们应该在逻辑上将三个库按名称分开,因此我编写了以下 require.config:

  require.config({
     baseUrl: '/s/js/libs',
     paths: {
       app: '../app', shims: '../shims'
     },
     map: {
       '*' : {
       // underscore, backbone, jquery and bootstrap are bundled
       'underscore': '../base',
       'backbone': '../base',
       'jquery': '../base',
       'bootstrap': '../base'
        }
     },
     shim:{
        'bootstrap': {
           deps: ['jquery']
        },
        'backbone': {
           deps: ['underscore', 'jquery'],
           exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        },
        'jquery': {exports: '$'}
      }
  });

我没有使用data-main; 但相反,我需要几件事:

  require(["jquery", "underscore", "backbone", "bootstrap", "../baseapp"],
     function($){
       // Next line fixes the bootstrap issue with double modals taken from:
       // http://stackoverflow.com/questions/13649459/twitter-bootstrap-multiple-modal-error
       $.fn.modal.Constructor.prototype.enforceFocus = function () {};
       $('.modal').on('shown', function () {
         $('input:text:visible:first, textarea:visible:first', this).focus();
       });
       $('#search').on('shown', function () {
         $('#id_asf-text').focus();
       })

       require(['micro', 'csrf_xhr', 'locale']);
       require(['app/routers']);

     });

但是,这会导致$未定义的错误。

全局window.$已定义,但似乎 requirejs 没有用exports我的垫片正确检测到它。即使我这样做exports: 'window.jQuery'也不起作用。

这是 RequireJS 中的错误还是我的代码中有错误?mapshim一起玩好吗?RequireJS 是否支持我的用例?

2013-11-05 更新

经过长时间的调试,我发现 RequireJS 中的每个“真实”模块都记录了垫片;所以如果我只是把我的垫片改成:

 shim : {
    '../base': {init: function() {return [$, _, Backbone]}}
 }

我确实将此数组作为回调的第一个参数。但是我希望它们被爆炸,即;将每个返回值作为参数...

我认为内部地图+路径会起作用。像这样:

  var require = {
     baseUrl: '/s/js/libs/',
     paths: {
       app: '../app',
       shims: '../shims',

       'base-underscore': '../base',
       'base-backbone': '../base',
   'base-jquery': '../base',
   'base-bootstrap': '../base'
     },
     map: {
       '*' : {
       // underscore, backbone, jquery and bootstrap are bundled
       'underscore': 'base-underscore',
       'backbone': 'base-backbone',
       'jquery': 'base-jquery',
       'bootstrap': 'base-bootstrap',
        }
     },
     shim:{
        'base-bootstrap': {
           deps: ['base-jquery'],
           init: function() {return null}
        },
        'base-backbone': {
           deps: ['base-underscore', 'base-jquery'],
           init: function() {return window.Backbone;}
        },
        'base-underscore': {
           init: function() {return window.Underscore;}
        },
        'base-jquery': {
          init: function() {return $}
        }
     }  // shims
  };

不幸的是,它没有。现在的错误是:Uncaught Error: Load timeout for modules: base-underscore,base-backbone,base-bootstrap,../base... 注意 base-jquery 未列出!

4

1 回答 1

0

我找到了一种解决方法,但涉及一个插件。这是我目前的解决方案。在我的 HTML 上,我有以下内容config(我更改为require = {...}idiom 以便调试更容易):

  var STATIC_URL = "/s/js/libs/";
  var require = {
     baseUrl: STATIC_URL,
     paths: {
       app: '../app',
       shims: '../shims',
     },
     map: {
       '*': {
            'jquery': 'bundler!jQuery',
            'bootstrap': 'bundler!',
            'underscore': 'bundler!_',
            'backbone': 'bundler!Backbone'
        }
     },
     bundler: {url: '../base'}
  };

bundler.js插件位于我的js/libs. 这是原始的 CoffeeScript:

global = @

each = (ary, func) ->
    if (ary)
        i = 0
        while i < ary.length and (what = ary[i]) and func(what, i, ary)
            i += 1

getGlobal = (value) ->
    if not value
        value
    g = global;
    each value.split('.'), (part) ->
        g = g[part]
    g

define
    load: (name, require, onload, config) ->
        base = config.bundler?.url ? '../base'
        require [base], () ->
            if name? and name
                value = getGlobal(name)
                onload(value)
            else
                onload()

    normalize: (name, norm) -> name

可能应该有一种方法可以在没有bundler...的情况下做到这一点。我会暂时保留这个问题,以便提供更好的答案。

于 2013-11-05T19:45:08.027 回答