Para meus alunos do primeiro ano, eu forneci uma biblioteca simples baseada no ES5, escrita usando o Revealing Module Pattern. Aqui está um trecho do módulo / espaço para nome "principal", que abrigará outras extensões:
window.Library = (function ($) {
if (!$) {
alert("The Library is dependent on jQuery, which is not loaded!");
}
return {};
})(window.jQuery);
Isso funciona para praticamente 99,9% dos estudantes que são novos no desenvolvimento da Web e não estão usando coisas sofisticadas como o ES6 em combinação com o Webpack ou o Babel.
Os 0,1% agora solicitaram que eu forneça uma versão baseada no ES6, que pode ser importada corretamente. Eu ficaria feliz em fornecer isso, mas estou meio confuso sobre a melhor maneira de abordar isso.
Obviamente, quero manter o caminho do ES5, para que meus alunos possam apenas incluir o arquivo usando uma tag de script e digitar Library.SomeExtension.aFunction();
sempre que desejarem. Além disso, algumas das extensões dependem do jQuery, que é injetado de maneira semelhante ao snippet acima.
Agora estou procurando uma maneira sustentável de obter o melhor dos dois mundos, com uma base de código e o jQuery como dependência. Quero dar 99,9% a window.Library
, enquanto quero dar aos 0,1% uma maneira de usar import Library from 'library'
.
Posso fazer isso com um único arquivo JS que faz as duas coisas? Ou precisaria de uma versão especial do ES6 (não é um problema)? E acima de tudo: como eu reorganizaria meu código (todos semelhantes ao snippet acima) de maneira a suportar ambas as situações?
Todos e quaisquer indicadores serão muito apreciados!
EDIT: Assim como uma nota lateral, eu já tenho um gulpfile.js
no lugar que decorre esta biblioteca através de Babel
, minifiers
entre outras coisas. Portanto, ter que estender isso para resolver o problema acima não é um problema!
fonte
Library.SubLibrary.functionName
instalação e também em arquivos separados, mesmo se alguém a importar como ES6 ou qualquer outra coisa. (Isso ocorre principalmente porque as extensões também podem se usar e, usando uma configuração padrão do ES6, isso causaria referências circulares).export
e o outro atribuawindow
. Eu estava pensando que seria ótimo se as duas coisas pudessem ser feitas em um único arquivo, já que isso pareceria muito mais elegante, mas aexport
palavra - chave parece funcionar apenas dentro de atype=module
. Não sei se há uma solução alternativa ou se é apenas impossível.Respostas:
Depois de algumas noites movendo o código e instalando tantos pacotes gulp que nem me lembro de todos os que tentei, acabei decidindo por algo com o qual estou quase feliz.
Primeiro, para responder minha própria pergunta, que também foi apoiada por @Bergi nos comentários:
Então, o que eu acabei fazendo? Deixe-me colocar à frente que eu realmente queria manter a configuração do módulo IIFE que eu tinha (por enquanto) no arquivo ES5 de saída. Atualizei minha base de código para o ES6 puro e tentei todos os tipos de combinações de plugins (incluindo o Rollup.js mencionado por @David Bradshaw). Mas eu simplesmente não conseguia fazê-los funcionar, ou eles manipulariam completamente a saída de tal maneira que os navegadores não pudessem mais carregar o módulo ou abandonariam o suporte ao mapa de origem. Com o projeto que os alunos estão concluindo no momento, já perdi meu tempo livre o suficiente para 0,1% dos meus alunos. Então, melhor sorte no próximo ano para uma solução "melhor".
Baseei meu padrão UMD (como mencionado por @Sly_cardinal) no jQuery e joguei esse código em um
Library.umd.js
. Para a parte ES6, fiz umLibrary.es6.js
com apenas umexport default Library
.Nos dois arquivos, coloquei um comentário
/*[Library.js]*/
com várias linhas em que queria injetar o Library.js não minificado e concatenado.Eu modifiquei a minha tarefa Gulp existente para apenas construir o
Library.js
comconcat
eBabel
e armazenado em um local temporário. Eu escolhi sacrificar o suporte ao mapa de origem nesse processo, pois o código concatenado era perfeitamente legível na saída. Tecnicamente, o suporte ao mapa de origem "funcionou", mas ainda assim descartaria muito o depurador.Adicionei uma tarefa Gulp adicional para ler o conteúdo da temperatura e
Library.js
, em seguida, para cada um dos arquivos da Etapa 1, localizaria e substituiria o comentário de várias linhas pelo conteúdo. Salve os arquivos resultantes e jogue-os na geração finalconcat
(por exemplo, pacote com jQuery)terser
e no mapa de origem.O resultado final são dois arquivos:
Enquanto estou feliz com o resultado, não gosto da cadeia de tarefas Gulp e da perda de suporte ao mapa de origem na primeira metade do processo. Como dito anteriormente, tentei vários plugins gulp para obter o mesmo efeito (por exemplo
gulp-inject
), mas eles não funcionaram corretamente ou fizeram coisas estranhas no mapa de origem (mesmo que eles alegassem suportá-lo).Para um próximo empreendimento, posso procurar algo diferente do Gulp ou criar meu próprio plugin, que faz o que foi descrito acima, mas corretamente: P
fonte
Você pode usar o Rollup.js para agrupar seu código como uma biblioteca ES5, bem como um módulo ES6 que o acompanha.
O rollup possui suporte interno para o Gulp, portanto, algo assim seria um ponto de partida razoável (com base no exemplo do Gulp do Rollup):
Você pode ver mais informações sobre os diferentes formatos de saída disponíveis: https://rollupjs.org/guide/en/#outputformat
Geralmente, é mais fácil se a fonte da sua biblioteca for gravada usando módulos ES e depois agrupada / transpilada até o pacote ES5.
fonte