Как использовать XI18N (AOT) в серверной части рендеринга (универсальный) в угловых - PullRequest
0 голосов
/ 11 июня 2018

Я хочу обслуживать многоязычное угловое приложение, используя серверную визуализацию для SEO и производительности.Для этого у меня сейчас следующая ситуация:

package.json скрипты:

"build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server",
"serve:ssr": "node dist/server",
"build:client-and-server-bundles": "npm run build-i18n && ng run my-web:server",
"webpack:server": "webpack --config webpack.server.config.js --progress --colors",
"build-i18n:de": "LOCALE=de && npm run build-i18n:locale",
"build-i18n:en": "ng build --output-path=dist/browser/en --aot --prod --base-href /en/ --i18n-locale=en",
"build-i18n": "npm run build-i18n:en && npm run build-i18n:de"

server.ts:

// Locale to get best language match
import { Locales } from 'locale';

app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [
    provideModuleMap(LAZY_MODULE_MAP)
  ]
}));

app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));

const supportedLanguages = ['de', 'en'];

for (const language of supportedLanguages) {
  // Server languages static files from /browser
  app.get('/' + language + '/*.*', express.static(join(DIST_FOLDER, language, 'browser'))); // todo

  // All languaged regular routes use the Universal engine
  app.get('/' + language + '/*', (req, res) => {
    console.log(language);
    res.render(language + '/index', {req});
  });
}

Моя проблема в том, что я получаю только правильный index.html с правильным base-href, но не правильные переведенные тексты из файлов .xlf (только те, которые находятся в компонентах HTML).У меня есть только один main.js в dist / server.С xi18n и AOT я получаю dist / browser / de и dist / browser / en.Я не смог найти ни одного учебного пособия или примера, чтобы можно было объединить xi18n и серверную визуализацию angular.

My angular.json имеет следующую запись architect :

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

Было бы здорово, если бы кто-нибудь помог мне решить эту проблему.

Моя угловая версия: 6.0.3

Заранее спасибо.

Рамазан

1 Ответ

0 голосов
/ 29 июля 2018

Это то, что я делаю для корейской версии:

package.json

"build:client-and-server-bundles-ko": "ng build --prod --base-href=/ko --deploy-url=/ko/ --output-path=dist/ko/browser --i18n-file=src/locale/messages.ko.xlf --i18n-locale=ko --i18n-format=xlf  && ng run rendercore-www:server --outputPath=dist/ko/server",
"build:client-and-server-bundles-staging-ko": "ng build --prod --base-href=/ko --deploy-url=/ko/ --output-path=dist/ko/browser --i18n-file=src/locale/messages.ko.xlf --i18n-locale=ko --i18n-format=xlf  --configuration=staging && ng run rendercore-www:server:staging --outputPath=dist/ko/server",
"build:client-and-server-bundles-prod-ko": "ng build --prod --base-href=/ko --deploy-url=/ko/ --output-path=dist/ko/browser --i18n-file=src/locale/messages.ko.xlf --i18n-locale=ko --i18n-format=xlf  --configuration=production && ng run rendercore-www:server:production --outputPath=dist/ko/server",
"build:ssr-ko": "npm run build:client-and-server-bundles-ko && npm run webpack:server-ko",
"build:ssr-staging-ko": "npm run build:client-and-server-bundles-staging-ko  && npm run webpack:server-ko",
"build:ssr-prod-ko": "npm run build:client-and-server-bundles-prod-ko  && npm run webpack:server-ko",
"webpack:server-ko": "webpack --config webpack.server.config.js --env.lang=ko --progress --colors",

server-ko.ts

// These are important and needed before anything else
import "zone.js/dist/zone-node";
import "reflect-metadata";
import { enableProdMode } from "@angular/core";
import * as express from "express";
import { join } from "path";

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
const app = express();

const PORT = process.env.PORT || 4000;
// const DIST_FOLDER = join(process.cwd(), 'dist');
const DIST_FOLDER = join(process.cwd(), "");  //here..i changed

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require("./dist/ko/server/main");//here..i changed add ko

// Express Engine
import { ngExpressEngine } from "@nguniversal/express-engine";
// Import module map for lazy loading
import { provideModuleMap } from "@nguniversal/module-map-ngfactory-loader";

