Angular2: CoreModule vs SharedModule


¿Podría alguien explicar qué significan SharedModule y CoreModule?

He estado viendo varios proyectos por ahí están utilizando este enfoque con el fin de construir sus proyectos angulares.

  1. ¿por Qué necesito dos módulos?
  2. ¿Cuándo debo importar cada uno?
  3. Que imports, exports, declarations cada uno tiene?
 33
Author: Jordi, 2017-03-09

4 answers

TLDR:

  1. CoreModule debe tener solo services y importarse solo una vez en el AppModule.
  2. SharedModule debe tener cualquier cosa menos services y ser importado en todos los módulos que necesitan el material compartido (que también podría ser el AppModule).

Pero:

Los módulos del mundo real a menudo son híbridos que deliberadamente se desvían de las pautas [anteriores]. Estas pautas no son leyes; sígalas a menos que tenga una buena razón para hacerlo de lo contrario.


RTFM :

Así que, después de revisar todos los documentos de NgModules (además de algunas otras cosas para entender el contexto), encontré fácilmente la respuesta para sus preguntas 2a y 3a allí . Aquí están:

Módulo compartido

  • Crear un SharedModule con el components, directives, y pipes que usas en todas partes de tu app. Este módulo debe consistir enteramente en declarations, la mayoría de ellos exportar.
  • El SharedModule puede reexportar otros módulos de widget, tales como CommonModule, FormsModule, y módulos con los controles de interfaz de usuario que utiliza más ampliamente.
  • El SharedModule no debe tener providers por razones explicadas anteriormente. Ninguno de sus módulos importados o reexportados debe tener proveedores. Si se desvía de esta guía, sepa lo que está haciendo y por qué.
  • Importe el SharedModule en sus módulos de características, tanto los cargados cuando se inicia la aplicación como los que carga perezosamente tarde.

CoreModule

  • Cree un CoreModule con providers para los servicios singleton que cargue cuando se inicie la aplicación.
  • Importa CoreModule solo en la raíz AppModule. Nunca importe CoreModule en ningún otro módulo.
  • Considere hacer CoreModule un módulo de servicios puros sin declarations.

Aunque estos son más detallados que la versión anterior de TLDR y ahora puede continuar y seguir codificando, menciona algunas cosas que usted tiene que leer los documentos para entender (es decir, 'widget module", "reasons explained previously", "pure service modules"), y también no responde a su 1a pregunta.

Así que vamos a tratar de hacer eso!


¿por Qué necesito dos módulos?

Usted no necesita dos módulos. Esto es lo que está en los documentos:

El módulo raíz es todo lo que necesita en una aplicación simple con unos pocos componentes.

Dicho esto, es importante para hacer una pregunta diferente primero:

¿Por qué las personas organizan sus proyectos en múltiples módulos?

La explicación básica para esto viene justo después de la declaración anterior en los documentos:

A medida que la aplicación crece, refactoriza el módulo raíz en módulos de características que representan colecciones de funcionalidades relacionadas. A continuación, importe estos módulos en el módulo raíz.

Pero usted preguntó "¿por qué?"y esto requiere más que una explicación básica. Tan comencemos a explicar cuáles son algunos problemas que pueden ocurrir si tu aplicación comienza a crecer y no separas funcionalidades en módulos de características:

  • El módulo raíz comienza a estar desordenado, con un código que es difícil de leer y trabajar, ya que debe importar todas las dependencias (por ejemplo, Módulos de terceros), proporcionar todos los servicios y declarar todos los componentes, directivas y tuberías. Cuanto más necesita la aplicación, más grande será este módulo ser.
  • Las diferentes funcionalidades no tienen un límite claro entre ellas, por lo que es más difícil, no solo entender la estructura de la aplicación, sino también tener diferentes responsabilidades en un equipo.
  • Puede comenzar a tener que resolver conflictos entre diferentes partes de su aplicación. Por ejemplo, si tienes directivas o componentes que hacen lo mismo en dos partes diferentes de tu app, tendrás que empezar a usar nombres más largos para diferenciarlos o cambiarles el nombre al importar.

Aunque puedes pensar que los ejemplos anteriores no son exactamente problemas (tal vez trabajas solo y puedes vivir con tu propio desorden o todos tus compañeros de equipo también son desordenados), ten en cuenta que otras personas ciertamente no estarán de acuerdo contigo y es por eso que "has estado viendo varios proyectos por ahí ... usando este enfoque " .

Teniendo en cuenta que está de acuerdo con eso y desea organizar su aplicación creciente en módulos de características, por favor nótese lo siguiente de los documentos:

El módulo raíz y el módulo de características comparten el mismo contexto de ejecución. Comparten el mismo inyector de dependencias, lo que significa que los servicios en un módulo están disponibles para todos.

Los módulos tienen las siguientes diferencias técnicas significativas:

  • Se inicia el módulo raíz para iniciar la aplicación; se importa un módulo de características para extender la aplicación.
  • Un módulo de características puede exponer u ocultar su implementación desde otros módulos.

Información para nunca olvidar: "los servicios en un módulo están disponibles para todos [módulos]", mientras que otras cosas, como Componentes, Directivas y Tuberías deben inyectarse en cada módulo que quiera usarlos.

Con esta información ahora podemos acercarnos a lo que quieres saber contestando la siguiente pregunta:{[80]]}

