2016-11-12 2 views
2

Я пытаюсь использовать prerender-node и частный сервер prerender для предварительного запуска приложения Angular2/Express. Если я пытаюсь целевым ES5 в моем tsconfig.json, сервер PreRender выдает эту ошибку:Prerender es6 Ошибки с угловым 2/Typcript/Webpack

ReferenceError: Can't find variable: Map 

undefined:1521 in KeyRegistry 
:1540 
:7 

Если я пытаюсь целевым ES6 (включая node_modules/typescript/lib/lib.es6.d.ts в files массиве), сервер PreRender выдает эту ошибку:

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 

Я предполагаю, что мне нужно включить какой-то полиполк, чтобы это работало, но у меня нет первой идеи, что включать или куда ее включать.

Вот мой WebPack конфигурация в случае, который помогает:

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/ 
      } 
     ] 
    } 
}; 

И мой клиенту TSconfig в случае, который помогает:

{ 
    "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"] 
} 

Update

Если я изменить WebPack конфигурацию целевой web вместо node и прокомментировать server.use(prerender.removeScriptTags()); на сервере prerender, запрос обращается к серверу prerender каждый раз и ошибки не выбрасываются, но ничто не является предварительным. Кажется ближе, чем раньше, поэтому я решил обновить.

Update

Предварительно обрабатывать не похоже, чтобы выполнить любой угловой код. Если установить window.prerenderReady = false в теге сценария в голове в моей index.html, а затем попытаться установить его истинный еще раз, когда мой корневой компонент конкретизируется, время 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'); 
    } 
} 
+0

Похоже, тех Javascript ошибки предотвращения PhantomJS (лежащий в основе рендеринга) потерпеть неудачу, и остановить обработку страницы. Вы включили полифонию для Карты? 'removeScriptTags' удаляет только теги сценария после того, как страница будет выполнена, поэтому это не должно влиять на визуализацию. –

+0

Таргетинг «web» вместо «узла» в моей конфигурации webpack закрепил ошибки prerender es6. Сервер prerender возвращает 200, но не выполняется угловой код. – MyCompassSpins

+0

Есть ли какие-либо другие подробности, которые я мог бы предоставить, которые могли бы помочь получить ответ на это? – MyCompassSpins

ответ

0

мне удалось получить это работает со следующими изменениями:

Используйте target: 'web' в конфигурации Webpack.

Используйте target: 'es5' и добавьте node_modules/typescript/lib/lib.es6.d.ts в массив файлов в tsconfig.json. Это предотвращает ошибки времени компиляции на материалах es6.

Очевидно, несмотря на то, что веб-сайт и таргетинг ориентированы на веб-сайты, Webpack все еще оставляет es6 styntax вокруг того, с которым PhantomJs не справляется. Мне не нравится идея включить babel в проект Typcript, но это единственное, что я нашел, что работает: require('babel-polyfill'); ПЕРЕД другим кодом приложения или кодом поставщика, который может использовать любой синтаксис es6.

Установите window.prerenderReady = false; в head документа, а затем установить его на true при создании экземпляра компонента корня приложения:

export class ApplicationComponent implements OnInit 
{ 
    ngOnInit() 
    { 
     window.prerenderReady = true; 
    } 
} 

Примечание: для более работать в машинописном вам нужно, чтобы убедиться, свойство prerenderReady есть сверху type Window. Например:

interface Window 
{ 
    prerenderReady:boolean; 
} 

На стороне сервера убедитесь, что вы настроили prerender-node до того, как настроены любые маршруты. Например.:

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`); 
     }); 
} 

Надеется, что это помогает кто-то :)

Смежные вопросы