Eu tenho funções IIFE para parte do código da biblioteca em um aplicativo herdado que precisa funcionar para o IE10 + (sem carregamento do módulo ES6, etc.).
No entanto, estou começando a desenvolver um aplicativo React que usará o ES6 e o TypeScript e quero reutilizar o código que já tenho sem duplicar os arquivos. Após algumas pesquisas, descobri que desejaria usar um padrão UMD para permitir que esses arquivos de biblioteca funcionassem como <script src=*>
importações e para permitir que o aplicativo React os importasse através do carregamento do módulo ES6.
Eu vim com a seguinte conversão:
var Utils = (function(){
var self = {
MyFunction: function(){
console.log("MyFunction");
}
};
return self;
})();
para
(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");
};
})));
Isso permitirá carregar via Import Utils from './Utils.js'
comando e também pode ser inserido usando uma tag de script<script src='Utils.js'></script>
No entanto, alguns dos meus IIFE usam outros IIFE como uma dependência (mal sei, mas é uma realidade).
var Utils = Utils; // Used to indicate that there is dependency on Utils
var RandomHelper = (function(){
var self = {
DoThing: function(){
Utils.MyFunction();
}
};
return self;
})();
Se corretamente transformar RandomHelper
e Utils
em arquivos que podem ser importados, a Reagir aplicativo não é compatível com esta técnica. Fazendo simplesmente
Import Utils from './Utils.js'
Import RandomHelper from './RandomHelper.js'
não funciona porque acredito que o Utils não tem escopo de janela. Ele será carregado sem problemas, mas RandomHelper.DoThing()
mostrará que o Utils não está definido.
No aplicativo herdado
<script src='Utils.js'></script>
<script src='RandomHelper.js'></script>
funciona perfeitamente.
Como o RandomHelper pode usar Utils em um aplicativo React, mantendo-o compatível com o IE e ES5, mas ainda trabalhando em reação. Talvez, de alguma forma, definir uma janela / variável global?
PS: Entendo que o objetivo do carregamento do módulo ES6 é lidar com dependências e meus IIFEs existentes não são ideais. Pretendo, eventualmente, mudar de classe es6 e melhor controle de dependência, mas, por enquanto, quero usar o que está disponível para ficar sem reescrever
fonte
Respostas:
Vamos resolver isso primeiro, os recursos do módulo, se não forem explicitamente exportados, têm um escopo particular para o módulo de definição . Você não pode contornar esse fato. Mas existem opções de solução alternativa que você pode considerar.
1. Supondo que uma modificação mínima do código legado seja aceitável
Uma solução alternativa com alterações mínimas no seu código legado seria simplesmente adicionar
Utils
eRandomHelper
aowindow
objeto. Por exemplo, mudevar Utils = (...)();
parawindow.Utils = (...)();
. Conseqüentemente, o objeto será acessível a partir do objeto global pelos códigos herdados (carregados viaimport
) e pela base de código mais recente.2. Supondo que absolutamente nenhuma modificação no código legado possa ser tolerada
Um novo módulo ES6 deve ser criado como proxy para carregar os scripts herdados:
Por fim, você pode importar
Utils
eRandomHelper
delegacy-main.js
quando necessário:fonte
Uma abordagem que você poderia considerar é alguma forma de injeção de dependência : faça com que o aplicativo React receba o RandomHelper, ou algumas de suas propriedades, do mundo exterior. Depois, você pode removê-lo quando estiver pronto para cortar o cordão.
fonte