如何条件 bootstrap angular app?
How to conditional bootstrap angular app?
我正在尝试 bootstrap 我的 angular 5 应用程序基于条件。基本上我有两个模块 MobileModule
和 WebModule
,其中分别包含 UI 网络和移动组件。
我正在尝试 bootstrap MobileModule
如果用户已在移动浏览器中打开该应用程序,否则 WebModule
。
这是我的 main.ts
来源。
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { environment } from './environments/environment';
import { AppSettings } from './app/core/app-settings';
import { MobileModule } from './app/mobile/mobile.module';
import { WebModule } from './app/web/web.module';
if (environment.production) {
enableProdMode();
}
/*
* Bootstrap mobile or web module based on mobile
* or desktop client.
*/
if (AppSettings.isMobileDevice) {
platformBrowserDynamic().bootstrapModule(MobileModule)
.catch(err => console.log(err));
} else {
platformBrowserDynamic().bootstrapModule(WebModule)
.catch(err => console.log(err));
}
web.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing/app-routing.module';
import { CoreModule } from '../core/core.module';
import { SharedModule } from '../shared/shared.module';
import { AuthModule } from './auth/auth.module';
import { SignupComponent } from './auth/signup/signup.component';
@NgModule({
imports: [
BrowserModule, // Support for common angular directives and services
AppRoutingModule, // Web routing controller module.
CoreModule, // Core modules
SharedModule, // Shared modules
AuthModule, // App authentication module (signup and login)
],
declarations: [],
providers: [],
bootstrap: [SignupComponent] // Bootstrap Signup component
})
export class WebModule { }
mobile.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing/app-routing.module';
import { CoreModule } from '../core/core.module';
import { SharedModule } from '../shared/shared.module';
import { AuthModule } from './auth/auth.module';
import { SignupComponent } from './auth/signup/signup.component';
@NgModule({
imports: [
BrowserModule, // Support for common angular directives and services
AppRoutingModule, // Mobile app routing controller module
CoreModule, // Core modules
SharedModule, // Shared modules
AuthModule, // App authentication module (signup and login)
],
declarations: [],
providers: [],
bootstrap: [SignupComponent] // Bootstrap Signup component
})
export class MobileModule { }
上述方法在 ng serve
上运行良好,但是当我尝试使用 ng serve --aot
选项 运行 它时,它在 chrome 控制台中抛出错误。
Uncaught Error: No NgModule metadata found for 'WebModule'.
at NgModuleResolver.resolve (compiler.js:20242)
at CompileMetadataResolver.getNgModuleMetadata (compiler.js:15195)
at JitCompiler._loadModules (compiler.js:34405)
at JitCompiler._compileModuleAndComponents (compiler.js:34366)
at JitCompiler.compileModuleAsync (compiler.js:34260)
at CompilerImpl.compileModuleAsync (platform-browser-dynamic.js:239)
at PlatformRef.bootstrapModule (core.js:5567)
at eval (main.ts:26)
at Object../src/main.ts (main.bundle.js:53)
at __webpack_require__ (inline.bundle.js:55)
我的项目结构是
|-node_modules
|-src
|-app
|-core
|-mobile
|-mobile.module.ts
|-shared
|-web
|-web.module.ts
我尝试了几种方法来有条件地 bootstrap 应用程序,但没有成功。任何建议将不胜感激。
我认为Angular 5 不支持多根模块,因为AOT(提前编译)的方式目前有效。它似乎只编译了第一个模块及其依赖项。
一个解决方法是拥有一个仅用于引导的根模块,并将 Router 与 Guards 一起使用,并在根模块中仅延迟加载所需的模块。
参考文献:
经过大量研究,我发现我们一次只能 bootstrap 个模块。这意味着每个 angular 个应用程序只有一个根模块。
但是,自 angular lazy loading of modules 以来,我们可以动态加载所有功能模块。因此,想法是加载一个根模块,并根据条件动态加载任何子模块。
让我们考虑上面的例子。
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { environment } from './environments/environment';
import { AppModule } from './app/app.module';
if (environment.production) {
enableProdMode();
}
/*
* Bootstrap single root module
*/
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CoreModule } from '../core/core.module';
import { SharedModule } from '../shared/shared.module';
import { AppComponent } from './app.component';
const isMobileDevice = true; // Mobile device condition
const routes: Routes = [
{
path : 'app',
loadChildren: isMobileDevice ? './mobile/mobile.module#MobileModule' : './web/web.module#WebModule' // Conditionally load mobile or web module
}
];
@NgModule({
imports: [
BrowserModule, // Support for common angular directives and services
RouterModule.forRoot(routes),
CoreModule, // Core modules
],
declarations: [],
providers: [],
bootstrap: [AppComponent] // Bootstrap Signup component
})
export class AppModule { }
希望这对那些希望在他们的 angular 应用程序中有这种行为的其他人有所帮助。
我通过在 angular.json 文件中使用 fileReplacements
实现了在 main.ts
中有条件地加载模块,方法是在配置下创建一个对象,我在其中添加了替换项,如下所示:
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.lib.ts"
},
{
"replace": "src/main.ts",
"with": "src/main.lib.ts"
}
]
以上解决了我的问题。
希望这对某人有所帮助。
谢谢...
我正在尝试 bootstrap 我的 angular 5 应用程序基于条件。基本上我有两个模块 MobileModule
和 WebModule
,其中分别包含 UI 网络和移动组件。
我正在尝试 bootstrap MobileModule
如果用户已在移动浏览器中打开该应用程序,否则 WebModule
。
这是我的 main.ts
来源。
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { environment } from './environments/environment';
import { AppSettings } from './app/core/app-settings';
import { MobileModule } from './app/mobile/mobile.module';
import { WebModule } from './app/web/web.module';
if (environment.production) {
enableProdMode();
}
/*
* Bootstrap mobile or web module based on mobile
* or desktop client.
*/
if (AppSettings.isMobileDevice) {
platformBrowserDynamic().bootstrapModule(MobileModule)
.catch(err => console.log(err));
} else {
platformBrowserDynamic().bootstrapModule(WebModule)
.catch(err => console.log(err));
}
web.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing/app-routing.module';
import { CoreModule } from '../core/core.module';
import { SharedModule } from '../shared/shared.module';
import { AuthModule } from './auth/auth.module';
import { SignupComponent } from './auth/signup/signup.component';
@NgModule({
imports: [
BrowserModule, // Support for common angular directives and services
AppRoutingModule, // Web routing controller module.
CoreModule, // Core modules
SharedModule, // Shared modules
AuthModule, // App authentication module (signup and login)
],
declarations: [],
providers: [],
bootstrap: [SignupComponent] // Bootstrap Signup component
})
export class WebModule { }
mobile.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing/app-routing.module';
import { CoreModule } from '../core/core.module';
import { SharedModule } from '../shared/shared.module';
import { AuthModule } from './auth/auth.module';
import { SignupComponent } from './auth/signup/signup.component';
@NgModule({
imports: [
BrowserModule, // Support for common angular directives and services
AppRoutingModule, // Mobile app routing controller module
CoreModule, // Core modules
SharedModule, // Shared modules
AuthModule, // App authentication module (signup and login)
],
declarations: [],
providers: [],
bootstrap: [SignupComponent] // Bootstrap Signup component
})
export class MobileModule { }
上述方法在 ng serve
上运行良好,但是当我尝试使用 ng serve --aot
选项 运行 它时,它在 chrome 控制台中抛出错误。
Uncaught Error: No NgModule metadata found for 'WebModule'.
at NgModuleResolver.resolve (compiler.js:20242)
at CompileMetadataResolver.getNgModuleMetadata (compiler.js:15195)
at JitCompiler._loadModules (compiler.js:34405)
at JitCompiler._compileModuleAndComponents (compiler.js:34366)
at JitCompiler.compileModuleAsync (compiler.js:34260)
at CompilerImpl.compileModuleAsync (platform-browser-dynamic.js:239)
at PlatformRef.bootstrapModule (core.js:5567)
at eval (main.ts:26)
at Object../src/main.ts (main.bundle.js:53)
at __webpack_require__ (inline.bundle.js:55)
我的项目结构是
|-node_modules
|-src
|-app
|-core
|-mobile
|-mobile.module.ts
|-shared
|-web
|-web.module.ts
我尝试了几种方法来有条件地 bootstrap 应用程序,但没有成功。任何建议将不胜感激。
我认为Angular 5 不支持多根模块,因为AOT(提前编译)的方式目前有效。它似乎只编译了第一个模块及其依赖项。
一个解决方法是拥有一个仅用于引导的根模块,并将 Router 与 Guards 一起使用,并在根模块中仅延迟加载所需的模块。
参考文献:
经过大量研究,我发现我们一次只能 bootstrap 个模块。这意味着每个 angular 个应用程序只有一个根模块。
但是,自 angular lazy loading of modules 以来,我们可以动态加载所有功能模块。因此,想法是加载一个根模块,并根据条件动态加载任何子模块。
让我们考虑上面的例子。
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { environment } from './environments/environment';
import { AppModule } from './app/app.module';
if (environment.production) {
enableProdMode();
}
/*
* Bootstrap single root module
*/
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CoreModule } from '../core/core.module';
import { SharedModule } from '../shared/shared.module';
import { AppComponent } from './app.component';
const isMobileDevice = true; // Mobile device condition
const routes: Routes = [
{
path : 'app',
loadChildren: isMobileDevice ? './mobile/mobile.module#MobileModule' : './web/web.module#WebModule' // Conditionally load mobile or web module
}
];
@NgModule({
imports: [
BrowserModule, // Support for common angular directives and services
RouterModule.forRoot(routes),
CoreModule, // Core modules
],
declarations: [],
providers: [],
bootstrap: [AppComponent] // Bootstrap Signup component
})
export class AppModule { }
希望这对那些希望在他们的 angular 应用程序中有这种行为的其他人有所帮助。
我通过在 angular.json 文件中使用 fileReplacements
实现了在 main.ts
中有条件地加载模块,方法是在配置下创建一个对象,我在其中添加了替换项,如下所示:
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.lib.ts"
},
{
"replace": "src/main.ts",
"with": "src/main.lib.ts"
}
]
以上解决了我的问题。
希望这对某人有所帮助。
谢谢...