为什么我的 require.js 配置中的 shim 没有调用? [英] Why `init` of shim in my require.js configuration not called?

查看:14
本文介绍了为什么我的 require.js 配置中的 shim 没有调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:

我正在编写一个小模块来处理 backbone 中的这个 csrf 令牌问题,直到我收到@Louis 回答的推送通知.

I was writing a small module to handle this csrf token problem in backbone until I got push notification of @Louis's answer.

他的回答非常优雅,看起来不错,但我会留下一个链接到我的backbone.csrf 模块 github 存储库,仅供需要它的人使用.

His answer is quite elegant and seems nice, but I'll leave a link to my backbone.csrf module github repo just for anyone who needs it.

====================================================================

====================================================================

我使用 Backbone 作为我的前端框架以及我的 Django 后端.

I'm using Backbone as my frontend framework along with my Django backend.

为了与 Django 的 CSRF 保护系统兼容,我必须配置我的 Backbone.sync 以在发送之前为每个 AJAX 请求设置 CSRF 请求标头.

I had to configure my Backbone.sync to set CSRF request header for every single AJAX requests before it sends it, for compatibility with Django's CSRF protection system.

由于我使用 require.js 进行模块化 javascript 开发,因此我尝试在 require.configshim.init 中进行配置,因此一旦 Backbone 在浏览器上加载,这个覆盖将被触发:

Since I was using require.js for modular javascript development, I tried to configure this in shim.init of require.config so that this overriding will be fired as soon as the Backbone is loaded on browser:

<script>
    var require = {
        ...

        shim: {
            'jquery': {'exports': 'jQuery'},
            'backbone': {
                'deps': ['underscore', 'jquery'],
                'exports': 'Backbone',
                'init': function(_, $) {
                     alert('NOT EVEN CALLED');
                     var originalSync = this.Backbone.sync;
                     this.Backbone.sync = function(method, model, options) {
                         options.beforeSend = function(xhr) {
                             xhr.setRequestHeader('X-CSRFToken', window.csrf_token);
                         }
                         return originalSync(method, model, options);
                     }
                 }
            }
        }
    }
</script>
// Load require.js
<script src="require.js"></script>

尽管 Backbone 已成功加载,但未调用 require 配置的 'init'.

Although the Backbone has been successfully loaded, the 'init' of the require configuration doesn't get called.

有什么问题?

推荐答案

查看注释源,我看到 Backbone 在检测到它正在使用 AMD 加载器运行时调用 define.将 shim 与调用 define 的模块一起使用会导致未定义的行为,因为 shim 用于不调用 define 的模块.

Looking at the annotated source, I see that Backbone calls define when it detects it is running with an AMD loader. Using a shim with a module that calls define results in undefined behavior because shim is for modules that do not call define.

你可以用这样一个伪造的 backbone 模块来实现你想要的,你可以将它保存在一个名为 backbone-glue.js 的文件中:

You could achieve what you want with a fake backbone module like this which you'd save in a file named backbone-glue.js:

define(['backbone'], function (Backbone) {
    var originalSync = Backbone.sync;
    Backbone.sync = function(method, model, options) {
        options.beforeSend = function(xhr) {
            xhr.setRequestHeader('X-CSRFToken', window.csrf_token);
        }
        return originalSync(method, model, options);
    };

    return Backbone;
});

然后你应该在你的 RequireJS 配置中有一个这样的地图:

And then you should have a map like this in your configuration for RequireJS:

map: {
     '*': {
          backbone: 'backbone-glue'
     },
     'backbone-glue': {
          backbone: 'backbone'
     }
}

这样做的作用是,当需要 backbone 模块时,到处 (*) RequireJS 加载 backbone-glue 代替.但是,在backbone-glue 中,当需要backbone 时,则加载backbone.这允许 backbone-glue 加载原始 Backbone.

What this does is that everywhere (*) when the module backbone is required RequireJS loads backbone-glue instead. However, in backbone-glue, when backbone is required, then backbone is loaded. This allows backbone-glue to load the original Backbone.

这篇关于为什么我的 require.js 配置中的 shim 没有调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