简体   繁体   English

如何在Angular服务器端渲染(通用)中使用xi18n(AOT)

[英]How to use xi18n (AOT) within server side rendering (universal) in angular

I want to serve a multi language angular application, while using server side rendering for SEO and performance. 我想使用SEO和性能使用服务器端渲染时,为多语言角度应用程序提供服务。 For that I have currently following situation: 为此,我目前有以下情况:

package.json scripts: 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: 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});
  });
}

My issue is that I get only the right index.html with the right base-href, but not the right translated texts from the .xlf files (only the ones who are in the component HTMLs). 我的问题是,我只能从正确的base-href获得正确的index.html,而不能从.xlf文件获得正确的翻译文本(仅来自组件HTML中的文本)。 I have only one single main.js in dist/server. 我在dist / server中只有一个main.js。 With xi18n and AOT I get dist/browser/de and dist/browser/en. 使用xi18n和AOT,我得到dist / browser / de和dist / browser / en。 I could not found any tutorial or example to be able to combine xi18n and the server side rendering of angular. 我找不到任何可以将xi18n和angular的服务器端渲染结合起来的教程或示例。

My angular.json has following architect entry: 我的angular.json具有以下架构师条目:

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

It would be great if some one could help me solving this issue. 如果有人可以帮助我解决这个问题,那就太好了。

My angular version is: 6.0.3 我的角度版本是:6.0.3

Thank you in advance. 先感谢您。

Ramazan 拉马赞

This is what I do for the Korean version: 这是我对韩文版本所做的工作:

package.json 的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 服务器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 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"), {})
      ]
    };
};

Use npm run build:ssr-ko 使用npm run build:ssr-ko

Then it will make a subfolder under dist folder like so: 然后它将在dist文件夹下创建一个子文件夹,如下所示:

/dist/ko/xxxxx

You have to rewrite the URL from the web server. 您必须从Web服务器重写URL。 I use IIS so this is an IIS example: 我使用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>

Also you will get an error with the /assets URL because the current angular has a bug. 另外,由于当前的角度有错误,因此/assets URL也会出现错误。

Even if you use base-href and deploy-url , still some HTML will have an /assets path. 即使您使用base-hrefdeploy-url ,某些HTML仍具有/assets路径。

So I try this: 所以我尝试这样:

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

One more tip, if the client accesses / of the site, redirect to their browser language setup: 还有一个提示,如果客户端访问站点的/ ,则重定向到其浏览器语言设置:

<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>

Then if you want to add other language do this step again. 然后,如果您想添加其他语言,请再次执行此步骤。

My build script looks like this: 我的构建脚本如下所示:

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 , then it will create this: build en ko ja ,然后它将创建以下内容:

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

Just upload this to the web server then setup rewrite correctly. 只需将其上传到Web服务器,然后正确重写设置即可。

Hopefully you understand. 希望你能理解。 Thanks. 谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 带有 i18n 的 Angular Universal(服务器端渲染) - Angular Universal with i18n (Server Side Rendering) 如何在对象数组上实现ng xi18n - How to implement ng xi18n on array of objects Angular 9:使用 angular i18n 和服务器端渲染(angular Universal) - Angular 9: Using angular i18n along with server side rendering (angular universal) Angular 9 $localize 和 xi18n:“元数据中不支持标记模板表达式” - Angular 9 $localize and xi18n: "Tagged template expressions are not supported in metadata" 在Angular库上运行ng xi18n以生成messages.xlf会引发错误 - Running ng xi18n to generate messages.xlf on angular library throws error 如何通过多应用程序项目为分离的应用程序运行“ ng xi18n”命令? - How to run “ng xi18n” command for separated apps by Multi-App project? 添加新标签时 ng xi18n 的问题 - Problems with ng xi18n when adding new tags Angular 10: 运行 ng xi18n 时无法解析 SomeComponent (?, [object Object], [object Object]) 的所有参数 - Angular 10: Can't resolve all parameters for SomeComponent (?, [object Object], [object Object]) when running ng xi18n 何时不使用服务器端渲染-Angular Universal - When not to use Server Side rendering - Angular Universal Angular 8 通用服务器端渲染 - Angular 8 universal server side rendering
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM