Typescript error: Type *Page is part of the declarations of 2 modules

#1

Hi,
when I try to build my App with this command:
ionic cordova build android --prod --release
I have this error:

C:\ElectDir\myassistant>ionic cordova build android --prod --release
Running app-scripts build: --prod --platform android --target cordova
[14:40:49]  build prod started ...
[14:40:49]  clean started ...
[14:40:49]  clean finished in 20 ms
[14:40:49]  copy started ...
[14:40:50]  deeplinks started ...
[14:40:50]  deeplinks finished in 90 ms
[14:40:50]  ngc started ...
[14:40:57]  typescript error
            Type CustomersPage in C:/ElectDir/myassistant/src/pages/customers/customers.ts is part of the
            declarations of 2 modules: AppModule in C:/ElectDir/myassistant/src/app/app.module.ts and
            CustomersPageModule in C:/ElectDir/myassistant/src/pages/customers/customers.module.ts! Please
            consider moving CustomersPage in C:/ElectDir/myassistant/src/pages/customers/customers.ts to a
            higher module that imports AppModule in C:/ElectDir/myassistant/src/app/app.module.ts and
            CustomersPageModule in C:/ElectDir/myassistant/src/pages/customers/customers.module.ts. You can
            also create a new NgModule that exports and includes CustomersPage in
            C:/ElectDir/myassistant/src/pages/customers/customers.ts then import that NgModule in AppModule in
            C:/ElectDir/myassistant/src/app/app.module.ts and CustomersPageModule in
            C:/ElectDir/myassistant/src/pages/customers/customers.module.ts.

Error: The Angular AoT build failed. See the issues above
    at C:\ElectDir\myassistant\node_modules\@ionic\app-scripts\dist\aot\aot-compiler.js:237:55
    at step (C:\ElectDir\myassistant\node_modules\@ionic\app-scripts\dist\aot\aot-compiler.js:32:23)
    at Object.next (C:\ElectDir\myassistant\node_modules\@ionic\app-scripts\dist\aot\aot-compiler.js:13:53)
    at fulfilled (C:\ElectDir\myassistant\node_modules\@ionic\app-scripts\dist\aot\aot-compiler.js:4:58)
    at <anonymous>
[14:40:57]  copy finished in 7.82 s

I can’t understand the problem, it is normal that CustomersPage is used in app.module.ts and customers…module.ts.
Why the builder raises this error?
These are more infos about the configuration:

C:\ElectDir\myassistant>ionic info
cli packages: (C:\Users\claudio\AppData\Roaming\npm\node_modules)
    @ionic/cli-utils  : 1.19.2
    ionic (Ionic CLI) : 3.20.0

global packages:
    cordova (Cordova CLI) : 8.0.0

local packages:
    @ionic/app-scripts : 3.1.11
    Cordova Platforms  : android 7.0.0
    Ionic Framework    : ionic-angular 3.9.2

System:
    Android SDK Tools : 26.0.2
    Node              : v8.11.3
    npm               : 6.2.0
    OS                : Windows 10
#2

Actually, it’s not normal to use in both modules. It’s an error (the error you’re receiving).

If you want to include in a custom module customers…module.ts then just remove from the app module (this is the approach used in ionic v3 regarding lazy load, each page in their own module only).

If you use @IonicPage() in the page component then you must create a module per page and import the page only there.

If you pager component is not annotated with IonicPage you can either import the page component in AppModule, or import it in its own module (I prefer this approach) and import the page module (not the page) in AppModule.

#3

Hello,

no it is not normally, because this raise the error. If you would do eager loading, then app.module.ts is the right palce. For lazy loading use whatever.module.ts. Never both for the same page.

Best reagrds, anna-liebt-

#4

Hi Lucas and Anna,
thank you for your answer.

If I remove the import of CustomersPage from app.module.ts I have this error:

ion-dev.js?v=3.1.11:156 ERROR Error: Uncaught (in promise): Error: No component factory found for CustomersPage. Did you add it to @NgModule.entryComponents?
Error: No component factory found for CustomersPage. Did you add it to @NgModule.entryComponents?

This is why I added the CustomersPage to app.module.ts:

However, now I understand why I have this problem.

I added the new pages using the command “ionic generate page Customers” that created the CustomersPage in a different way from, for example, the existent page AboutPage.
The new page has both a .ts and a.module.ts file:

@IonicPage()
@Component({
  selector: 'page-customers',
  templateUrl: 'customers.html',
})
export class CustomersPage {

The existent pages have not the “.module.ts” file and are defined in this way:

@Component({
  selector: 'page-about',
  templateUrl: 'about.html'
})
export class AboutPage {
...

So they are two different ways of creating pages.
Now I have to understand what are the differences between them and which one is better for my purposes.

cld

#5

If you include the page in an exclusive module you will enable lazy loading. This means that the page will be loaded on demand, which can improve boot time, because you won’t load all pages during startup.

If you don’t want lazy load you can import the page in the AppModule and discard the generated page module.

But in my opinion I advise to create one module per page (actually, per component), even if you don’t use lazy load. You can create my-page.module.ts related to my-page.ts and import the module in AppModule, like I said in my previous post.

app.module.ts

Instead of:

declarations: [
    CustomerPage
]

do this:

imports: [
    CustomerPageModule
]

(see that I use the page module instead of the page itself)

Then, if you want to enable lazy load you can just remove the page module from the AppModule.

As a side note, if you are starting ionic now, it may be better to start with ionic4, even tough it’s still in beta, so that you can avoid having to migrate from v3 to v4 in the future.

2 Likes