Atualização 24/05/2018: agora somos +3 versões do Angular da minha postagem original e ainda não temos uma solução final viável. Lars Meijdam (@LarsMeijdam) criou uma abordagem interessante que certamente vale a pena dar uma olhada. (Devido a problemas de propriedade, ele teve que remover temporariamente o repositório do GitHub onde havia publicado originalmente sua amostra. No entanto, você pode enviar uma mensagem diretamente se desejar uma cópia. Consulte os comentários abaixo para obter mais informações.)
Mudanças recentes na arquitetura do Angular 6 nos aproximam de uma solução. Além disso, o Angular Elements ( https://angular.io/guide/elements ) fornece algumas funcionalidades dos componentes - embora não sejam exatamente o que descrevi originalmente neste post.
Se alguém da incrível equipe Angular se deparar com isso, observe que parece haver muitas outras pessoas que também estão muito interessadas nessa funcionalidade. Vale a pena considerar a lista de pendências.
Gostaria de implementar um (plug-in) quadro conectável em um Angular 2
, Angular 4
, Angular 5
, ou Angular 6
aplicação.
(Meu caso de uso específico para desenvolver essa estrutura conectável é que eu preciso desenvolver um sistema de gerenciamento de conteúdo em miniatura. Por várias razões não necessariamente elaboradas aqui, Angular 2/4/5/6
é um ajuste quase perfeito para a maioria das necessidades desse sistema.)
Por estrutura conectável (ou arquitetura de plug-in), quero dizer especificamente um sistema que permite que desenvolvedores de terceiros criem ou estendam a funcionalidade de um aplicativo primário através do uso de componentes conectáveis sem ter acesso direto ou conhecimento do código fonte do aplicativo primário ou funcionamento interno .
(Essa frase sobre " sem ter acesso direto ou conhecimento do código fonte ou do funcionamento interno do aplicativo " é um objetivo principal.)
Exemplos de estruturas conectáveis incluem sistemas comuns de gerenciamento de conteúdo como WordPress
ou Drupal
.
A situação ideal (como no Drupal) seria simplesmente poder colocar esses componentes conectáveis (ou plug-ins) em uma pasta, fazer com que o aplicativo os detecte automaticamente ou os descubra e faça com que eles funcionem magicamente. Fazer com que isso ocorra de alguma maneira conectável a quente, ou seja, enquanto o aplicativo estava sendo executado, seria o ideal.
Atualmente, estou tentando determinar respostas ( com sua ajuda ) para as cinco perguntas a seguir.
- Praticidade: A estrutura de plug-ins para um
Angular 2/4/5/6
aplicativo é ainda prática? (Até agora, não encontrei nenhuma maneira prática de criar uma estrutura verdadeiramente conectávelAngular2/4/5/6
.) - Desafios esperados: Quais desafios alguém pode encontrar na implementação de uma estrutura de plug-ins para um
Angular 2/4/5/6
aplicativo? - Estratégias de implementação: Quais técnicas ou estratégias específicas podem ser empregadas para implementar uma estrutura de plugins para um
Angular 2/4/5/6
aplicativo? - Práticas recomendadas: Quais são as práticas recomendadas para implementar um sistema de plug-ins para um
Angular 2/4/5/6
aplicativo? - Tecnologias alternativas: se uma estrutura de plug-in não é prática em um
Angular 2/4/5/6
aplicativo, que tecnologias relativamente equivalentes (por exemploReact
) podem ser adequadas para um aplicativo Web altamente reativo moderno ?
Em geral, o uso de Angular 2/4/5/6
é muito desejável porque:
- é naturalmente extremamente rápido - impressionante.
- consome muito pouca largura de banda (após o carregamento inicial)
- tem uma pegada relativamente pequena (depois
AOT
etree shaking
) - e essa pegada continua a encolher - é altamente funcional, e a equipe e a comunidade Angular continuam o rápido crescimento de seu ecossistema
- ele funciona bem com muitas das melhores e mais recentes tecnologias da Web, como
TypeScript
eObservables
- O Angular 5 agora oferece suporte a funcionários de serviço ( https://medium.com/@webmaxru/a-new-angular-service-worker-creating-automatic-progressive-web-apps-part-1-theory-37d7d7647cc7 )
- apoiado
Google
, é provável que seja apoiado e aprimorado no futuro
Eu gostaria muito de usar Angular 2/4/5/6
no meu projeto atual. Se eu puder usar Angular 2/4/5/6
, também o usarei Angular-CLI
e provavelmente Angular Universal
(para renderização no servidor).
Aqui estão meus pensamentos, até agora, sobre as perguntas acima. Revise e forneça seus comentários e esclarecimentos.
Angular 2/4/5/6
aplicativos consomem pacotes - mas isso não é necessariamente o mesmo que permitir plug-ins dentro de um aplicativo. Um plug-in em outros sistemas (por exemploDrupal
) pode ser adicionado essencialmente ao colocar a pasta do plug-in em um diretório de módulos comum, onde é automaticamente "captado" pelo sistema. EmAngular 2/4/5/6
, um pacote (como um plug-in) pode ser instalado vianpm
, adicionado aopackage.json
e importado manualmente para o aplicativo - como emapp.module
. Isso é muito mais complicado do que oDrupal
método de eliminar uma pasta e fazer com que o sistema detecte automaticamente o pacote. Quanto mais complicado for instalar um plug-in, menor a probabilidade de as pessoas os usarem. Seria muito melhor se houvesse uma maneira deAngular 2/4/5/6
para detectar e instalar plug-ins automaticamente. Estou muito interessado em encontrar um método que permita que não desenvolvedores instalem oAngular 2/4/5/6
aplicativo e instalem todos os plugins escolhidos sem ter que entender toda a arquitetura do aplicativo.Geralmente, um dos benefícios de fornecer uma arquitetura conectável é que é muito fácil para desenvolvedores terceirizados estender a funcionalidade do sistema. Obviamente, esses desenvolvedores não estarão familiarizados com todos os meandros do código do aplicativo em que estão conectados. Uma vez desenvolvidos os plugins, outros usuários ainda menos técnicos podem simplesmente instalar o aplicativo e quaisquer plugins selecionados. No entanto,
Angular 2/4/5/6
é relativamente complicado e tem uma curva de aprendizado muito longa. Para mais coisas complicar, a maioria produçãoAngular 2/4/5/6
aplicativos também utilizamAngular-CLI
,Angular Universal
eWebPack
. Alguém que esteja implementando um plug-in provavelmente precisará ter pelo menos algum conhecimento básico de como tudo isso se encaixa - junto com um forte conhecimento prático deTypeScript
e uma familiaridade razoável comNodeJS
. Os requisitos de conhecimento são tão extremos que nenhum terceiro desejaria desenvolver um plugin?A maioria dos plug-ins provavelmente terá algum componente do lado do servidor (por exemplo, para armazenar / recuperar dados relacionados ao plug-in), bem como alguma saída do lado do cliente.
Angular 2/4/5
especificamente (e fortemente) desencoraja os desenvolvedores a injetar seus próprios modelos em tempo de execução - pois isso representa um sério risco à segurança. Para lidar com muitos tipos de saída que um plug-in pode acomodar (por exemplo, exibição de um gráfico), parece que é provavelmente necessário permitir que os usuários criem conteúdo injetado no fluxo de resposta, de uma forma e de outra. Eu me pergunto como seria possível acomodar essa necessidade sem fragmentarAngular 2/4/5/6
os mecanismos de segurança.A maioria dos
Angular 2/4/5/6
aplicativos de produção é pré-compilada usando a compilaçãoAhead of Time
(AOT
). (Provavelmente todos deveriam ser.) Não tenho certeza de como os plug-ins podem ser adicionados (ou integrados a) aplicativos pré-compilados. O melhor cenário seria compilar os plugins separadamente do aplicativo principal. No entanto, não tenho certeza de como fazer isso funcionar. Uma alternativa pode ser recompilar todo o aplicativo com todos os plug-ins incluídos, mas isso complica um pouco as coisas para um usuário administrativo que simplesmente deseja instalar o aplicativo (em seu próprio servidor) junto com todos os plug-ins selecionados.Em um
Angular 2/4/5/6
aplicativo, especialmente um pré-compilado, um único pedaço de código incorreto ou conflitante pode quebrar o aplicativo inteiro.Angular 2/4/5/6
aplicativos nem sempre são os mais fáceis de depurar. A aplicação de plugins mal comportados pode resultar em experiências muito desagradáveis. Atualmente, não conheço um mecanismo para lidar com plugins mal comportados.
fonte
Respostas:
Eu criei um repositório no github com uma solução que pode ajudar. Ele usa bibliotecas Angular 6 e aplicativos 1 base que carregam as bibliotecas agrupadas UMD preguiçosamente; https://github.com/lmeijdam/angular-umd-dynamic-example
Se você tiver alguma sugestão, não hesite em adicionar!
fonte
Demo️ Demonstração do Github angular-plugin-architecture
Talvez Ivy possa mudar alguma coisa, mas por enquanto eu uso a solução que usa o Angular CLI Custom Builder e atende aos seguintes requisitos:
O uso é simples como:
Mais sobre isso no meu artigo:
fonte
OAuthToken
em tempo de execução para o serviço Biblioteca do nosso aplicativo principal?InjectionToken
que será fornecido no AppModule e injetado em outros plugins. Obrigado!Acabei de publicar um novo capítulo para o meu livro " Developing with Angular ", que aborda o tópico dos plugins no Angular 2+ e deve ser de grande interesse para as pessoas que estão tentando criar plugins externos.
Pontos chave:
O livro é gratuito, e possui o modelo "pague o que você quiser". Sinta-se livre para pegar uma cópia e espero que ajude.
fonte
Exemplo de aplicativo com um sistema de plug-ins em funcionamento (graças ao Gijs por fundar o repositório do github!) Https://github.com/PacktPublishing/Mastering-Angular-2-Components/tree/master/angular-2-components-chapter-10 baseado no eBook Mastering Angular 2 Components
Cheers, Niklas
fonte
O que você está procurando é o carregamento lento do módulo. Aqui está um exemplo disso: http://plnkr.co/edit/FDaiDvklexT68BTaNqvE?p=preview
Melhor ... Tom
fonte
Eu fiz um hack para carregar e compile outros módulos no tempo de inicialização, mas não resolvi o problema das dependências cíclicas
em seguida, no AppModule, adicione isto:
fonte
Eu estava procurando por um sistema de plug-in angular 2/4 também para desenvolver um ambiente RAD para um aplicativo corporativo no trabalho. Após algumas pesquisas, decidi implementar uma coleção de componentes pseudo-angulares armazenados em banco de dados (mas poderia estar no sistema de arquivos).
Os componentes armazenados no banco de dados do banco de dados são baseados em ng-dynamic e a implementação do componente principal é semelhante a esta:
O código javascript externo é semelhante aos componentes angulares:
E os modelos dos componentes são como modelos angulares:
E também pode ser aninhado:
Embora não seja perfeito, os desenvolvedores dos componentes personalizados têm uma estrutura semelhante à do angular2 / 4.
fonte
Isso pode ser feito "manualmente". Como o webpack não sabe nada sobre o módulo externo (plug-ins), ele não pode incluí-los nos pacotes. Então, o que eu fiz foi examinar o código gerado pelo webpack e encontrei essas tortas de código em main.bundle.js:
Vamos examinar o que essa matriz contém:
Portanto, em teoria, se você incluir uma entrada na propriedade map, configure seu roteamento e siga o padrão, poderá ter um sistema de plug-in. Agora, o desafio é como adicionar ou remover entradas dessa propriedade do mapa. Obviamente, isso não pode ser feito a partir de código angular, deve ser feito para ferramenta externa.
fonte
Tentei implementar uma arquitetura de plug-in usando o ABP, Angular e ASP.NET Core: https://github.com/chanjunweimy/abp_plugin_with_ui
Basicamente, desenvolvi plugins angulares usando diferentes aplicativos angulares e os adicionei dinamicamente.
Mais informações sobre como consegui-lo:
Eu tenho 2 aplicativos angular-cli, 1 é o principal aplicativo angular cli e outro é o aplicativo plug-in angular cli. O problema que estamos enfrentando na abordagem da arquitetura do plugin Angular-cli é como os integramos.
No momento, o que fiz foi executar o ng-build nos dois aplicativos e colocá-los em uma pasta "wwwroot", que depois era hospedada em um servidor ASP.NET core 2.0. Um repositório mais simples que mostra essa ideia é o Angular Multiple App: https://github.com/chanjunweimy/angular-multiple-app
abp_plugin_with_ui é um repositório que trabalha no desenvolvimento de um plug-in que contém o backend e o Angular CLI. Para o back-end, fiz uso da estrutura aspnetboilerplate, desenvolvida pelo front-end usando vários aplicativos angular-cli.
Para que o aplicativo principal seja integrado ao aplicativo de plug-in, precisamos executar "ng-build" nos dois aplicativos (observe que também precisamos alterar o href do aplicativo de plug-in) e, em seguida, movemos o conteúdo incorporado do plug-in aplicativo cli angular, para a pasta "wwwroot" do aplicativo principal. Depois de conseguir tudo isso, podemos executar "dotnet run" para servir o aplicativo Web ASP.NET Core 2.0 para hospedar os arquivos estáticos gerados por "ng build".
Espero que ajude. Quaisquer comentários são bem-vindos! ^^
fonte
Um pouco fora de tópico, mas as bibliotecas de componentes da interface do usuário podem ser interessantes para alguns dos leitores que pesquisam plugins:
https://medium.com/@nikolasleblanc/building-an-angular-4-component-library-with-the -angular-cli-and-ng-packagr-53b2ade0701e
O NativeScript possui plug-ins de interface do usuário incorporados:
https://docs.nativescript.org/plugins/building-plugins
Esses plugins precisam de um Wrapper Angular:
https://docs.nativescript.org/plugins/angular-plugin
fonte
Atualmente, estou na mesma missão que você, tentando criar uma versão plugável / teórica do Angular, e não é um problema trivial.
Na verdade, encontrei boas soluções, lendo o livro Developing with Angular , do gênio Denys Vuyika , ele realmente explica uma boa solução, fala sobre plugins externos na página 356 do livro e usa o Rollup.js para obter o solução, ele processa para carregar dinamicamente plugins externos que foram criados anteriormente fora do seu aplicativo.
Existem também duas outras bibliotecas / projetos que ajudam a alcançar esse resultado ng-packagr e extensões Nx para Agnular (do Nrwl) que estamos tentando implementar o último, e eu diria que não é tão tranquilo quanto prevíamos, angular era simples não foi criado para isso, então temos que trabalhar em parte do núcleo de como o Angular e os NX ppls são um dos melhores.
Estamos apenas no começo do nosso projeto de código aberto, estamos usando Django + Mongo + Angular (estamos chamando WebDjangular e uma das nossas possíveis abordagens para essa resposta é que o Django precisará escrever alguns arquivos de configuração JSON e compilar o aplicativo toda vez que um novo plug-in ou tema é instalado e ativado.
O que já realizamos é que, a partir do banco de dados, podemos usar tags para os componentes, como no plug-in, e o componente será impresso na tela! Novamente, o projeto está em estágios iniciais, baseando um pouco nossa arquitetura no Wordpress e temos muito mais testes a serem realizados para alcançar nosso sonho: D
Espero que o livro possa ajudá-lo e, usando o Rollup.js, sei que você poderá solucionar esse problema não trivial.
fonte
Eu encontrei um bom artigo de Paul Ionescu sobre como criar um aplicativo extensível de plug-in em angular.
https://itnext.io/how-to-build-a-plugin-extensible-application-architecture-in-angular5-736890278f3f
Ele também faz referência a um aplicativo de exemplo no github: https://github.com/ionepaul/angular-plugin-architecture
fonte