app.engine(
    "html",
    ngExpressEngine({
        bootstrap: AppServerModuleNgFactory,
        providers: [provideModuleMap(LAZY_MODULE_MAP)]
    })
);

//here..i changed
app.use(function(req, res, next) { 
    if (req.url.slice(0, 4) === "/ko/") {
      req.url = req.url.slice(3);
    }
    next();
});

app.set("view engine", "html");
app.set("views", join(DIST_FOLDER, "browser"));

// Server static files from /browser
app.get("*.*", express.static(join(DIST_FOLDER, "browser")));

// All regular routes use the Universal engine
app.get("*", (req, res) => {
    console.log(`GET: ${req.originalUrl}`);
    res.render("index", {
      req: req,
      res: res
    });
});

// Start up the Node server
app.listen(PORT, () => {
    console.log(`Node server listening on http://localhost:${PORT}`);
});

webpack.server.config.js

const path = require("path");
const webpack = require("webpack");

module.exports = env => {
    //console.log(env);
    let langWithDash = env == undefined ? "" : "-" + env.lang;
    let langWithSlash = env == undefined ? "" : "/" + env.lang;
    return {
      entry: { server: "./server" + langWithDash + ".ts" },
      resolve: { extensions: [".js", ".ts"] },
      target: "node",
      mode: "none",
      // this makes sure we include node_modules and other 3rd party libraries
      externals: [/node_modules/],
      output: {
        path: path.join(__dirname, "dist" + langWithSlash),
        filename: "[name].js"
      },
      module: {
        rules: [{ test: /\.ts$/, loader: "ts-loader" }]
      },
      plugins: [
        // Temporary Fix for issue: https://github.com/angular/angular/issues/11580
        // for 'WARNING Critical dependency: the request of a dependency is an expression'
        new webpack.ContextReplacementPlugin(
          /(.+)?angular(\\|\/)core(.+)?/,
          path.join(__dirname, "src"), // location of your src
          {} // a map of your routes
        ),
        new webpack.ContextReplacementPlugin(/(.+)?express(\\|\/)(.+)?/, path.join(__dirname, "src"), {})
      ]
    };
};

Использовать npm run build:ssr-ko

Затем он создаст подпапку в папке dist примерно так:

/dist/ko/xxxxx

Необходимо переписать URL-адрес с веб-сервера.Я использую IIS, так что это пример IIS:

<rule name="Lang-EN" stopProcessing="true">
    <match url="^en[\/].*?" />
    <action type="Rewrite" url="dist/en/server.js" />
</rule>

<rule name="L51ang-KO" stopProcessing="true">
    <match url="^ko[\/].*" />
    <action type="Rewrite" url="dist/ko/server.js" />
</rule>

Кроме того, вы получите сообщение об ошибке с /assets URL, потому что текущий угол имеет ошибку.

Даже если вы используете base-href и deploy-url, но некоторые HTML-файлы будут иметь путь /assets.

Итак, я пытаюсь это сделать:

<rule name="Asset Redirect" stopProcessing="true">
    <match url="^assets\/.*" />
    <action type="Rewrite" url="dist/en/server.js" appendQueryString="true" />
</rule>

Еще один совет, если клиент заходит на / сайта, перенаправьте его на настройку языка браузера:

<rule name="Redirect To KO"  stopProcessing="true">
    <match url="^$" />
        <conditions>
          <add input="{HTTP_ACCEPT_LANGUAGE}" pattern="^ko" />
        </conditions>
    <action type="Redirect" url="{R:0}/ko/home" appendQueryString="true" />
</rule>

Затем, если вы хотите добавить другой язык, выполните этот шаг снова.

Мой скрипт сборки выглядит следующим образом:

cd www
rmdir /S /Q dist
call npm i 
call npm run build:ssr-staging-en || exit /b -1
call npm run build:ssr-staging-ko || exit /b -1
call npm run build:ssr-staging-ja || exit /b -1

build en ko ja, тогда он создаст это:

/dist/ko/server.js
/dist/en/server.js
/dist/ja/server.js

Просто загрузите это на веб-сервер, а затем настройте его правильно.

Надеюсь, вы понимаете.Благодаря.

...