Angular 9: использование angular i18n вместе с рендерингом на стороне сервера (angular универсальный) - PullRequest
2 голосов
/ 11 марта 2020

Я в процессе переноса приложения angular 7 на angular 9, которое использует рендеринг на стороне сервера (angular универсальный) и angular i18n для 2 языков (французский и английский sh) .

В старом процессе angular 7, поскольку я использовал AOT, мне пришлось сделать 5 сборок для производства:

  • 2 x клиентская сборка (1 для французского, 1 для engli sh)
  • 2 x сборка сервера (1 для французского, 1 для engli sh)
  • сборка server.ts

Затем в server.ts Я динамически загружал правильный серверный комплект

old server.ts

app.engine('html', (_, options: any, callback) => {

  const isFR= options.req.url.indexOf('site-fr') >= 0 ;
  const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = isFR ? require('./dist/server/fr/main') : require('./dist/server/en/main');

// Our index.html we'll use as our template
  const template = readFileSync(join(DIST_FOLDER, 'browser', isFR ? 'fr' : 'en', 'index.html')).toString();
  renderModuleFactory(AppServerModuleNgFactory, {
    // Our index.html
    document: template,

Я перенес приложение в angular 9, и теперь из какого Я понимаю, что в документации требуется только одна сборка клиента.

Вы также можете указать опцию --localize для команды ng build с существующей производственной конфигурацией. В этом случае CLI создает все локали, определенные в i18n в конфигурации проекта.

Это похоже на работу для сборки клиента, так как генерируются 2 папки (fr и en).

Однако нигде нет упоминаний об использовании SSR с i18n. В итоге я получаю один server.ts.

Вот сценарии, которые я использую для сборки и запуска проекта

angular. json

"serve:ssr": "node dist/myproject/server/main.js",
"build:ssr": "ng build -c production --localize && ng run myproject:server:production"

новый server.ts

// The Express app is exported so that it can be used by serverless Functions.
export function app(port) {
  const server = express();
  const distFolder = join(process.cwd(), 'dist/myproject/browser/fr');
  const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';

  // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
  server.engine('html', ngExpressEngine({
    bootstrap: AppServerModule,
  }));

Структура папок Dist

- dist
  - myproject
    - browser
        - fr
          - index.html
          - *.js
        - en
          - index.html
          - *.js      
    - server
        - main.js

Примечание. Я видел закрытая проблема GitHub , описывающая эту проблему, но решение в основном состоит в том, чтобы go вернуться назад, как это было раньше, то есть иметь 2 сборки на язык, а также 2 сборки для server.ts.

Неужели есть другой способ?

1 Ответ

1 голос
/ 13 марта 2020

Я нашел решение, включающее всего 2 сборки. Но теперь необходимо запустить 2 экземпляра серверного процесса.

Шаг # 1: angular. json

Убедитесь, что ваши локали правильно определены в angular.json и добавьте новый allLocales target в my-project:server option.

Я создал новую allLocales target, потому что я не знал, как объединить production target с en и fr конфигурациями. Смысл этого заключается в том, чтобы иметь только одну сборку сервера со всеми созданными языковыми серверами.

Для передней связки это возможно с помощью ng build (то есть ng build --configuration=production,fr,en or ng build --configuration=production --localize)

angular. json

 "projects": {
    "my-project": {
      "i18n": {
        "locales": {
          "en": {
            "translation": "src/locale/messages.en.xlf",
            "baseHref": ""
          },
          "fr": {
            "translation": "src/locale/messages.fr.xlf",
            "baseHref": ""
          }
        }
      },
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            //...
          },
          "configurations": {
            "production": {
             //...
            },

            "en": {
              "localize": [
                "en"
              ]
            },


            "fr": {
              "localize": [
                "fr"
              ]
            }

          }
        },

        "server": {
          "builder": "@angular-devkit/build-angular:server",
          "options": {
            "outputPath": "dist/my-project/server",
            "main": "server.ts",
            "tsConfig": "tsconfig.server.json"
          },

          "configurations": {
            "production": {
              //...
            },

            "allLocales": {
              "outputHashing": "none",
              "optimization": false,
              "sourceMap": false,
              "namedChunks": false,
              "extractLicenses": true,
              "vendorChunk": false,
              "localize": [
                "en", "fr"
              ],
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            }
          }
        },

Шаг № 2: server.ts

Измените файл server.ts, чтобы принять языковой параметр. Каждый работающий сервер сгенерированного серверного комплекта main.js будет иметь свой собственный порт и язык.

server.ts

//...
export function app(language) { //add language here
  const server = express();
  const distFolder = join(process.cwd(), 'dist/my-project/browser', language); //Use language here


//...

function run() {
  const port = process.env.PORT || 5006;
  const language = process.env.LANGUAGE || 'fr';

  // Start up the Node server
  const server = app(language); //Use the language here
  server.listen(port, () => {
    console.log(`Node Express server listening on http://localhost:${port} for language ${language}`);
    });

Шаг № 3: Изменить пакет. json

пакет. json

"build:ssr": "ng build -c production --localize && ng run my-project:server:allLocales"
"serve:ssr-en": "env PORT=5006 LANGUAGE=en node dist/my-project/server/en/main.js",
"serve:ssr-fr": "env PORT=5007 LANGUAGE=fr node dist/my-project/server/fr/main.js",

build:ssr создаст клиентские пакеты для всех языков, а затем создаст серверные пакеты для всех языков server:ssr-XX запустит сервер nodejs для порта и языка, связанных с языком XX

Вот структура

- dist
  - myproject
    - browser
        - fr
          - index.html
          - *.js
        - en
          - index.html
          - *.js      
    - server
        - fr
            - main.js
        - en
            - main.js

Шаг 4: Обратный прокси

Если вы используете обратный прокси-сервер, не забудьте перенаправить все запросы на правильный основной. js экземпляр

Примечание Процесс сборки теперь намного быстрее с angular 9, так как есть только 2 билда.

...