【问题标题】:Configure Angular Routes in environment在环境中配置 Angular 路由
【发布时间】:2018-12-05 23:46:38
【问题描述】:

我有一个带有路由和延迟加载模块的 Angular 6 应用程序。 AppModule 有一个路由配置,其中包含两个延迟加载的路由,比如 AModule 和 BModule。

我们为 prod 和 dev 配置了不同的 angular-cli 环境。

在开发 BModule 期间,我希望 BModule 在我们的开发服务器上作为路由可用,但在我们的生产服务器上不可用。

因此,我们使用 angular-cli 环境 dev 构建应用程序的开发版本,而使用环境 prod 构建生产版本。

所以现在和将来通常会为 prod 配置一个路由配置,为 dev 配置一个路由配置,这是 prod 配置的超集。

所以我所做的是创建了两个路由配置:

export const prodRoutes: Routes = [
  { path: 'a-module', loadChildren: `app/a-module/a.module#AModule` },
];

export const devRoutes: Routes = [
  { path: 'b-module', loadChildren: `app/b-module/b.module#BModule` },
];

对于 prod,我只需使用变量 prodRoutes 进行路由配置。 效果很好。

对于开发配置,我将路由设置为[...devRoutes, ...prodRoutes]。 那不能正常工作。看来 Angular 不理解合并的路由配置。

有没有办法将多个路由数组合并到一个工作路由配置中?

【问题讨论】:

  • 我尝试了您在我的项目中尝试过的方法,它似乎有效。另外,你有AModule insinde b.module吗?因为,您的开发路线配置告诉我。是错字还是故意的?
  • 我猜 OP 为示例重命名了他的模块。一定是笔误
  • 这是一个错字。对不起。我修好了。

标签: angular angular-cli angular-routing


【解决方案1】:

我们遇到了类似的问题,我们使用路由作为“类似环境”的常量来处理它。

这里是我们的 app.routing.ts

import {appRoutes} from "../environments/general/approutes"; <----THAT'S IT

@NgModule({
    imports: [
        CommonModule,
        BrowserModule,
        RouterModule.forRoot(appRoutes, {useHash: true})
    ],
    exports: [
    ],
})

export class AppRoutingModule { }

environemnt 下的通用文件夹存储环境常量和文件 将用于开发模式。

所以我们在 /environments/general/approutes 下有我们的 approutes.ts 文件

..Omissis imports...
export const appRoutes: Routes =[
    {
        path: 'login', component: LoginComponent
    },
    { path: '', component: FullPageLayoutComponent,
        children: [
            { path: 'logged', loadChildren: '../../app/logged.module#LoggedModule' }
        ]
    },
    { path: '', component: ComponentA,
        children: [
            { path: 'pathA', loadChildren: '../../app/componentA.module#ComponentAModule' }
        ]
    },
    {
        path: '**', component: NotFoundComponent
    }
];

然后我们在 /environments/prod/approutes 下有一个不同的 approutes.ts 文件

..Omissis imports...
export const appRoutes: Routes =[
    {
        path: 'login', component: LoginComponent
    },
    { path: '', component: FullPageLayoutComponent,
        children: [
            { path: 'logged', loadChildren: '../../app/logged.module#LoggedModule' }
        ]
    },
    { path: '', component: ComponentA,
        children: [
            { path: 'pathB', loadChildren: '../../app/componentB.module#ComponentBModule' }
        ]
    },
    {
        path: '**', component: NotFoundComponent
    }
];

显然你必须为 prod 环境配置你的 angular.json 文件替换,如下所示:

        "prod":{
          "fileReplacements": [
            {
              "replace": "src/environments/general/environment.ts",
              "with": "src/environments/prod/environment.ts"
            }, //For sure you will have different stuff in your environment const in dev and prod mode
            {
              "replace": "src/environments/general/approutes.ts",
              "with": "src/environments/prod/approutes.ts"
            }
          ]
        }

会发生什么?

当以 prod 模式启动时,文件替换将首先发生,然后你的 app.routing.ts 将导入 approutes 常量以产生路由和加载魔法,包括惰性模块的东西。

通过这样做,您可能在不同的环境中拥有不同的路由和加载的模块。 这种方法可用于构建共享相同基础组件的不同应用程序,将它们作为单独的环境处理,所有这些都在一个项目中,我发现它非常有用

希望对你有帮助

【讨论】:

  • 它不起作用,角度会在读取环境集之前捆绑惰性模块。这意味着,在角度输出不同的包时,没有惰性模块。您将收到模块未找到错误。
【解决方案2】:

我发现使用“Development Guard”延迟加载效果最好。

development-guard.service.ts

@Injectable({
  providedIn: "root",
})
export class DevelopmentGuard implements CanActivate {
  canActivate() {
    return !environment.production;
  }
}

app-routing.module.ts

const routes = [
  { 
    path: "dev-page",
    canActivate: [DevelopmentGuard], 
    loadChildren: "app/development-only/development-only.module#DevelopmentOnlyModule" 
  },
  {
    path: "", 
    loadChildren: "app/production/production.module#ProductionModule" 
  },
]

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule { }

app.module.ts

const developmentModules = []
if (!environment.production) {
  developmentModules.push(DevelopmentOnlyModule)
}

@NgModule({
  imports: [
    AppRoutingModule,
    ...developmentModules,
  ],
})

据我所知,这并没有影响我的 main.js 文件的大小。我想有一个最小的增加,因为后卫。但是生产永远不会加载“DevelopmentOnlyModule”,所以我认为没关系。

注意请务必导入默认环境文件。

【讨论】:

  • 使用这种方法,如果用户尝试直接尝试访问/dev-page会发生什么?
  • @Drenai 出于安全目的,假设任何客户端都可以暴露。但是,如果他们不修改任何代码,模块将不会加载,并且守卫会阻止他们。您可以修改警卫,使其重定向。我不确定 false 会做什么,但更改该实现很容易。
  • 我不明白它是如何工作的。在生产中 DevelopmentOnlyModule 将不可用,但仍配置路由。 canActivate 不会阻止加载尝试和失败(可以加载会这样做)。您是否在生产环境中对此进行了测试?
  • @Drenai 我有一段时间没用过 Angular 了。如果有问题,请编辑。 :)
猜你喜欢
  • 1970-01-01
  • 2020-01-29
  • 1970-01-01
  • 2019-12-04
  • 2017-07-04
  • 2019-05-30
  • 2014-05-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多