我已经为Angular 5实现了Angular Universal。一切都编译得很好。我看到通用工作的唯一地方(视图源中带有html的html)是在静态页面中,即没有从服务器获取数据的地方。在页面的视图源中未显示具有通过解析或任何其他方式获取的数据的视图。我不太确定自己缺少什么。你能帮忙吗?
下面是具有来自服务器的数据的页面视图源的屏幕截图。
任何人都可以调查此问题。过去一周一直被困在这个位置。没有结果。
下面是我的文件。
1。 angular-cli.json
{
"$schema":"./node_modules/@angular/cli/lib/config/schema.json",
"project":{
"name":"project"
},
"apps":[
{
"root":"src",
"outDir":"dist/browser",
"assets":[
"assets",
"favicon.ico"
],
"index":"index.html",
"main":"main.ts",
"polyfills":"polyfills.ts",
"test":"test.ts",
"tsconfig":"tsconfig.app.json",
"testTsconfig":"tsconfig.spec.json",
"prefix":"app",
"styles":[
],
"scripts":[
],
"environmentSource":"environments/environment.ts",
"environments":{
"dev":"environments/environment.ts",
"stag":"environments/environment.stag.ts",
"prod":"environments/environment.prod.ts"
}
},
{
"platform":"server",
"root":"src",
"outDir":"dist/server",
"assets":[
"assets",
"favicon.ico"
],
"index":"index.html",
"main":"main.server.ts",
"test":"test.ts",
"tsconfig":"tsconfig.server.json",
"testTsconfig":"tsconfig.spec.json",
"prefix":"app",
"styles":[
"styles.css"
],
"scripts":[
],
"environmentSource":"environments/environment.ts",
"environments":{
"dev":"environments/environment.ts",
"stag":"environments/environment.stag.ts",
"prod":"environments/environment.prod.ts"
}
}
]
}
2。 server.ts
import "zone.js/dist/zone-node";
import "reflect-metadata";
import {
renderModuleFactory
} from "@angular/platform-server";
import {
enableProdMode
} from "@angular/core";
import * as express from "express";
import {
join
} from "path";
import {
readFileSync
} from "fs";
// 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");
// Our index.html we'll use as our template
const template = readFileSync(
join(DIST_FOLDER, "browser", "index.html")
).toString();
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {
AppServerModuleNgFactory,
LAZY_MODULE_MAP
} = require("./dist/server/main.bundle");
// Express Engine
import {
ngExpressEngine
} from "@nguniversal/express-engine";
// Import module map for lazy loading
import {
provideModuleMap
} from "@nguniversal/module-map-ngfactory-loader";
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine(
"html",
ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [provideModuleMap(LAZY_MODULE_MAP)]
})
);
app.set("view engine", "html");
app.set("views", join(DIST_FOLDER, "browser"));
/* - Example Express Rest API endpoints -
app.get('/api/**', (req, res) => { });
*/
// Server static files from /browser
app.get(
"*.*",
express.static(join(DIST_FOLDER, "browser"), {
maxAge: "1y"
})
);
// ALl regular routes use the Universal engine
app.get("*", (req, res) => {
res.render("index", {
req
});
});
// Start up the Node server
app.listen(PORT, () => {
console.log(`Node Express server listening on http://localhost:${PORT}`);
});
3。 prerender.ts
// Load zone.js for the server.
import "zone.js/dist/zone-node";
import "reflect-metadata";
import {
readFileSync,
writeFileSync,
existsSync,
mkdirSync
} from "fs";
import {
join
} from "path";
import {
chdir
} from "process";
import {
enableProdMode
} from "@angular/core";
const domino = require("domino");
const fs = require("fs");
const path = require("path");
const templateA = fs
.readFileSync(path.join("..", "dist/browser", "index.html"))
.toString();
const win = domino.createWindow(templateA);
win.Object = Object;
win.Math = Math;
global["window"] = win;
global["document"] = win.document;
global["branch"] = null;
global["object"] = win.object;
// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();
// Express Engine
import {
ngExpressEngine
} from "@nguniversal/express-engine";
// Import module map for lazy loading
import {
provideModuleMap
} from "@nguniversal/module-map-ngfactory-loader";
import {
renderModuleFactory
} from "@angular/platform-server";
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {
AppServerModuleNgFactory,
LAZY_MODULE_MAP
} = require("./dist/server/main.bundle");
// Get route paths to prerender only static pages
const PATHS = require("./static.paths");
const BROWSER_FOLDER = join(process.cwd(), "browser");
// Load the index.html file containing referances to your application bundle.
const index = readFileSync(join("browser", "index.html"), "utf8");
let prom = Promise.resolve();
// Iterate each route path
PATHS.forEach(function(route) {
// Changes current directory to ./dist/browser
chdir(BROWSER_FOLDER);
// Creates new directories (if not exists) and changes current directory for the nested one
route
.split("/")
.filter(val => val !== "")
.forEach(function(dir) {
if(!existsSync(dir)) {
mkdirSync(dir);
}
chdir(dir);
});
// Writes rendered HTML to index.html, replacing the file if it already exists.
prom = prom
.then(_ =>
renderModuleFactory(AppServerModuleNgFactory, {
document: index,
url: route,
extraProviders: [
[provideModuleMap(LAZY_MODULE_MAP)]
]
})
)
.then(html =>
writeFileSync(join(BROWSER_FOLDER, route, "index.html"), html)
);
});
4。 package.json
{
"name":"sirved",
"version":"0.0.0",
"license":"MIT",
"scripts":{
"ng":"ng",
"start":"ng serve",
"build":"ng build --prod",
"test":"ng test",
"lint":"ng lint",
"e2e":"ng e2e",
"build:client-and-server-bundles":"ng build --prod && ng build --prod --app 1 --output-hashing=false",
"build:static":"npm run build:client-and-server-bundles && npm run webpack:server && npm run generate:static",
"build:dynamic":"npm run build:client-and-server-bundles && npm run webpack:server",
"generate:static":"cd dist && node prerender",
"webpack:server":"webpack --config webpack.server.config.js --progress --colors",
"serve:static":"cd dist/browser && http-server",
"serve:dynamic":"node dist/server"
},
"private":true,
"dependencies":{
"@agm/core":"^1.0.0-beta.3",
"@angular/animations":"^5.2.11",
"@angular/common":"^5.2.0",
"@angular/compiler":"^5.2.0",
"@angular/core":"^5.2.0",
"@angular/forms":"^5.2.0",
"@angular/http":"^5.2.0",
"@angular/platform-browser":"^5.2.0",
"@angular/platform-browser-dynamic":"^5.2.0",
"@angular/platform-server":"^5.2.0",
"@angular/router":"^5.2.0",
"@nguniversal/express-engine":"^5.0.0-beta.1",
"@nguniversal/module-map-ngfactory-loader":"^5.0.0-beta.1",
"@types/jquery":"^3.3.4",
"core-js":"^2.4.1",
"zone.js":"^0.8.19"
},
"devDependencies":{
"@angular/cli":"~1.7.4",
"@angular/compiler-cli":"^5.2.0",
"@angular/language-service":"^5.2.0",
"@types/googlemaps":"^3.30.11",
"@types/jasmine":"~2.8.3",
"@types/jasminewd2":"~2.0.2",
"@types/node":"~6.0.60",
"codelyzer":"^4.0.1",
"jasmine-core":"~2.8.0",
"jasmine-spec-reporter":"~4.2.1",
"karma":"~2.0.0",
"karma-chrome-launcher":"~2.2.0",
"karma-coverage-istanbul-reporter":"^1.2.1",
"karma-jasmine":"~1.1.0",
"karma-jasmine-html-reporter":"^0.2.2",
"protractor":"~5.1.2",
"ts-node":"~4.1.0",
"tslint":"~5.9.1",
"typescript":"~2.5.3",
"ts-loader":"^2.3.7"
}
}
我完成的工作与角度通用启动器项目完全相同,但没有得到所需的结果。任何人都可以调查一下!