在Angular应用中集成非模块化JS库和丰富的模块化库

时间:2018-10-25 08:50:07

标签: angular webpack

在Angular项目中,我使用的是modularized libleaflet库。

尽管是模块化库,leaflet仍为“旧版”应用声明了全局L变量,但未在其应用上使用模块加载器。

最近,我们不得不在项目中集成NonTiledLayer Leaflet plugin。该库的目的是“丰富” L提供的全局leaflet变量,并添加新的实用程序类(例如,L.NonTiledLayer)。

此插件通过npm分发时,未声明为模块(在导入的npm源中不存在define())。

"use strict";

var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null);

L.NonTiledLayer = (L.Layer || L.Class).extend({
//....

据我了解,这意味着当Webpack在应用程序上提供代码时,代码按“原样”执行(不会延迟加载)。

问题在运行时出现是因为,按时间顺序(带有调试断点)可以看到的是:

  1. leaflet模块已声明,但由于当时没有模块消耗它,因此它的主体未执行。
  2. leaflet.nontiledlayer被执行(没有模块声明),因此window.L全局变量充斥着NonTiledLayer对象。
     请注意,当执行L代码时,我不是100%理解为什么undefined变量不是leaflet.nontiledlayer……我想我有时会遗漏某些东西。 / em>
  3. 某些依赖于leaflet模块的模块使leaflet的延迟加载得以执行。声明了一个新的window.L变量,并覆盖了一个由leaflet.nontiledlayer定义的变量,从而使leaflet.nontiledlayer实用程序不可用。

所以,主要来说,我担心的是:我要么想要:

  • 至少在到达/执行leaflet代码之前,考虑“非常早”加载leaflet.nontiledlayer模块(避免延迟加载)
  • 或将leaflet.nontiledlayer转换为模块并使其依赖于leaflet模块,以确保leafletleaflet.nontiledlayer之前被加载

我想我可以通过调整一点Webpack(我想使用shims)来实现这一目标……但我想尽可能避免使用ng eject

我没有找到任何Angular文档,可以轻松声明此类配置。

当前,我的解决方法是将Leaflet.NonTiledLayer个js文件直接集成到我的项目中,将其转换为TS文件,并在文件开头的import上放置一个leaflet,以声明对leaflet的依赖关系,并将纯JS文件转换为TS模块。 这种快速而肮脏的解决方案可以工作,但是有很多缺点:

  • 不允许简单的leaflet.nontiledlayer版本升级(通过程序包管理器)
  • 我需要在我的root应用程序模块中导入TS文件,以使其尽早执行。我不确定,但是当webpack注意到我的代码中从未使用过导入的模块时,很有可能会摇晃我删除此导入。
  • 如果某天某人删除了此导入,它将不再起作用,而且如果我们不在地图屏幕上也不会注意到它。

我确定有更好的解决方案,但是这里缺少一些Angular x Webpack知识。

预先感谢

0 个答案:

没有答案