Angular 2 Universal:Prerender不适用于templateUrl或styleUrls

时间:2016-08-05 22:50:25

标签: angular angular2-universal

我一直在使用Angular 2 通用进行服务器端预渲染。

但是具有直接html模板并通过 templateUrl 引用它们的组件不会预渲染(仅通过url。使用模板:' ...'一切都很好),但是客户端仍然加载。我使用 asp.net核心服务器和 system.js

package.json的一部分:

"dependencies": {
    "@angular/common": "^2.0.0-rc.4",
    "@angular/compiler": "^2.0.0-rc.4",
    "@angular/core": "^2.0.0-rc.4",
    "@angular/forms": "^0.2.0",
    "@angular/http": "^2.0.0-rc.4",
    "@angular/platform-browser": "^2.0.0-rc.4",
    "@angular/platform-browser-dynamic": "^2.0.0-rc.4",
    "@angular/platform-server": "^2.0.0-rc.4",
    "@angular/router": "^3.0.0-alpha.8",
    "angular2-express-engine": "^0.15.3",
    "angular2-hapi-engine": "^0.15.0",
    "angular2-universal": "^0.104.5",
    "angular2-universal-polyfills": "^0.4.1",
    "aspnet-prerendering": "^1.0.1",
    "bootstrap": "^3.3.5",
    "css": "^2.2.1",
    "es6-module-loader": "^0.17.11",
    "es6-shim": "^0.35.0",
    "isomorphic-fetch": "^2.2.1",
    "less": "^2.5.3",
    "parse5": "^1.5.0",
    "path": "^0.12.7",
    "preboot": "^2.1.2",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.6",
    "systemjs": "^0.19.3",
    "traceur": "0.0.111",
    "zone.js": "^0.6.12"
  },

引导server.ts:

import 'angular2-universal/polyfills';

import { APP_BASE_HREF } from '@angular/common';
import * as ngCore from '@angular/core';
import * as ngRouter from '@angular/router';

import * as ngUniversal from 'angular2-universal';
import { BASE_URL, ORIGIN_URL, REQUEST_URL } from 'angular2-universal/common';

import { AppComponent } from './components/app.component';
import { routes } from './components/app.routes';


const bootloader = ngUniversal.bootloader({
    async: true,
    preboot: false,
    platformProviders: [
        ngCore.provide(APP_BASE_HREF, { useValue: '/' }),
    ]
});

export default function (params: any): Promise<{ html: string, globals?: any }> {
    const config: ngUniversal.AppConfig = {
        directives: [AppComponent],
        providers: [
            ngCore.provide(ORIGIN_URL, { useValue: params.origin }),
            ngCore.provide(REQUEST_URL, { useValue: params.url }),
            ...ngUniversal.NODE_HTTP_PROVIDERS,
            ngRouter.provideRouter(routes),
            ...ngUniversal.NODE_LOCATION_PROVIDERS,
        ],
        // TODO: Render just the <app> component instead of wrapping it inside an extra HTML document
        // Waiting on https://github.com/angular/universal/issues/347
        template: '<!DOCTYPE html>\n<html><head></head><body><app></app></body></html>'
    };

    return bootloader.serializeApplication(config).then(html => {
        return { html };
    });
}

Index.cshtml:

<app asp-prerender-module="wwwroot/app/boot-server">Loading...</app>

@section scripts {
    <script src="~/lib/zone.js/dist/zone.min.js"></script>
    <script src="~/lib/reflect-metadata/Reflect.js"></script>

    <script src="~/lib/traceur/bin/traceur-runtime.js"></script>
    <script src="~/lib/systemjs/dist/system.src.js"></script>
    <script src="~/system.config.js"></script>

    <script src="~/lib/rxjs/bundles/Rx.js"></script>
    <script>System.import('./app/boot-client');</script>
}

app.component.ts:

import * as ng from '@angular/core';
import * as router from '@angular/router';

@ng.Component({
    selector: 'app',
    templateUrl: './app/components/app.template.html',
    directives: [router.ROUTER_DIRECTIVES]
})
export class AppComponent {
}

app.routes.ts

import { RouterConfig } from '@angular/router';

import { HomeComponent } from './home/home.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { SignInComponent } from './signin/signin.component';
import { SignUpComponent } from './signup/signup.component';
import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component';

export const routes: RouterConfig = [
  { path: '', component: HomeComponent },
  { path: 'dashboard', component: DashboardComponent },
  { path: 'sign-in', component: SignInComponent },
  { path: 'sign-up', component: SignUpComponent },
  { path: '**', component: PageNotFoundComponent }
];

home.component.ts:

import * as ng from '@angular/core';

@ng.Component({
    templateUrl: './app/components/home/home.template.html',    
})
export class HomeComponent {
}

app.template.html:

<router-outlet></router-outlet>

<div *ngIf="globalErrors" class="container">
    <div *ngIf="globalErrors.length > 0" class="alert alert-danger fade in">
        <a (click)="clearErrors()" class="close" aria-label="close">&times;</a>
        error...
    </div>
</div>
content of app.component.ts

home.template.html:

<h1>Hello, world!</h1>
<p>Welcome to your new single-page application, built with:</p>
<ul>
    <li><a href='https://get.asp.net/'>ASP.NET Core</a> and <a href='https://msdn.microsoft.com/en-us/library/67ef8sbd.aspx'>C#</a> for cross-platform server-side code</li>
    <li><a href='https://angular.io/'>Angular 2</a> and <a href='http://www.typescriptlang.org/'>TypeScript</a> for client-side code</li>
    <li><a href='https://webpack.github.io/'>Webpack</a> for building and bundling client-side resources</li>
    <li><a href='http://getbootstrap.com/'>Bootstrap</a> for layout and styling</li>
</ul>
<p>To help you get started, we've also set up:</p>
<ul>
    <li><strong>Client-side navigation</strong>. For example, click <em>Counter</em> then <em>Back</em> to return here.</li>
    <li><strong>Server-side prerendering</strong>. For faster initial loading and improved SEO, your Angular 2 app is prerendered on the server. The resulting HTML is then transferred to the browser where a client-side copy of the app takes over.</li>
    <li><strong>Webpack dev middleware</strong>. In development mode, there's no need to run the <code>webpack</code> build tool. Your client-side resources are dynamically built on demand. Updates are available as soon as you modify any file.</li>
    <li><strong>Hot module replacement</strong>. In development mode, you don't even need to reload the page after making most changes. Within seconds of saving changes to files, your Angular 2 app will be rebuilt and a new instance injected is into the page.</li>
    <li><strong>Efficient production builds</strong>. In production mode, development-time features are disabled, and the <code>webpack</code> build tool produces minified static CSS and JavaScript files.</li>
</ul>

html为空

但我们可以看到服务器端成功请求

1 个答案:

答案 0 :(得分:0)

尝试将模板更改为相对模板

@Component({ 
   template: require('./home.template.html')
})