使用 @angular/localize 本地化的 Angular 12 使用 nginx 在 docker 中运行

问题描述

我已经建立了一个 angular 12 的项目并在其中使用了本地化。我可以成功运行我的网站的英文版本,但是当我通过按钮切换到其他语言环境时,将 url 更改为 localhost/de 服务器响应不同文件的许多 404。当我切换回 en 时效果很好。

Package.json

    {
  "name": "my-frontend","version": "0.0.0","scripts": {
    "ng": "ng","start": "ng serve --configuration=development","build": "ng build --localize","transl": "ng extract-i18n --output-path locale --format=xlf2","watch": "ng build --watch --configuration development","test": "ng test","lint": "ng lint","prepare": "husky install"
  },"private": true,"dependencies": {
    "@angular/animations": "~12.0.0","@angular/common": "~12.0.0","@angular/compiler": "~12.0.0","@angular/core": "~12.0.0","@angular/forms": "~12.0.0","@angular/platform-browser": "~12.0.0","@angular/platform-browser-dynamic": "~12.0.0","@angular/router": "~12.0.0","@angular/service-worker": "~12.0.0","@ngrx/effects": "^12.0.0","@ngrx/store": "^12.0.0","@ngrx/store-devtools": "^12.0.0","ramda": "^0.27.1","rxjs": "6.6.0","tslib": "^2.1.0","zone.js": "~0.11.4"
  },"devDependencies": {
    "@angular-devkit/build-angular": "~12.0.0","@angular-eslint/builder": "12.0.0","@angular-eslint/eslint-plugin": "12.0.0","@angular-eslint/eslint-plugin-template": "12.0.0","@angular-eslint/schematics": "12.0.0","@angular-eslint/template-parser": "12.0.0","@angular/cli": "~12.0.0","@angular/compiler-cli": "~12.0.0","@angular/localize": "12.0.0","@types/jasmine": "~3.6.0","@types/node": "^12.11.1","@types/ramda": "^0.27.40","@typescript-eslint/eslint-plugin": "4.23.0","@typescript-eslint/parser": "4.23.0","autoprefixer": "^10.2.5","eslint": "^7.26.0","eslint-config-prettier": "^8.3.0","eslint-plugin-ngrx": "^1.0.0","eslint-plugin-prettier": "^3.4.0","husky": "^6.0.0","jasmine-core": "~3.7.0","karma": "~6.3.0","karma-chrome-launcher": "~3.1.0","karma-coverage": "~2.0.3","karma-jasmine": "~4.0.0","karma-jasmine-html-reporter": "^1.5.0","postcss": "^8.2.15","postcss-loader": "^5.3.0","prettier": "^2.3.0","tailwindcss": "^2.1.2","typescript": "~4.2.3"
  }
}

Dockerfile


# stage 1  for building the dist folder.
FROM node:14.17-alpine3.13 as my-front-dev
LABEL author="Victor Orlyk"
workdir /app
copY package.json package.json
copY yarn.lock yarn.lock
RUN yarn install
#copy all code
copY . .
RUN yarn run build
#Stage 2
FROM Nginx:alpine
# cashing it is default anyway
VOLUME /var/cache/Nginx
copY --from=my-front-dev /app/dist/my-frontend/ /usr/share/Nginx/my-frontend/
copY ./config/Nginx.conf /etc/Nginx/conf.d/default.conf
# docker build -t Nginx-angular -f dockerfile .
# docker run -p 8080:80 Nginx-angular

Docker-compose.yml


# This can be used to run a development version of the Angular and Node containers
# See the readme.md for details on changes that are required in the Angular service
# Run docker-compose build
# Run docker-compose up
# Live long and prosper
version: '3.7'
services:
  Nginx:
    container_name: Nginx-angular
    image: Nginx-angular
    build:
      context: .
      dockerfile: dockerfile
    volumes:
      - ./dist/my-frontend:/usr/share/Nginx/html
    ports:
      - "80:80"
#    depends_on:
#      - node
    networks:
      - app-network
