使用Angular 5实现Rendertron - Firebase

时间:2018-02-19 19:26:47

标签: javascript angular firebase angular5 firebase-hosting

我正在尝试使用由Firebase托管的Angular 5网站实现Rendertron。我密切关注this tutorial。在他开始在 index.js 中实现自定义函数之前,我能够完成所有工作。他在视频中的9:12开始这个。

以下是 index.js 文件中的代码:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const express = require('express');
const fetch = require('node-fetch');
const url = require('url');
const app = express();

const appUrl = 'project-name.firebaseapp.com';
const renderUrl = 'https://render-tron.appspot.com/render';

admin.initializeApp(functions.config().firebase);

function generateUrl(request) {
  return url.format({
    protocol: request.protocol,
    host: appUrl,
    pathname: request.originalUrl
  });
}

function dectectBot(userAgent) {
  const bots = [
    'bingbot',
    'yandexbot',
    'duckduckbot',
    'slurp',

    'twitterbot',
    'facebookexternalhit',
    'linkedinbot',
    'embedly',
    'baiduspider',
    'pinterest',
    'slackbot',
    'vkShare',
    'facebot',
    'outbrain',
    'W3C_Validator'
  ]

  const agent = userAgent.toLowerCase();

  for (const bot of bots) {
    if (agent.indexOf(bot) > -1) {
      console.log('bot detected', bot, agent)
      return true
    }
  }

  console.log('no bots found')
  return false

}

app.get('*', (req, res) => {
  const isBot = dectectBot(req.headers['user-agent']);

  if (isBot) {
    const botUrl = generateUrl(req);

    fetch(`${renderUrl}/${botUrl}`)
      .then(res => res.text() )
      .then(body => {
        res.set('Cache-Control', 'public, max-age=300, s-maxage=600');
        res.set('Vary', 'User-Agent');
        res.send(body.toString());
      });
  } else {
    fetch(`https://${appUrl}`)
      .then(res => res.text())
      .then(body => {
        res.send(body.toString());
      })
  }
});

exports.app = functions.https.onRequest(app);

我在 firebase.json 文件中引用 app 变量,如下所示:

"public": "dist",
    "rewrites": [
      {
        "source": "**",
        "destination": "app"
      }
    ],

我的IDE在代码中没有显示任何错误,但是当我尝试部署函数时,我看到以下错误:

36:3   warning  Arrow function expected no return value     consistent-return
   89:5   error    Expected catch() or return                  promise/catch-or-return
   91:13  error    Each then() should return a value or throw  promise/always-return
   98:5   error    Expected catch() or return                  promise/catch-or-return
  100:13  error    Each then() should return a value or throw  promise/always-return

✖ 5 problems (4 errors, 1 warning)

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! functions@ lint: `eslint .`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the functions@ lint script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/username/.npm/_logs/2018-02-19T15_12_33_236Z-debug.log

Error: functions predeploy error: Command terminated with non-zero exit code1

我确定这不是最佳做法,但我在firebase.json文件中关闭了linter。一旦我这样做,我就可以部署功能。

但是,当我部署托管文件时,我收到以下错误:

Error: HTTP Error: 400, hosting.rewrites[0] is not exactly one from [subschema 0],[subschema 1]

我找到了以下错误解决方案:https://github.com/firebase/firebase-functions/issues/27

问题是我对Javascript和Angular很新,所以我不确定如何实现该修复。另外,我不知道lint错误是否与之相关。

2 个答案:

答案 0 :(得分:0)

您的部署脚本是什么样的?我的是

"deploy": "ng build --prod --build-optimizer && firebase deploy --only hosting && cd functions && firebase deploy --only functions"

部署后我不调用函数服务器

https://us-central1-your-project-name.cloudfunctions.net/app

(这给我的错误与你相同)

但托管服务器改为:

https://your-project-name.firebaseapp.com

答案 1 :(得分:0)

找到问题而不是目的地,您需要添加功能并指向功能名称。像这样:

"public": "dist",
   "rewrites": [
     {
    "source": "**",
    "function": "app"
  }
],

而且,修复棉绒错误基本上没有问题,因为它们基本上是在说您需要为使用的每个.catch()添加.then()