1

I have ruthlessly tried to build my Ionic 3 app for production using several different methods.

Attempts

Firstly I imported enableProdMode from Angular and called enableProdMode in my app.component.ts constructor. In turn, I got a blank screen when I built the app.

I decided that this was an unnecessary step, as the Ionic Framework documentation suggested that I simply run ionic cordova build ios --prod to get a production build. In turn, I got the following errors.

Errors

After running the aforementioned line of code to build my app for production, I received this in the console output and my build was then terminated (condensed for legibility).

Type AvatarComponent in .../avatar.ts is part of the declarations of 2 modules: AppModule in .../app.module.ts and AvatarComponentModule in .../avatar.module.ts! Please consider moving AvatarComponent in .../avatar.ts to a higher module that imports AppModule in .../app.module.ts and AvatarComponentModule in .../avatar.module.ts.

Thus, I tried doing exactly what Cordova prompted me to do, so I removed my avatar.module.ts file and voila, the error was gone. To my dismay, this issue occurred for every single component in my project (keep in mind, every component was generated automatically through ionic g component). After repeating this process for every component, my app began loading with a blank screen just as it had done when I tried using enableProdMode.

Misc. Details

cli packages:

    @ionic/cli-utils  : 1.13.1
    ionic (Ionic CLI) : 3.13.2

global packages:

    cordova (Cordova CLI) : 7.0.1 

local packages:

    @ionic/app-scripts : 1.3.7
    Cordova Platforms  : android 6.2.3 ios 4.4.0
    Ionic Framework    : ionic-angular 3.2.1

System:

    Android SDK Tools : 26.0.1
    Node              : v8.6.0
    npm               : 5.4.2 
    OS                : macOS Sierra
    Xcode             : Xcode 8.3.3 Build version 8E3004b 

Misc:

    backend : legacy

Summary

I would like a way to mitigate the Type ___ in ___/__.ts is part of the declarations of 2 modules issue, as well as an explanation as to why this occurs despite my usage of the pre-installed generation method.

Feel free to ask for clarification. Thank you so much in advance!

Anthony Krivonos
  • 4,596
  • 4
  • 16
  • 31
  • As the error say, it is because you declare your component in 2 modules. See [my answer](https://stackoverflow.com/a/46166922/4254681) to fix it. If you have any question please let me know – Duannx Oct 20 '17 at 03:31
  • @Duannx I read your answer, but I do not want to centralize all components into one shared module and then import from `app.module.ts`. I've seen this answer before and I posted this question to seek an alternative solution to this one. Thanks! – Anthony Krivonos Oct 20 '17 at 12:19

2 Answers2

0

Explanation for 'is part of the declarations of 2 modules'

To explain the ionic g issue, in ionic 3 they have started configuring your components to be lazy-loaded. this is why you are ending up with the .module.ts file. In my case I took a different approach, I actually included the module for the component in my app.module.ts

share.module.ts

import { NgModule } from '@angular/core';
import { IonicPageModule } from 'ionic-angular';
import { SharePage } from './share';

@NgModule({
  declarations: [
    SharePage,
  ],
  imports: [
    IonicPageModule.forChild(SharePage),
  ],
})
export class SharePageModule {}

app.module.ts

// I removed other modules just look at how I encorporate the component "SharedPageModule"
import {SharePageModule} from "../pages/share/share.module";

@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  imports: [
    BrowserModule,
    ComponentsModule,
    ProjectPageModule,
    SharePageModule,
    FormsModule,
    IonicModule.forRoot(MyApp,{
      preloadModules: true
    }),
    IonicStorageModule.forRoot(),
    MomentModule
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: [
    EmailComposer,
    File,
    Globalization,
    Keyboard,
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler},
    ModelProvider
  ]
})
export class AppModule {
}

Resolving your issue

I don't get any issues building with ionic cordova build ios --prod or white screen of death at run-time so perhaps it would help to import the modules as I have.

I doubt that will resolve your white screen of death so I would suggest debugging on your device or simulator.

Philip Brack
  • 1,340
  • 14
  • 26
  • Did what you suggested, but I am looking for an answer specific to components, since they are causing this issue. Also, here is my error output for my `button` component after following your instructions: `Unhandled Promise rejection: Template parse errors: 'button' is not a known element: 1. If 'button' is an Angular component, then verify that it is part of this module. 2. If 'button' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.` – Anthony Krivonos Oct 23 '17 at 16:22
  • 1
    strange error. Have you tried option 2. I remember needing to do that on one of my apps. Cannot remember what for though at the moment. – Philip Brack Oct 23 '17 at 16:47
  • 1
    I am starting to think this is a red herring. Perhaps the issue is with one of your dependencies... – Philip Brack Oct 23 '17 at 16:54
  • Progress! I deleted the `.module.ts` file from each component and kept the component imports in my `app.module.ts` file. I have a new error now, however, and it's caused by a set of `Injectable` helper classes I put in the `src/classes` folder I created. I am confused as to how these classes should be imported into `app.module.ts` since they are neither components nor modules. – Anthony Krivonos Oct 23 '17 at 20:44
  • See error: `Error: Cannot determine the module for class Alert in .../src/classes/alert.ts! Add Alert to the NgModule to fix it. Cannot determine the module for class Phone in.../src/classes/phone.ts! Add Phone to the NgModule to fix it.`... etc. – Anthony Krivonos Oct 23 '17 at 20:44
  • Those should show up in providers section of app.module.ts – Philip Brack Oct 23 '17 at 20:47
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/157313/discussion-between-philip-brack-and-anthony-krivonos). – Philip Brack Oct 23 '17 at 20:52
0

In my case, the solution was to delete the .module.ts (ngModule file) from each component and page folder generated by Ionic. Then, I made sure the components from my app were listed as declarations in my app.module.ts file. The app compiled perfectly in production.

Here is how my folder structure for a sample component or page looks like now:

/examplecomponent
    /examplecomponent.html
    /examplecomponent.scss
    /examplecomponent.ts

Additionally, here is how my app.module.ts file imports these components:

import { ExampleComponent } from '../components/examplecomponent/examplecomponent';

@NgModule({
      declarations: [
            ExampleComponent
      ],
      imports: [
            IonicModule.forRoot(App),
            CloudModule.forRoot(cloudSettings),
            ElasticModule,
            BrowserModule,
            HttpModule
      ],
      bootstrap: [IonicApp],
      entryComponents: [
            MyApp,
            MainPage
      ],
      providers: [
            {provide: ErrorHandler, useClass: IonicErrorHandler},
            // All Injectable Classes Go Here
            Alert,
            Analytics,
            Auth,
            Background
      ]
})
export class AppModule {}

If your issue persists, see Philip Brack's Solution.

Anthony Krivonos
  • 4,596
  • 4
  • 16
  • 31