使用Angular 2/Typescript/Webpack预渲染es6错误
我正在尝试使用prerender节点和专用prerender服务器来预渲染Angular2/Express应用程序。如果我尝试在tsconfig.json中以es5为目标,则预渲染服务器会抛出以下错误:使用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
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配置更改为targetweb
,而不是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服务器上测试一些页面。这还没有部署。本地测试。我确实设法让它工作了。我在下面的回答中概述了这些步骤。