我希望提供多语言角度应用程序,同时使用服务器端呈现来实现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});
});
}
我的问题是我只使用正确的base-href得到了正确的index.html,但没有得到.xlf文件中正确的翻译文本(只有组件HTML中的文本)。我在dist / server中只有一个main.js。 使用xi18n和AOT,我得到dist / browser / de和dist / browser / en。 我找不到任何教程或示例能够将xi18n和服务器端渲染角度结合起来。
我的 angular.json 有以下架构师条目:
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/server",
"main": "src/main.server.ts",
"tsConfig": "src/tsconfig.server.json"
}
}
如果有人可以帮我解决这个问题,那将会很棒。
我的角度版本是:6.0.3
提前谢谢。
拉马
答案 0 :(得分:1)
这是我为朝鲜语版本做的事情:
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
您必须从Web服务器重写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
只需将其上传到Web服务器,然后正确重写设置即可。
希望您能理解。谢谢。