¿Todos los módulos de funciones son iguales?

¡NO! At al menos se sugiere que no deberían ser iguales, ya que se sugiere que no deberías tener solo el módulo raíz, sino que puedes hacer lo que quieras. Pero no deberías.

Los documentos tienen una tabla que muestra las diferencias entre los grupos de módulos de características sugeridos. Echemos un vistazo a un extracto de la misma:

FEATURE   SHOULD HAVE    SHOULD HAVE   SHOULD HAVE
MODULE    DECLARATIONS   PROVIDERS     EXPORTS         

Domain    Yes            Rare          Top component   
Routed    Yes            Rare          No              
Routing   No             Yes (Guards)  RouterModule    
Service   No             Yes           No              
Widget    Yes            Rare          Yes             

ATENCIÓN! Dejan bastante claro que esto es una...

...orientación preliminar basada en la experiencia inicial NgModules en unos pocos aplicación.

Así que, de nuevo, no estás pegado a estas pautas y las desviaciones pueden ocurrir, pero debes saber lo que estás haciendo y por qué.

Ahora analicemos esta tabla:

  • Los grupos Service y Widget son los únicos que tienen valores completamente diferentes entre ellos en cada columna.
  • Los grupos Domain y Routed son básicamente los mismos que el grupo Widget, solo que con exportaciones limitadas o ninguna.
  • El grupo Routing es básicamente un Service grupo, con una excepción de exportación y limitado a un proveedor específico.

Entonces, consideremos la Domain, Routed y Routing agrupa solo variantes de Service o Widget y se centran en estos dos últimos.

Los servicios deben llamar su atención. Recuerde que nunca debe olvidar que " los servicios en un módulo están disponibles para todos los [módulos]"? Bueno, si llaman a un grupo de módulos de características Services, eso es porque debe estar aislado de los otros módulos para que pueda ser importado solo una vez. Como ejemplo, puede tener un UserModule que consiste en servicios como SignUpService, SignInService, SocialAuthService y UserProfileService. Donde quiera que importe UserModule, todos sus servicios estarán disponibles en toda la aplicación. Y según la tabla anterior, no debe tener declaraciones ni exportaciones, solo los proveedores.

Widgets suena más genérico, pero debería decirte algo. Recuerde que nunca debe olvidar que "otras cosas, como Componentes, Directivas y Tuberías deben ser inyectados en cada módulo que quiera utilizarlos."? Así que este es el tipo de módulo que va a utilizar para los. Por ejemplo, usted puede tener un UIModule con ButtonComponent, NavComponent, SlideshowComponent, HighlightLinkDirective, CtaPipe. Y cada vez que necesite usar uno o todos sus elementos exportados, importe solo el UIModule.

Así que, básicamente, debido a cómo Angular trata con los Servicios, cuando comienza a dividir funcionalidades en módulos de características, tiene que aislar los servicios en sus propios módulos, mientras que el otras cosas se pueden organizar entre ellos como desee.

¿Cómo encajan CoreModule y SharedModule en esto?

Para mantenerlo simple, el CoreModule es un módulo Service y el SharedModule es un módulo Widget. Y es por eso que debes importar el primero solo una vez en el AppModule y el segundo en todos los módulos que lo necesiten. De mis ejemplos anteriores, el UserModule sería importado por el CoreModule y el UIModule por el SharedModule.

Pero, como se dijo antes, estas son pautas y las desviaciones pueden sucede, incluso en sus propios ejemplos declaran componentes en el CoreModule, pero con una observación:

Este ejemplo de página se aparta de ese consejo declarando y exportando [en el CoreModule] dos componentes que solo se usan dentro del AppComponent raíz declarado por AppModule. Alguien siguiendo estrictamente esta guía habría declarado estos componentes en el AppModule en su lugar.


Personalmente, creo que la mayor confusión es con respecto al nombramiento opción. En general, la gente pensará que todo lo que es parte del núcleo de su aplicación (es decir, cosas de usuario, barra de navegación, barra de carga, tostadoras, etc.) irá a CoreModule y todo lo que se comparte a través de múltiples características irá a SharedModule.

Eso no es realmente cierto y un poco engañoso, ya que todos los servicios se comparten entre todos los módulos "por naturaleza" y no se debe incluir ningún servicio en el SharedModule, así como un NavbarComponent es parte del núcleo de su aplicación y no se debe incluir ningún componente en el CoreModule.

En cualquier caso, la recomendación es seguir las pautas hasta que encuentre una razón para no hacerlo.

Y aquí está el resto de la tabla anterior para ayudar a comprender mejor las pautas:

FEATURE   CAN BE                 SOME
MODULE    IMPORTED BY            EXAMPLES

Domain    Feature, AppModule     ContactModule (before routing)
Routed    Nobody                 ContactModule, DashboardModule,
Routing   Feature (for routing)  AppRoutingModule, ContactRoutingModule
Service   AppModule              HttpModule, CoreModule
Widget    Feature                CommonModule, SharedModule

