RequireJS 加载 Wicket 库

RequireJS load Wicket library

我正在使用库 Wicket 来处理地图内容。如果我像往常一样将它作为脚本标记引用,它工作正常。工作 link 如下。

https://arthur-e.github.io/Wicket/sandbox-gmaps3.html

当我们的项目使用 RequireJS 作为模块加载器时,问题就来了。

这是我试过的以下代码。

require.config({    
    waitSeconds: 200,
    paths: {
        'wicket': '/Vendor/Wicket/wicket',
        'wicketGmap3': '/Vendor/Wicket/wicket-gmap3'
    },
    shim: {
        wicket: {
            exports: 'Wkt'
        },
        wicketGmap3: {            
            deps: ['wicket']
        }          
    },
});
require(['wicket', 'wicketGmap3'],(Wkt) => {
    $(() => {
        angular.bootstrap(document, ['app']);
    });
});

错误依旧如下

Uncaught ReferenceError: Wkt is not defined at wicket-gmap3.js:744

有没有人遇到过同样的情况?

wicket.js 文件调用了 define。所以为它设置一个 shim 是没有用的,因为 shim 只对非 AMD "modules" 有意义(即文件不是真正的模块,但我们希望表现得像它们一样) . AMD 模块调用 define.

另一方面,wicket-gmap3.js 不是 AMD 模块。所以你确实需要shim。但是,这取决于 Wkt 是否存在于全局 space 中。 wicket.js 中的逻辑是这样的,当它调用 define 时,它不会在全局 space 中设置 Wkt。 (对于性能良好的 AMD 模块, 是正确的行为。)您需要自己执行泄漏。

将您的配置更改为:

define("wicket-glue", ["wicket"], function (wicket) {
    Wkt = wicket; // Deliberately leak into the global space.
    return wicket;
});

require.config({    
    waitSeconds: 200,
    paths: {
        'wicket': '/Vendor/Wicket/wicket',
        'wicketGmap3': '/Vendor/Wicket/wicket-gmap3'
    },
    map: {
        '*': {
            wicket: 'wicket-glue',
        },
        'wicket-glue': {
            wicket: 'wicket'
        }
    }
    shim: {
        wicketGmap3: {            
            deps: ['wicket']
        }          
    },
});

我添加了一个名为 wicket-glue 的新模块。我经常将这些模块与配置放在一起,这样它们就不需要额外的数据获取。如果你愿意,你也可以把它放在一个单独的文件中。 (如果我这样做了,我会删除 define 的第一个参数并将文件命名为 wicket-glue.js 以便 RequireJS 从文件名中获取模块名称。)

我还添加了一个 map,它基本上表示 "in all modules, when the module wicket is required, load wicket-glue instead, but in wicket-glue when wicket is required, load wicket"。

最终效果是,每当需要 wicket 时,Wkt 将被泄漏到全局 space 并且 wicket-glue 应该可以正常工作。