У меня есть функции IIFE для некоторого кода библиотеки в унаследованном приложении, которое должно работать для IE10 + (без загрузки модуля ES6 и т. Д.).
Однако я начинаю разрабатывать приложение React, которое будет использовать ES6 и TypeScript, и я хочу повторно использовать уже имеющийся у меня код без дублирования файлов. После небольшого исследования я обнаружил, что хотел бы использовать шаблон UMD, чтобы эти библиотечные файлы могли работать как для <script src=*>
импорта, так и чтобы приложение React могло импортировать их через загрузку модуля ES6.
Я придумал следующее преобразование:
var Utils = (function(){
var self = {
MyFunction: function(){
console.log("MyFunction");
}
};
return self;
})();
в
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.Utils = {})));
}(this, (function (exports) {
exports.MyFunction = function(){
console.log("MyFunction");
};
})));
Это разрешит загрузку через Import Utils from './Utils.js'
команду, а также позволит вставить ее с помощью тега script<script src='Utils.js'></script>
Тем не менее, некоторые из моих IIFE используют другие IIFE в качестве зависимости (плохо, я знаю, но реальность).
var Utils = Utils; // Used to indicate that there is dependency on Utils
var RandomHelper = (function(){
var self = {
DoThing: function(){
Utils.MyFunction();
}
};
return self;
})();
Если правильно превратить RandomHelper
и Utils
в файлы, которые можно импортировать, приложение React не совместимо с этой техникой. Делать просто
Import Utils from './Utils.js'
Import RandomHelper from './RandomHelper.js'
не работает, потому что я считаю, что Utils не ограничен окнами. Он загрузится без проблем, но RandomHelper.DoThing()
выдаст, что Utils не определен.
В устаревшем приложении
<script src='Utils.js'></script>
<script src='RandomHelper.js'></script>
работает без нареканий
Как сделать так, чтобы RandomHelper мог использовать Utils в приложении React, поддерживая его совместимость с IE и ES5, но при этом реагируя на него. Возможно, как-то установить окно / глобальную переменную?
PS: Я понимаю, что смысл загрузки модуля ES6 заключается в том, чтобы иметь дело с зависимостями, и мои существующие IIFE не идеальны. Я планирую со временем переключить классы es6 и улучшить контроль над зависимостями, но сейчас я хочу использовать то, что доступно, без переписывания
Ответы:
Давайте сначала разберемся с этим, функции модуля, если они явно не экспортированы, находятся в частной области видимости для определяющего модуля . Вы не можете обойти этот факт. Но есть варианты обхода, которые вы можете рассмотреть.
1. Предполагается, что минимальная модификация устаревшего кода является приемлемой
Произведение вокруг с минимальными изменениями в вашем унаследованного кода будет просто добавить
Utils
иRandomHelper
кwindow
объекту. Например, изменитеvar Utils = (...)();
наwindow.Utils = (...)();
. Следовательно, объект будет доступен из глобального объекта как устаревшими кодами (загруженными черезimport
), так и более новой кодовой базой.2. Предполагая, что никакие изменения в унаследованном коде недопустимы
Новый модуль ES6 должен быть создан как прокси для загрузки устаревших скриптов:
Наконец, вы можете импортировать
Utils
иRandomHelper
изlegacy-main.js
когда требуется:источник
Один из подходов, который вы могли бы рассмотреть, - это внедрение формы зависимости : приложение React получит RandomHelper или некоторые его свойства из внешнего мира. Затем вы можете удалить его, когда будете готовы перерезать шнур.
источник