#  node:
#    container_name: angular-node-service
#    image: angular-node-service
#    build:
#      context: ./server
#      dockerfile: node.dockerfile
#    environment:
#      - NODE_ENV=development
#    ports:
#      - "3000:3000"
#    networks:
#      - app-network
  # disabled in case someone is running this on Windows (OK to uncomment if on Mac/Linux)
  # cadvisor:
  #   container_name: cadvisor
  #   image: google/cadvisor
  #   volumes:
  #     - /:/rootfs:ro
  #     - /var/run:/var/run:rw
  #     - /sys:/sys:ro
  #     - /var/lib/docker/:/var/lib/docker:ro
  #   ports:
  #     - "8080:8080"
  #   networks:
  #     - app-network
networks:
  app-network:
    driver: bridge

config/Nginx.conf


  types {
    module;
  }
  include /etc/Nginx/mime.types;
  # Expires map for caching resources
  map $sent_http_content_type $expires {
    default                    off;
    text/html                  epoch;
    text/css                   max;
    application/javascript     max;
    ~image/                    max;
  }
  # browser preferred language detection
  map $http_accept_language $accept_language {
    ~*^en en;
    ~*^de de;
    ~*^ua ua;
  }
  server {
      listen       80;
    root         /usr/share/Nginx/my-frontend;
    # Set cache expires from the map we defined.
    expires $expires;
    # Security. Don't send Nginx version in Server header.
    server_tokens off;
    # Fallback to default language if no preference defined by browser
    if ($accept_language ~ "^$") {
      set $accept_language "en";
    }
    # Redirect "/" to Angular app in browser's preferred language
    rewrite ^/$ /$accept_language permanent;
    # Everything under the Angular app is always redirected to Angular in the correct language
    location ~ ^/(en|de|ua) {
      try_files $uri /$1/index.html?$args;
      # Add security headers from separate file
#       include /etc/Nginx/security-headers.conf;
    }
    # Proxy for APIs.
#     location /api {
#       proxy_pass https://api.address.here;
#     }
  }

app.module.ts


import { NgModule } from "@angular/core";
import { browserModule } from "@angular/platform-browser";
import { ServiceWorkerModule } from "@angular/service-worker";
import { ReactiveFormsModule } from "@angular/forms";
import { HttpClientModule } from "@angular/common/http";
import { StoreModule } from "@ngrx/store";
import { EffectsModule } from "@ngrx/effects";
import { StoreDevtoolsModule } from "@ngrx/store-devtools";
import { environment } from "@environments/environment";
import { AppComponent } from "./app.component";
import { LandingComponent } from "./features/landing/landing.component";
import { NotFoundComponent } from "./features/not-found/not-found.component";
import { CoreModule } from "./core/core.module";
import { AppRoutingModule } from "./app-routing.module";
@NgModule({
    imports: [
        browserModule,HttpClientModule,ReactiveFormsModule,ServiceWorkerModule.register("ngsw-worker.js",{
            enabled: environment.production,// Register the ServiceWorker as soon as the app is stable
            // or after 30 seconds (whichever comes first).
            registrationStrategy: "registerWhenStable:30000"
        }),AppRoutingModule,StoreModule.forRoot({},{}),StoreDevtoolsModule.instrument({
            maxAge: 25,logonly: environment.production
        }),EffectsModule.forRoot([]),CoreModule
    ],declarations: [AppComponent,LandingComponent,NotFoundComponent],providers: [],bootstrap: [AppComponent]
})
export class AppModule {}

app.component.html


<div class="home">
    <header>
        <ul class="flex">
            <li><a routerLink="/">Home</a></li>
            <li><a routerLink="/auth/sign-in">Sign in</a></li>
            <li><a routerLink="/auth/sign-up">Sign up</a></li>
            <li><a routerLink="/tasks">Tasks</a></li>
            <li><a routerLink="/chats">Chats</a></li>
            <li><a routerLink="/projects">projects</a></li>
            <li>
                <button>logout</button>
            </li>
        </ul>
        <ng-container *ngFor="let language of languageList">
            <a href="/{{language.code}}/">
                <button class="button">{{language.label}}</button>
            </a></ng-container
        >
    </header>
    <div>
        <router-outlet></router-outlet>
    </div>
</div>

然后运行应用程序的命令

docker compose build
docker compose up -d

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)