Покопавшись, я решил опубликовать вопрос, и, надеюсь, появится правильный ответ:)
Цель : развернуть приложение angular в k8s, и выставляя его через вход nginx с настраиваемым путем И параметризованными маршрутами. Вызов, который должен работать:
http://my-url/my-app/
http://my-url/my-app/a
http://my-url/my-app/b
http://my-url/my-app/c
http://my-url/my-app/c/my-id
Проблема : параметризованный маршрут /c/:id
не поддерживается. Фабрика не вызывается, и поэтому динамика c APP_BASE_HREF
не устанавливается. Вызов, который не работает нормально:
http://my-url/my-app/c/my-id
Там APP_BASE_URL
не определяется должным образом, а angular пытается загрузить ресурсы из http://my-url/my-app/c/runtime.js
.
Будет сложно и долго, чтобы предоставить полный пример кода, но некоторые фрагменты будут предоставлены для
Kubernetes
nginx
helm uninstall -n ingress-nginx nginx-ingress; helm install --namespace ingress-nginx nginx-ingress stable/nginx-ingress
(версия диаграммы: nginx -ingress -1.33.5; версия приложения: 0.30.0)
конфигурация входа
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ template "my-app.ui.fullname" . }}
labels:
app: {{ template "my-app.name" . }}
component: "{{ .Values.ui.name }}"
annotations:
kubernetes.io/ingress.class: "nginx"
ingress.kubernetes.io/rewrite-target: /$2
ingress.kubernetes.io/ssl-redirect: "false"
ingress.kubernetes.io/use-regex: "true"
spec:
rules:
- host: "{{ .Values.root_url }}"
http:
paths:
- path: "{{ .Values.ui.ingress.path }}(/|$)(.*)"
backend:
serviceName: {{ template "my-app.ui.fullname" . }}
servicePort: 8085
где {{ .Values.ui.ingress.path }}
может быть любым, например /my-app
angular application
src/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
src/app/routing.module.ts
Маршруты, которые у нас есть.
const routes: Routes = [
{ path: '',
redirectTo: '/overview',
data: { title: 'Overview'},
pathMatch: 'full' },
{ path: 'overview',
data: { title: 'Overview'},
component: AComponent },
{ path: 'b',
data: { title: 'B'},
component: BComponent },
{ path: 'c/:id',
data: { title: 'C detail'},
component: CComponent },
{ path: 'c',
data: { title: 'C detail'},
component: CComponent },
{ path: '**',
component: PageNotFoundComponent }
];
@NgModule({
imports: [ RouterModule.forRoot(routes,
{enableTracing: false}
) ],
exports: [ RouterModule ]
})
export class RoutingModule { }
export const ROUTES_PATH = routes.map(p => p["path"])
src/app/app.module.ts
Просто взяв модификатор APP_BASE_HREF
:
import { getBaseLocation } from './common-utils';
/**
* Modules
*/
@NgModule({
declarations: [
AppComponent,
...
],
imports: [
BrowserModule,
RoutingModule
...
],
providers: [
Title,
{
provide: APP_BASE_HREF,
useFactory: getBaseLocation
}
],
bootstrap: [ AppComponent ],
entryComponents: [ t ]
})
export class AppModule { }
src/app/common-utils.ts
import { ROUTES_PATH } from './routing.module';
export function getBaseLocation() {
let paths: string[] = location.pathname.split('/');
let basePath: string = (paths && !ROUTES_PATH.includes(paths[1]) && paths[1]) || ''; // Default: ''
return '/' + basePath;
}
Ссылки
Providerfactory для токена APP_BASE_HREF вызывается до завершения APP_INITIALIZER
https://github.com/angular/angular/issues/25932
Angular 2 Установите APP_BASE_HREF со значением из Promise / Observable