使用Angular Universal的Firebase云函数

姓名:ちきさん
所属:オプト
GitHub/Twitter/Qiita: @ovrmrw

姓名:ちきさん
所属:オプト
GitHub/Twitter/Qiita:@ovrmrw


本次的GitHub仓库


参考来源


我想尝试使用Angular Universal。


需要Express…


我喜欢Firebase,想在Firebase Hosting上使用Angular Universal。


Firebase Hosting不允许托管Express应用程序…


也许在Firebase的云功能中可能有机会…!


安装Angular CLI 1.3.0-rc.3及以上版本和Firebase CLI。

$ npm install -g @angular/cli@next firebase-tools

用 ng new 命令创建一个新项目。

$ ng new angular-universal-with-firebase-hosting

将其设为Firebase项目。

$ cd angular-universal-with-firebase-hosting
$ firebase init

※主机和函数是必需的。其他设置如下所示。

Do you want to install dependencies with npm now? (Y/n): N
What do you want to use as your public directory? (public): public
Configure as a single-page app (rewrite all urls to /index.html): Y

安装 @angular/platform-server。

$ npm install --save-dev @angular/platform-server

编辑src/app/app.module.ts。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    // BrowserModule
    BrowserModule.withServerTransition({ appId: 'my-app' }) // ←ここ
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

添加 src/app/app.server.module.ts。

import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';

import { AppModule } from './app.module';
import { AppComponent } from './app.component';

@NgModule({
  imports: [
    AppModule, // ←ここにAppModuleを入れる。
    ServerModule,
  ],
  bootstrap: [AppComponent],
})
export class AppServerModule { }

添加src/main.server.ts。

import { enableProdMode } from '@angular/core';
export { AppServerModule } from './app/app.server.module';

enableProdMode();

添加 src / tsconfig.server.json。

{
  "extends": "./tsconfig.app.json",
  "compilerOptions": {
    "module": "commonjs"
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts"
  ],
  "angularCompilerOptions": {
    "entryModule": "app/app.server.module#AppServerModule"
  }
}

编辑angular-cli.json。

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "project": {
    "name": "angular-universal-with-firebase-hosting"
  },
  "apps": [
    {
      .......
    },
    {
      "platform": "server",
      "root": "src",
      "outDir": "functions/dist-server",
      "assets": [
        "assets",
        "favicon.ico"
      ],
      "index": "index.html",
      "main": "main.server.ts",
      "test": "test.ts",
      "tsconfig": "tsconfig.server.json",
      "testTsconfig": "tsconfig.spec.json",
      "prefix": "app",
      "styles": [
        "styles.css"
      ],
      "scripts": [],
      "environmentSource": "environments/environment.ts",
      "environments": {
        "dev": "environments/environment.ts",
        "prod": "environments/environment.prod.ts"
      }
    }
  ],
  .......
}

将 src/index.html 复制到 functions/dist-server 目录中。

$ cp src/index.html functions/dist-server

编辑 functions/package.json 的依赖项。然后切换到函数目录并运行 npm install。


{
  "name": "functions",
  "description": "Cloud Functions for Firebase",
  "dependencies": {
    "firebase-admin": "~4.2.1",
    "firebase-functions": "^0.5.7",
    "@angular/animations": "^4.0.0",
    "@angular/common": "^4.0.0",
    "@angular/compiler": "^4.0.0",
    "@angular/core": "^4.0.0",
    "@angular/forms": "^4.0.0",
    "@angular/http": "^4.0.0",
    "@angular/platform-browser": "^4.0.0",
    "@angular/platform-browser-dynamic": "^4.0.0",
    "@angular/platform-server": "^4.0.0",
    "@angular/router": "^4.0.0",
    "core-js": "^2.4.1",
    "express": "^4.15.3",
    "rxjs": "^5.4.2",
    "zone.js": "^0.8.16"
  }
  "private": true
}

编辑 functions/index.js。

require('zone.js/dist/zone-node');
const functions = require('firebase-functions');
const express = require('express');
const path = require('path')

const renderModuleFactory = require('@angular/platform-server').renderModuleFactory;

const AppServerModuleNgFactory = require('./dist-server/main.bundle').AppServerModuleNgFactory;

const index = require('fs').readFileSync(path.resolve(__dirname, './dist-server/index.html'), 'utf8');

const app = express();

app.get('/', (req, res) => {
  renderModuleFactory(AppServerModuleNgFactory, { document: index, url: '/' })
  .then(html => {
    res.send(html);
  })
  .catch(err => {
    console.log(err)
  });
});

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

编辑 firebase.json 文件。

{
  "hosting": {
    "public": "public",
    "rewrites": [
      {
        "source": "**",
        "function": "ssr"
      }
    ]
  }
}

添加一个public文件夹,并将一个名为hoge.css的空文件放置在其中。

由于文件夹中没有任何文件,因此无法将该文件夹部署到Firebase Hosting。(因为没有文件,所以无法将该文件夹部署到Firebase Hosting。)


编辑package.json文件中的scripts部分。

{
  "scripts": {
    .....,
    "build": "ng build --prod --app 1 --output-hashing=none",
    "copy": "cp src/index.html functions/dist-server", 
    "deploy": "npm run build && npm run copy && firebase deploy",
    .....
  }
}

部署。

$ npm run deploy

确认行动


虽然可能存在一些问题,但详细情况我并不清楚。


谢谢

bannerAds