如何使用Angular 2服务器端渲染

9
我已经开发了一个解析器,用于渲染我在 HTML 文件中的 Angular2 组件。到目前为止,我能够将它们呈现为 HTML:
import {Component} from 'angular2/core';
import {NgSwitch, NgSwitchWhen, NgSwitchDefault,NgFor} from 'angular2/common';
import {Http, Response} from 'angular2/http';
import {Observable} from 'rxjs/Rx';

@Component({
    selector: 'app',    
    template: `
            <div>
                <div>
                    <img src={{record}} class="pull-left image-responsive" style="width:50%;"> 
                    <img src={{record}} class="pull-right image-responsive" style="width:30%;">
                </div>
                <div>
                    <img src={{record}} class="pull-right image-responsive" style="width:100%;">
                </div>
                <br/><br/>
                <div>
                    <table class="table-responsive" style="width:100%;border-collapse:separate;border:solid #D8D8D8 2px;border-radius:5px;">
                        <tr style="background-color: grey;">
                            <th style="text-align:center;">{{record}}</th>
                            <th style="border-left:2px solid #f5821f;text-align:center;">{{record}}</th>
                        </tr>
                        <tr style="text-align:center;">
                            <td >&nbsp;</td>
                            <td style="border-left:2px solid #f5821f;">&nbsp;</td>
                        </tr>
                    </table>
                </div>
                <br/>
             </div>
           `
 })
export class App{
    public record;
    constructor() {       
        this.record="angular2";
    }
}

然后我的静态HTML可以正确生成,但如果我像这样使用我的组件:
import {Component} from 'angular2/core';
import {NgSwitch, NgSwitchWhen, NgSwitchDefault,NgFor} from 'angular2/common';
import {Http, Response} from 'angular2/http';
import {Observable} from 'rxjs/Rx';
import {Component1} from './component_1/component_1.component';
import {Component2} from './component_2/component_2.component';

@Component({
    selector: 'app',
    directives: [Component1,Component2],
    template: `
        <div class="container">
            <div class="row">
                <component_1>loading...</component_1>
            </div>
            <div class="row">
                <component_2>loading...</component_2>
            </div>             
        </div>
    `
 })
export class App{
    public record;   
    constructor() {       
        this.record="angular2";
    }
}

我的组件在HTML中正确加载,但我的静态HTML未能正确生成。请参见下面的图片:
组件在浏览器中加载 Components

但静态HTML未能正确生成 静态HTML的控制台窗口 Console for Static HTML

Server.ts

import * as path from 'path';
import * as express from 'express';
import * as universal from 'angular2-universal-preview';
// Angular 2
import {App} from './app/app.component'
let app = express();
let root = path.join(path.resolve(__dirname, '..'));

// Express View
app.engine('.ng2.html', universal.ng2engine);
app.set('views', __dirname);
app.set('view engine', 'ng2.html');

// Serve static files
app.use(express.static(root));
var i = 0;
// Routes

app.use('/', (req, res) => {
  res.render('index_new', {App}, function(err,html){
      console.log("------------------My HTML ---------\n"+(i++));
      console.log(html);
      console.log("------------------My HTML ----------");
      res.send(html);
  });
});

// Server
app.listen(3000, () => {
  console.log('Listen on http://localhost:3000');
});

index_new.ng2.html

<!doctype html>
<html lang="en">

<head>
    <link rel="icon" href="data:;base64,iVBORw0KGgo=">
    <link href="\node_modules\bootstrap\dist\css\bootstrap.min.css" rel="stylesheet" />
    <link href="\node_modules\bootstrap\dist\css\style.css" rel="stylesheet" />
    <script src="/node_modules/es6-shim/es6-shim.js"></script>
    <script src="/node_modules/es6-promise/dist/es6-promise.js"></script>
    <script src="/node_modules/reflect-metadata/Reflect.js"></script>
    <script src="/node_modules/zone.js/dist/zone-microtask.js"></script>
    <script src="/node_modules/zone.js/dist/long-stack-trace-zone.js"></script>
    <script src="/dist/client/bundle.js"></script>    
</head>
<body>
    <app>Loading....</app>    
</body>
</html>

我尝试了@alexpods的更新后的GitHub仓库,提前感谢。
2个回答

4
我曾经遇到过与universal-starter-kit相同的问题。可以尝试https://github.com/pmachowski/angular2-starter-kit优点:
  • 服务器端渲染实际上可行
  • Web Worker
  • 生产就绪
  • 良好的结构
  • 正在积极开发中
  • 现代堆栈(webpack,karma,protractor)
  • 单元测试和端到端测试


1
@BhushanGadekar 我看到你在使用Windows。我在Mac上,node_modules没有问题。如果你能发布错误信息,我可以帮忙解决。 - Peter Machowski
typings ERR! message Unable to resolve "github:typings/typed-es6-promise" \n typings ERR! caused by Unable to connect to "https://raw.githubusercontent.com/typings/typed-es6-promise/master/typings.json" \n typings ERR! caused by getaddrinfo ENOTFOUND proxy.example.com - Bhushan Gadekar
1
@BhushanGadekar 你好。这是typings库中的一个错误。我已经更新了依赖项并将es6-promise移动到环境模块定义中。现在应该可以正常工作了。试一下,如果由于任何原因它不能正常工作,请告诉我。 - alexpods
@alexpods,现在它可以工作了...但我不确定我的静态HTML生成在哪里?在控制台上没有显示任何内容。 - Bhushan Gadekar
@alexpods 我遇到了这个错误,ERROR in C:\Users\Bhushan.Gadekar\Downloads\angular2-universal-starter-master\angular2-universal-starter-master\node_modules\angular2\src\mock\mock_applicat ion_ref.d.ts (12,80): error TS2304: Cannot find name 'Promise'.,但应用程序已经在浏览器中加载了。你能告诉我我的静态HTML生成或保存在哪里吗? - Bhushan Gadekar
显示剩余6条评论

1

请看我最近部署的示例应用程序https://github.com/ng-seed/universal)。

优点:

  • 服务器端渲染
  • SCSS编译
  • 延迟/异步路由
  • 开发/生产(AoT)编译
  • SPA /通用模式
  • TsLint/Codelyzer
  • 最新依赖项(Angular 4,platform-server等)
  • 现代堆栈(webpack,karma,protractor)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接