在 Firebase 上部署 Angular 8 Universal (SSR) 应用程序

mis*_*ing 4 firebase google-cloud-functions angular-universal angular

我最近将我的 Angular 8 应用程序升级为通用应用程序 (SSR)。在它成为 SSR 应用程序之前,我已将其部署到 Firebase,但后来我发现使用常规 Firebase 托管无法在 Firebase 上部署 SSR 应用程序。我做了一些研究,发现我必须使用Firebase Cloud Functions

我使用以下方法创建了一个 SSR 应用程序:

ng add @nguniversal/express-engine --clientProject PROJECT_NAME
Run Code Online (Sandbox Code Playgroud)

PROJECT_NAME可以在angular.json下面的文件中找到"projects"

谁能帮我这个?

mis*_*ing 14

重要说明:此解决方案取自 Udemy 上 Angular 课程的问答部分(此处)。我试了一下,并通过一些修改设法使它工作。


因此,首先通过运行npm run build:ssr和来确保 SSR 确实有效npm run serve:ssr

然后安装 Firebase Tools 并初始化项目:

  • 如果您之前没有安装 Firebase 命令行工具,请运行 npm install -g firebase-tools
  • 运行firebase login,根据要求提供您的 Firebase 凭据(电子邮件/密码)。
  • firebase init

回答一些问题...

  • “你准备好继续了吗?”

    键入y并按 ENTER。

  • “您要设置哪些 Firebase CLI 功能?”

    选择 ...

    (*) Functions
    
    (*) Hosting
    
    Run Code Online (Sandbox Code Playgroud)

    ... ,使用空格键选择两者,然后按 ENTER。

  • “为这个目录选择一个默认的 Firebase 项目?”

    使用箭头键选择一个,然后按 ENTER。

  • “您想用什么语言来编写 Cloud Functions?”

    TypeScript使用箭头键选择并按 ENTER。

  • “你要使用 TSLint 吗?”

    键入y并按 ENTER。

  • “您现在要使用 npm 安装依赖项吗?”

    键入y并按 ENTER。

  • “你想用什么作为你的公共目录?”

    键入dist/browser并按Enter键(请注意:这是从部署没有通用的应用程序不同的!)。

  • “配置为单页应用程序?”

    键入y并按 ENTER。

  • 文件 index.html 已经存在。覆盖?

    输入n(重要!)并按回车键。

修改一些文件...

  • firebase.json替换"destination": "/index.html""function": "ssr"

    ssr指向这个export const ssr = functions.https.onRequest(universal);变量,你会在下面找到它)。

  • server.ts添加exportapp初始化:export const app = express();而不是const app = express();

  • server.ts中注释掉最后三行 ( app.listen(...)) 或将它们替换为以下内容:

(*) Functions

(*) Hosting
Run Code Online (Sandbox Code Playgroud)

  您可以在部署到 Firebase 时删除它们,但在运行时需要它们npm run serve:ssr才能在localhost.

  • webpack.server.config.js 中修改output如下:
    // If we're not in the Cloud Functions environment, spin up a Node server
    if (!process.env.FUNCTION_NAME) {
        // Start up the Node server
        app.listen(PORT, () => {
            console.log(`Node Express server listening on http://localhost:${PORT}`);
        });
    }
Run Code Online (Sandbox Code Playgroud)

  并externals像这样修改:

    output: {
        // Puts the output at the root of the dist folder
        path: path.join(__dirname, 'dist'),
        // Export a UMD of the webpacked server.ts & dependencies for rendering in Cloud Functions
        library: 'app',
        libraryTarget: 'umd',
        filename: '[name].js',
    },
Run Code Online (Sandbox Code Playgroud)

  这将修复一个错误:

找不到模块 'require("./server/main")'

  运行npm run serve:ssrfirebase serve命令时。

  • 通过运行重新构建您的应用程序npm run build:ssr

  • 使用终端移动到函数文件夹: cd functions

  • 安装用于文件系统访问的 npm 包: npm i fs-extra

  • 函数文件夹中创建一个名为copy-angular-app.js的新文件,内容如下:

    const fs = require('fs-extra');
    fs.copy('../dist', './dist').then(() => {
        // We should remove the original "index.html" since Firebase will use it when SSR is enabled (instead of calling SSR functions),
        // and because of that, SSR won't work for the initial page.
        fs.remove('../dist/browser/index.html').catch(e => console.error('REMOVE ERROR: ', e));
    }).catch(err => {
        console.error('COPY ERROR: ', err)
    });
Run Code Online (Sandbox Code Playgroud)

  这修复了未作为 SSR 加载的初始页面(而不是显示它仍在显示的初始页面的内容<app-root></app-root>)。

  注意:由于我们删除了index.html文件,npm run serve:ssr除非您首先重建您的应用程序(通过运行npm run build:ssr-> 这将重新创建index.html文件),否则运行将不起作用。

  • functions/package.json(不在项目的 package.json 中!)像这样更改构建条目:

"build": "node copy-angular-app && tsc",

  • functions/src/index.ts中用这个替换内容:
    import * as functions from 'firebase-functions';

    const universal = require(`${process.cwd()}/dist/server`).app;
    export const ssr = functions.https.onRequest(universal);
Run Code Online (Sandbox Code Playgroud)
  • 在终端中确保您位于函数目录中,然后运行npm run builddist文件夹复制到文件functions夹中。

附加说明:为了更轻松地构建 Firebase,您可以在主项目的package.json文件中创建一个脚本:

    "build:ssr": "npm run build:client-and-server-bundles && npm run compile:server", // this one should already exist
    "build:ssr-firebase": "npm run build:ssr && npm --prefix functions/ run build",
Run Code Online (Sandbox Code Playgroud)

此脚本将首先构建您的 Angular SSR 应用程序 ( npm run build:ssr),然后它将npm run build在您的函数文件夹中运行(这样它会将项目的dist文件夹复制到您的函数 dist文件夹并删除项目的index.html文件)。

部署您的应用...

  • 您可以在部署之前在localhost:5000 上通过运行firebase serve(如果需要)在本地为您的应用程序提供服务。

  • 停止服务器 (Ctrl + C)。

  • 然后您可以通过运行部署应用程序firebase deploy并通过终端中显示的 url 访问它。

通过这种方式,我设法在 Firebase 上部署了我的 Angular SSR 应用程序。

希望这可以帮助...

  • 这是一次非常有趣的冒险。谢谢 !! (2认同)