如何设置 Angular CLI + Angular Universal?

10

有没有人在使用angular cli项目中安装过angular universal?

我尝试按照这个指南操作:

https://universal.angular.io/quickstart/

但在执行完这些步骤后:

typings install node express body-parser serve-static express-serve-static-core mime --global

我遇到了错误:

typings INFO globaldependencies "express" lists global dependencies on "node" that must be installed manually
typings ERR! message Unable to find "node" ("npm") in the registry.
typings ERR! message However, we found "node" for 2 other sources: "dt" and "env"
typings ERR! message You can install these using the "source" option.
typings ERR! message We could use your help adding these typings to the registry: https://github.com/typings/registry
typings ERR! caused by https://api.typings.org/entries/npm/node/versions/latest responded with 404, expected it to equal 200
typings ERR! 
typings ERR! cwd /home/universal
typings ERR! system Linux 3.10.17
typings ERR! command "/usr/bin/node" "/usr/bin/typings" "install" "node" "express" "body-parser" "serve-static" "express-serve-static-core" "mime" "--global"
typings ERR! node -v v4.2.4
typings ERR! typings -v 2.0.0
typings ERR! 
typings ERR! If you need help, you may report this error at:
typings ERR!   <https://github.com/typings/typings/issues>
3个回答

10
Angular Cli现在支持1.3.0-rc.0及以上版本。

您可以使用以下命令安装此版本:

npm install -g @angular/cli


来自Angular Cli Wiki关于通用渲染的设置说明

我有一个演示应用程序,可以在GitHub上找到

源代码: https://github.com/joejordanbrown/angular-cli-universal

在线演示: https://uixd.co.uk/open-source-software/angular-cli-universal/


步骤1:创建新的Angular Cli应用程序

$ ng new angular-cli-universal

步骤2:安装@angular/platform-server

将@angular/platform-server安装到您的项目中。确保使用与项目中其他@angular包相同的版本。

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

或者

$ yarn add @angular/platform-server

步骤3:为您的应用程序准备通用渲染

您需要做的第一件事是通过添加.withServerTransition()和应用程序ID来使您的AppModule与通用模式兼容,以便在BrowserModule导入时使用:

src/app/app.module.ts:

@NgModule({
  bootstrap: [AppComponent],
  imports: [
    // Add .withServerTransition() to support Universal rendering.
    // The application ID can be any identifier which is unique on
    // the page.
    BrowserModule.withServerTransition({appId: 'my-app'}),
    ...
  ],

})
export class AppModule {}

接下来,在服务器上运行时,创建一个专门为您的应用程序而设计的模块。建议将此模块命名为AppServerModule。
例如,将其与app.module.ts放置在同一文件夹中,命名为app.server.module.ts:

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: [
    // The AppServerModule should import your AppModule followed
    // by the ServerModule from @angular/platform-server.
    AppModule,
    ServerModule,
  ],
  // Since the bootstrapped component is not inherited from your
  // imported AppModule, it needs to be repeated here.
  bootstrap: [AppComponent],
})
export class AppServerModule {}

步骤4:创建服务器主文件和tsconfig进行构建

创建您的Universal bundle的主文件。此文件只需要导出您的AppServerModule即可,它可以放在src目录下。本示例将此文件命名为main.server.ts:

src/main.server.ts:

export {AppServerModule} from './app/app.server.module';

将tsconfig.app.json复制到tsconfig-server.json,并将其更改为使用“commonjs”目标的“module”构建。
添加一个“angularCompilerOptions”部分,并将“entryModule”设置为您的AppServerModule,指定为包含符号名称的哈希(#)导入路径。在这个例子中,这将是src/app/app.server.module#AppServerModule。

src/tsconfig.server.json:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "baseUrl": "./",
    // Set the module format to "commonjs":
    "module": "commonjs",
    "types": []
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts"
  ],
  // Add "angularCompilerOptions" with the AppServerModule you wrote
  // set as the "entryModule".
  "angularCompilerOptions": {
    "entryModule": "app/app.server.module#AppServerModule"
  }
}

步骤 5:创建一个 NodeJS 服务器文件 您需要创建一个 NodeJS 服务器来呈现和提供应用程序。此示例使用 express。

安装 express 和 compression。

$ npm install --save express compression @nguniversal/express-engine

或者

$ yarn add express compression @nguniversal/express-engine

src/express.server.js:

const path = require('path');
const fs = require('fs');
const express = require('express');
const compression = require('compression');
const ngExpressEngine = require('@nguniversal/express-engine').ngExpressEngine;

require('zone.js/dist/zone-node');
require('rxjs/add/operator/filter');
require('rxjs/add/operator/map');
require('rxjs/add/operator/mergeMap');

var hash;
fs.readdirSync(__dirname).forEach(file => {
  if (file.startsWith('main')) {
    hash = file.split('.')[1];
  }
});

const AppServerModuleNgFactory = require('./main.' + hash + '.bundle').AppServerModuleNgFactory;