Salud!

 76
Author: mattarau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-16 09:15:03

Yo mismo uso este enfoque y he aquí por qué / cómo :
(es un enfoque y tal vez otras personas tendrán!= ideas que está bien)

Me gusta mantener el app.module lo más limpio posible. Si desea utilizar universal o construir su proyecto con AOT (cuando no se utiliza angular-cli) es posible que necesite tener una aplicación duplicada.módulo con pequeños cambios en todos esos archivos.

Así que si importa muchos módulos en su app.module, tendrá que mantener esa lista actualizada en diferentes archivos.

Aquí viene el core.module :
Ponga todos los módulos que solo desea importar una vez aquí. Principalmente, módulos con métodos forRoot (los que exportan a sus proveedores y que deben importarse una sola vez).

Importa también tus proveedores aquí. (si usa ngrx, por ejemplo, declare su tienda aquí).

Entonces, el shared.module :
Ponga cada módulo que tendrá que reutilizar en su aplicación (CommonModule, HttpModule, RouterModule, MaterialModule, FlexLayoutModule, etc).

Por último, app.module :
Importar en app.module su core.module SOLO AQUÍ . CoreModule debe cargarse solo una vez. En todos sus submóbulos, puede cargar el SharedModule.

Con esa configuración, si necesita crear otra aplicación.módulo para universal u otros, no tiene que copiar y mantener toda la lista de módulos en archivos diferentes. Simplemente importa el core.module y ya está listo.

 3
Author: maxime1992,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-09 13:14:10

Según la guía de estilo de Angular y mis observaciones:

CoreModule (núcleo.módulo.ts) Módulo de características principales

Todos los servicios que deben ser singleton deben proporcionarse aquí. Por ejemplo HelperService, LoggerService.

El componente de toda la aplicación debe declararse en CoreModule como header, footer.

CoreModule proporciona uno o más servicios singleton. Angular registra los proveedores con el inyector raíz de la aplicación, haciendo una instancia de singleton de cada servicio está disponible para cualquier componente que lo necesite, ya sea que ese componente esté cargado con entusiasmo o perezosamente.

Solo el AppModule raíz debe importar el CoreModule.

SharedModule (compartido.módulo.ts) Módulo de características compartidas

Declare componentes, directivas y canalizaciones en un módulo compartido cuando esos elementos serán reutilizados y referenciados por los componentes declarados en otros módulos de características

Se sugiere evitar el uso de services en módulos compartidos. Los servicios son generalmente singletons que se proporcionan una vez para toda la aplicación o en un módulo de características en particular.

Los módulos requeridos por todos los módulos de características deben importarse en SharedModule como CommonModule & FormsModule.

La declaración de componente/tubería/directiva compartible debe estar en SharedModule. Si estos componentes / tuberías / directivas necesitan ser utilizados por otro módulo de características, deben exportarse.

Si utiliza material, es el mejor lugar para importar y reexportar Componentes de material angular.

Referencias: CoreModule, SharedModule

 0
Author: Anshuman Jaiswal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-11 19:42:36

Creo que esta pregunta es demasiado general y para una pregunta general, tendrás respuestas generales ... Por ejemplo, el módulo compartido está destinado a mantener lo que usan varios componentes/módulos:

import { NgModule }            from '@angular/core';
import { CommonModule }        from '@angular/common'; 
import { FormsModule, ReactiveFormsModule } from '@angular/forms';

//import { AwesomePipe }         from './awesome.pipe';
//import { HighlightDirective }  from './highlight.directive';

@NgModule({
  exports:      [ /*AwesomePipe, HighlightDirective,*/
                  CommonModule, FormsModule, ReactiveFormsModule ]
})
export class SharedModule { }

CoreModule se parece más a lo que consideras el núcleo de tu página (Nav, Spinner, Alert...). Esto es muy sugerente y depende de su sentimiento creo. Por ejemplo:

import { NgModule, Optional, SkipSelf } from '@angular/core';

import { NavComponent } from './nav/nav.component';
import { SpinnerComponent } from './spinner/spinner.component';
import { SpinnerService } from './spinner/spinner.service';
import { AlertComponent }     from './alert/alert.component';
import { AlertService }       from './alert/alert.service';

import { SharedModule }       from '../shared/shared.module';

import { CoreRoutingModule } from './core-routing.module';


@NgModule({
  imports: [ 
    SharedModule, 
    CoreRoutingModule,
  ],
  exports: [//Other modules use these components, so we export them
    AlertComponent, 
    NavComponent, 
    SpinnerComponent,

    ],
  declarations: [ //we use them in CoreModule, so we declare them
    AlertComponent, 
    NavComponent, 
    SpinnerComponent,

    ],
  providers: [
    SpinnerService, 
    AlertService,

  ]
})
export class CoreModule {
    constructor (@Optional() @SkipSelf() parentModule: CoreModule) {
      if (parentModule) {
        throw new Error(
          'CoreModule est déjà chargé. Importer le uniquement dans AppModule');
      }
    }
}
 -1
Author: mickdev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-09 13:07:59