使用Angular 2/Typescript/Webpack预渲染es6错误

使用Angular 2/Typescript/Webpack预渲染es6错误,angular,webpack,ecmascript-6,prerender,Angular,Webpack,Ecmascript 6,Prerender,我正在尝试使用prerender节点和专用prerender服务器来预渲染Angular2/Express应用程序。如果我尝试在tsconfig.json中以es5为目标,则预渲染服务器会抛出以下错误: ReferenceError: Can't find variable: Map undefined:1521 in KeyRegistry :1540 :7 SyntaxError: Unexpected token 'const' http://localhost:3000/app.j

我正在尝试使用prerender节点和专用prerender服务器来预渲染Angular2/Express应用程序。如果我尝试在tsconfig.json中以es5为目标,则预渲染服务器会抛出以下错误:

ReferenceError: Can't find variable: Map

undefined:1521 in KeyRegistry
:1540
:7
SyntaxError: Unexpected token 'const'

http://localhost:3000/app.js:50 in eval
http://localhost:3000/app.js:50
http://localhost:3000/app.js:20 in __webpack_require__
http://localhost:3000/app.js:40
如果我试图以es6为目标(包括
文件
数组中的
节点模块/typescript/lib/lib.es6.d.ts
),预渲染服务器将抛出以下错误:

ReferenceError: Can't find variable: Map

undefined:1521 in KeyRegistry
:1540
:7
SyntaxError: Unexpected token 'const'

http://localhost:3000/app.js:50 in eval
http://localhost:3000/app.js:50
http://localhost:3000/app.js:20 in __webpack_require__
http://localhost:3000/app.js:40
我猜我需要加入某种聚填充物才能让它起作用,但我不知道应该包括什么,或者在哪里包括它

以下是我的网页配置,以备不时之需:

var webpack = require('webpack');
var path = require('path');
var rootDir = path.resolve();

module.exports =
{
    target: 'node',
    entry: rootDir + "/dist/client/app/bootstrap.js",
    output: {
        path: rootDir + "/dist/client", publicPath: '/', filename: "app.js",
        pathinfo: true
    },
    devtool: 'eval',
    resolve: {
        root: rootDir + "/dist/client/app",
        extensions: ['', '.js']
    },
    module: {
        loaders: [
            {
                test: /\.ts/, loaders: ['ts-loader'], exclude: /node_modules/
            }
        ]
    }
};
{
    "compilerOptions": {
        "target": "es6",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": false,
        "outDir": "../../dist/client",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "noImplicitAny": true
    },
    "files": ["app/bootstrap.ts", "app/vendor.ts", "app/Window.ts", "tests/index.ts", "../../node_modules/typescript/lib/lib.es6.d.ts"]
}
和我的客户tsconfig,以防有帮助:

var webpack = require('webpack');
var path = require('path');
var rootDir = path.resolve();

module.exports =
{
    target: 'node',
    entry: rootDir + "/dist/client/app/bootstrap.js",
    output: {
        path: rootDir + "/dist/client", publicPath: '/', filename: "app.js",
        pathinfo: true
    },
    devtool: 'eval',
    resolve: {
        root: rootDir + "/dist/client/app",
        extensions: ['', '.js']
    },
    module: {
        loaders: [
            {
                test: /\.ts/, loaders: ['ts-loader'], exclude: /node_modules/
            }
        ]
    }
};
{
    "compilerOptions": {
        "target": "es6",
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": false,
        "outDir": "../../dist/client",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "noImplicitAny": true
    },
    "files": ["app/bootstrap.ts", "app/vendor.ts", "app/Window.ts", "tests/index.ts", "../../node_modules/typescript/lib/lib.es6.d.ts"]
}
更新 如果我将我的webpack配置更改为target
web
,而不是
node
,并注释掉
server.use(prerender.removeScriptTags())
在预渲染服务器中,每次请求都会命中预渲染服务器,并且不会抛出错误,但也不会预渲染任何内容。看起来比以前更接近了,所以我想我应该更新一下

更新 Prerender似乎不执行任何角度代码。如果我在index.html头部的脚本标记中设置
window.prerenderrady=false
,然后在实例化根组件时再次尝试将其设置为true,则prerender服务器超时:

import { Component, OnInit } from '@angular/core'

@Component({
    selector: 'my-app',
    template: `
        <div id="main"> all the things </div>
    `
})
export class AppComponent implements OnInit
{
    constructor(){}

    ngOnInit()
    {
        // Prerender never executes this code before it times out
        window.prerenderReady = true;
        console.info('Prerender Ready');
    }
}
从'@angular/core'导入{Component,OnInit}
@组成部分({
选择器:“我的应用程序”,
模板:`
一切
`
})
导出类AppComponent实现OnInit
{
构造函数(){}
恩戈尼尼特()
{
//Prerender在超时之前从不执行此代码
window.prerenderrady=true;
console.info(“预渲染准备就绪”);
}
}

通过以下更改,我成功地实现了这一点:

在网页包配置中使用
target:'web'

使用
target:'es5'
并将
node_modules/typescript/lib/lib.es6.d.ts
添加到tsconfig.json中的文件数组中。这可以防止es6上的编译时错误

显然,尽管Webpack的目标是web和es5,但它仍然留下了幽灵JS无法处理的es6 styntax。我不喜欢在Typescript项目中包含babel的想法,但这是我发现唯一有效的方法:
require('babel-polyfill')在任何可能使用任何es6语法的应用程序代码或供应商代码之前

设置
window.prerenderrady=false标题
,然后在实例化根应用程序组件时将其设置为
true

export class ApplicationComponent implements OnInit
{
    ngOnInit()
    {
        window.prerenderReady = true;
    }
}
注意:要在Typescript中执行上述操作,您需要确保type窗口中存在属性
prerenderReady
。例如:

interface Window
{
    prerenderReady:boolean;
}
在服务器端,确保在配置任何路由之前配置prerender节点。例如:

export function routeConfig(app:express.Application):void
{
    // Prerender
    app.use(require('prerender-node').set('prerenderServiceUrl', CONFIG.prerenderServiceUrl));

    // Angular routes should return index.html
    app.route(CONFIG.angularRoutes)
        .get((req:Request, res:Response, next:NextFunction) =>
        {
            return res.sendFile(`${app.get('appPath')}/client/index.html`);
        });
}

希望这对某人有所帮助:)

看起来这些javascript错误正在阻止PhantomJS(底层呈现引擎)失败并停止呈现页面。您是否为地图添加了多边形填充
removeScriptTags
仅在页面完成渲染后删除脚本标记,这样就不会影响任何与渲染相关的内容。在我的网页包配置中以“web”而不是“节点”为目标会导致prerender es6错误。prerender服务器返回一个200,但没有执行任何角度代码。我是否可以提供任何其他详细信息,以帮助获得有关此问题的答案?您是否可以发送电子邮件给我们support@prerender.io使用您正在使用的URL?这样我们就可以在prerender服务器上测试一些页面。这还没有部署。本地测试。我确实设法让它工作了。我在下面的回答中概述了这些步骤。