const app = express();
const port = Number(process.env.PORT || 8080);

app.engine('html', ngExpressEngine({
  baseUrl: 'http://localhost:' + port,
  bootstrap: AppServerModuleNgFactory
}));


app.set('view engine', 'html');
app.set('views', path.join(__dirname, '/../browser'));

app.use(compression());
app.use('/', express.static(path.join(__dirname, '/../browser'), {index: false}));


app.get('/*', function (req, res) {
  res.render('index', {
    req: req,
    // res: res
  });
});

app.listen(port, function() {
  console.log(`Listening at ${port}`);
});

步骤6:在.angular-cli.json中创建新项目

.angular-cli.json文件中有一个键为“apps”的数组。将客户端应用程序的配置复制到该数组中,并将其作为新条目粘贴到数组中,添加一个额外的键“platform”,并将其设置为“server”。

然后,删除“polyfills”键 - 服务器不需要它们,并调整“main”和“tsconfig”以指向您在步骤2中编写的文件。最后,将“outDir”调整为新位置(此示例使用dist/server)。

.angular-cli.json:

{
  ...
  "apps": [
    {
      // Keep your original application config the same apart from changing outDir to dist/browser.
      // It will be app 0.
      "outDir": "dist/browser",
    },
    {
      // This is your server app. It is app 1.
      "platform": "server",
      "root": "src",
      // Build to dist/server instead of dist. This prevents
      // client and server builds from overwriting each other.
      "outDir": "dist/server",
      "assets": [
        "assets",
        "favicon.ico",
        "express.server.js"
      ],
      "index": "index.html",
      // Change the main file to point to your server main.
      "main": "main.server.ts",
      // Remove polyfills.
      // "polyfills": "polyfills.ts",
      "test": "test.ts",
      // Change the tsconfig to point to your server config.
      "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"
      }
    }
  ],
  ...
}

构建捆绑包

完成这些步骤后,您应该能够使用 --app 标志告诉 CLI 构建服务器捆绑包,并在 .angular-cli.json 的 "apps" 数组中引用其索引为 1 的位置来为应用程序构建服务器捆绑包:

# This builds the client application in dist/browser/
$ ng build --prod
...
# This builds the server bundle in dist/server/
$ ng build --prod --app 1
Date: 2017-07-24T22:42:09.739Z
Hash: 9cac7d8e9434007fd8da
Time: 4933ms
chunk {0} main.988d7a161bd984b7eb54.bundle.js (main) 9.49 kB [entry] [rendered]
chunk {1} styles.d41d8cd98f00b204e980.bundle.css (styles) 0 bytes [entry] [rendered]

启动 Express 服务器

$ node dist/server/express.server.js

查看 Angular Cli Wiki 以获取更多详细信息 https://github.com/angular/angular-cli/wiki/stories-universal-rendering

谢谢,伙计。这对我真的有用...终于...经过漫长的奋斗...在你的帖子中缺少npm install @nguniversal/express-engine --save!;) - DS_web_developer
这很好,一开始我花了一些时间来玩弄它,使其与express服务器配合工作。因为他们实际上没有提供那部分,这真是遗憾。谢谢,我会将@nguniversal/express-engine添加到服务器的安装部分。 - J J B
我在这里创建了一个最小/骨架Angular Universal应用程序。https://github.com/gopivignesh/angular-universal。这个源代码可以作为构建新的Angular Universal项目的良好基础。 - gvm
我在构建项目时遇到了一个错误。"找不到本地工作区文件('angular.json')"。 - Kamuran Sönecek
1
@KamuranSönecek,这与v6中的新@angular/cli有关,他们将配置文件重命名为angular.json。你运行过ng update吗?我的答案在这里可以帮助你https://dev59.com/l-k6XIcBkEYKwwoYAfCc#41403927,你应该运行`ng update @angular/cli --migrate-only --from=1`。 - J J B

1
您可以使用https://github.com/devCrossNet/angular-cli中的universal-cli。
它是从angular-cli分支出来,但可以与angular universal一起使用。
安装后,请使用npm install -g universal-cli创建一个新项目: ung new PROJECT_NAME --universal 然后,该项目应该准备好服务: cd PROJECT_NAME ung serve 我没有使用现有的angular-cli项目进行测试,但也许ung init --universal可以帮助。

Angular Universal还比较不成熟。我也在等待稳定版本的发布。 - Vinay Pandya
@VinayPandya,你有没有找到使用Angular Universal与CLI项目的方法?任何意见都会很有帮助。 - Praveen Rana
是的,有一个名为universal-cli的项目,它结合了angular-cli和universal项目,但主要问题在于package.json文件中使用的是angular 2.2.3版本,而最新版本是2.4.10。可能会遇到一些错误。 - Vinay Pandya

-1

现在 Angular-cli 1.3 已经发布,文档已更新以涵盖 Universal,并提供了一个指南这里。有一个指南和示例,可以让您使用 Universal + material 2 和 Express 服务器这里


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接