共用方式為


在 .NET Aspire 中協調 Node.js 應用程式

在本文中,您將瞭解如何在 .NET.NET Aspire 專案中使用 Node.js 和 Node Package Manager (npm) 應用程式。 本文中的範例應用程式示範 AngularReactVueclient 體驗。 下列 .NET.NET Aspire API 存在以支持這些場景,且屬於 Aspire的一部分,這是 .Hosting.NodeJS NuGet 套件中的內容。

這兩個 API 之間的差異在於,前者用來裝載 Node.js 應用程式,而後者則用來裝載從 套件執行的應用程式。json 檔案的 [scripts] 區段,以及對應的 npm run <script-name> 命令。

提示

本文的範例原始程式碼可在 GitHub取得,而且 程式代碼範例中有詳細數據:具有 Angular、React 和 Vue 頁面的 .NET Aspire。

重要

雖然本文著重於 Single-Page 應用程式(SPA)前端部分,但在 原始碼範例:.NET AspireNode.js 範例 頁面上提供了額外的 Node.js 範例,示範如何使用 Node.js 作為使用 Express的 server 應用程式。

先決條件

若要與 .NET.NET Aspire一起工作,您需要在本地安裝以下項目:

如需詳細資訊,請參閱 .NET.NET Aspire 設定和工具.NET.NET Aspire SDK

此外,您必須在計算機上安裝 Node.js。 本文中的範例應用程式是使用 Node.js 20.12.2 版和 npm 10.5.1 版所建置。 若要確認您的 Node.js 和 npm 版本,請執行下列命令:

node --version
npm --version

若要下載 (包括 ),請參閱下載頁面

複製範例原始程式碼

若要從 GitHub複製範例原始程式碼,請執行下列命令:

git clone https://github.com/dotnet/aspire-samples.git

複製存放庫之後,流覽至 samples/AspireWithJavaScript 資料夾:

cd samples/AspireWithJavaScript

在此目錄中,下列列表描述了六個子目錄。

  • AspireJavaScript。Angular:Angular 應用程式,會取用天氣預報 API,並在數據表中顯示數據。
  • AspireJavaScript.AppHost:協調此範例中其他應用程式的 .NET.NET Aspire 專案。 如需詳細資訊,請參閱 .NET.NET Aspire協調流程概觀。
  • AspireJavaScript.MinimalApi:傳回隨機產生的天氣預報數據的 HTTP API。
  • AspireJavaScript。React:React 應用程式,會取用天氣預報 API,並在數據表中顯示數據。
  • AspireJavaScript.ServiceDefaults:.NET.NET Aspire 項目的預設共享專案。 如需詳細資訊,請參閱 .NET.NET Aspire 服務預設值
  • AspireJavaScript。Vue:Vue 應用程式,會取用天氣預報 API,並在數據表中顯示數據。

安裝 client 依賴項

範例應用程式示範如何使用建置在 Node.js之上的 JavaScript client 應用程式。 每個 client 應用程式都是使用 npm create 範本命令或手動撰寫。 下表列出用來建立每個 client 應用程式的範本命令,以及預設埠:

應用程式類型 建立範本命令 默認埠
Angular npm create @angular@latest 4200
React 未使用範本。 PORT env var
Vue npm create vue@latest 5173

提示

您不需要執行上述任何命令,因為範例應用程式已經包含用戶端。 相反地,這是建立用戶端的來源參考點。 如需詳細資訊,請參閱 npm-init

若要執行應用程式,您必須先為每個 client安裝相依性。 若要這樣做,請瀏覽至每個 client 資料夾,然後執行 npm install (或安裝別名 npm i) 命令

安裝 Angular 相依性

npm i ./AspireJavaScript.Angular/

如需 Angular 應用程式的詳細資訊,請參閱 探索 Angularclient

安裝 React 依賴項

npm i ./AspireJavaScript.React/

如需 React 應用程式的詳細資訊,請參閱 探索 Reactclient

安裝 Vue 相依性

npm i ./AspireJavaScript.Vue/

如需 Vue 應用程式的詳細資訊,請參閱 探索 Vueclient

執行範例應用程式

若要執行範例應用程式,請呼叫 dotnet run 命令,並使用協調器應用程式主機 AspireJavaScript.AppHost.csproj 作為 --project 開關:

dotnet run --project ./AspireJavaScript.AppHost/AspireJavaScript.AppHost.csproj

.NET .NET Aspire 儀表板 會在預設瀏覽器中啟動,而每個 client 應用程式端點會在 [資源] 頁面的 [端點] 欄中顯示。 下圖描述此範例應用程式的儀錶板:

具有多個 JavaScript client 應用程式的 .NET Aspire 儀錶板。

weatherapi 服務端點會解析到一個記錄 HTTP API 的 Swagger UI 頁面。 每個 client 應用程式都會使用此服務來顯示天氣預報數據。 您可以瀏覽至 .NET Aspire 儀錶板中的對應端點,以檢視每個 client 應用程式。 下列各節會詳細說明其螢幕快照和從範本起點進行的修改。

在您用來執行應用程式的相同終端機會話中,按 Ctrl Ctrl + C 以停止應用程式。

探索應用程式主機

若要協助瞭解每個 client 應用程式資源的協調方式,請查看應用程式主機專案。 為了裝載 Node.js 應用程式,應用程式主機需要 Aspire。Hosting.NodeJS NuGet 套件。

<Project Sdk="Microsoft.NET.Sdk">

  <Sdk Name="Aspire.AppHost.Sdk" Version="9.0.0" />

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <IsAspireHost>true</IsAspireHost>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Aspire.Hosting.AppHost" Version="9.0.0" />
    <PackageReference Include="Aspire.Hosting.NodeJs" Version="9.0.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\AspireJavaScript.MinimalApi\AspireJavaScript.MinimalApi.csproj" />
  </ItemGroup>

  <Target Name="RestoreNpm" BeforeTargets="Build" Condition=" '$(DesignTimeBuild)' != 'true' ">
    <ItemGroup>
      <PackageJsons Include="..\*\package.json" />
    </ItemGroup>

    <!-- Install npm packages if node_modules is missing -->
    <Message Importance="Normal" Text="Installing npm packages for %(PackageJsons.RelativeDir)" Condition="!Exists('%(PackageJsons.RootDir)%(PackageJsons.Directory)/node_modules')" />
    <Exec Command="npm install" WorkingDirectory="%(PackageJsons.RootDir)%(PackageJsons.Directory)" Condition="!Exists('%(PackageJsons.RootDir)%(PackageJsons.Directory)/node_modules')" />
  </Target>

</Project>

項目檔也會定義建置目標,以確保在建置應用程式主機之前已安裝 npm 相依性。 應用程式主機程式代碼 (Program.cs) 會使用 AddNpmApp(IDistributedApplicationBuilder, String, String, String, String[]) API 宣告 client 應用程式資源。

var builder = DistributedApplication.CreateBuilder(args);

var weatherApi = builder.AddProject<Projects.AspireJavaScript_MinimalApi>("weatherapi")
    .WithExternalHttpEndpoints();

builder.AddNpmApp("angular", "../AspireJavaScript.Angular")
    .WithReference(weatherApi)
    .WaitFor(weatherApi)
    .WithHttpEndpoint(env: "PORT")
    .WithExternalHttpEndpoints()
    .PublishAsDockerFile();

builder.AddNpmApp("react", "../AspireJavaScript.React")
    .WithReference(weatherApi)
    .WaitFor(weatherApi)
    .WithEnvironment("BROWSER", "none") // Disable opening browser on npm start
    .WithHttpEndpoint(env: "PORT")
    .WithExternalHttpEndpoints()
    .PublishAsDockerFile();

builder.AddNpmApp("vue", "../AspireJavaScript.Vue")
    .WithReference(weatherApi)
    .WaitFor(weatherApi)
    .WithHttpEndpoint(env: "PORT")
    .WithExternalHttpEndpoints()
    .PublishAsDockerFile();

builder.AddNpmApp("reactvite", "../AspireJavaScript.Vite")
    .WithReference(weatherApi)
    .WithEnvironment("BROWSER", "none")
    .WithHttpEndpoint(env: "VITE_PORT")
    .WithExternalHttpEndpoints()
    .PublishAsDockerFile();

builder.Build().Run();

上述程式代碼:

  • 建立 DistributedApplicationBuilder
  • 將 「weatherapi」 服務新增為應用程式主機的專案。
    • 將 HTTP 端點標示為外部端點。
  • 使用 「weatherapi」 服務的參考,將 「angular」、“react” 和 “vue” client 應用程式新增為 npm 應用程式。
    • 每個 client 應用程式都會設定為在不同的容器埠上執行,並使用 PORT 環境變數來判斷埠。
    • 所有 client 應用程式也都依賴 Dockerfile 來建置其容器映射,並設定為在發佈指令清單中以 PublishAsDockerFile API 中的容器表示自己。

如需內部循環網路的詳細資訊,請參閱 .NET.NET Aspire 內部循環網路概觀。 如需部署應用程式的詳細資訊,請參閱部署工具產生器的 指令清單格式。

當應用程式主機協調每個 client 應用程式的啟動時,它會使用 npm run start 命令。 此命令定義於 套件的 scripts 區段中。每個 client 應用程式的json 檔案。 start 文稿可用來在指定的埠上啟動 client 應用程式。 每個 client 應用程式都依賴 Proxy 來要求 「weatherapi」 服務。

代理伺服器被設定於:

  • Angular client的 proxy.conf.js 檔案。
  • React client的 webpack.config.js 檔案。
  • Vue client的 vite.config.ts 檔案。

探索 Angularclient

相較於原始 Angular 範本,做出了數個主要修改。 第一個是新增 proxy.conf.js 檔案。 此檔案用來將 Angularclient 的要求代理到 “weatherapi” 服務。

module.exports = {
  "/api": {
    target:
      process.env["services__weatherapi__https__0"] ||
      process.env["services__weatherapi__http__0"],
    secure: process.env["NODE_ENV"] !== "development",
    pathRewrite: {
      "^/api": "",
    },
  },
};

.NET .NET Aspire 應用程式主機會設定 services__weatherapi__http__0 環境變數,用來解析 「weatherapi」 服務端點。 上述組態 Proxy 會將開頭為 /api 的 HTTP 要求傳送至環境變數中指定的目標 URL。

第二個更新是針對 套件和json 檔案。 此檔案可用來設定 Angularclient,以在與預設埠不同的埠上執行。 這是透過使用 PORT 環境變數和 run-script-os npm 套件來設定埠以達成此目的。

{
  "name": "angular-weather",
  "version": "0.0.0",
  "engines": {
    "node": ">=20.12"
  },
  "scripts": {
    "ng": "ng",
    "start": "run-script-os",
    "start:win32": "ng serve --port %PORT%",
    "start:default": "ng serve --port $PORT",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^18.1.1",
    "@angular/common": "^18.1.1",
    "@angular/compiler": "^18.1.1",
    "@angular/core": "^18.1.1",
    "@angular/forms": "^18.1.1",
    "@angular/platform-browser": "^18.1.1",
    "@angular/platform-browser-dynamic": "^18.1.1",
    "@angular/router": "^18.1.1",
    "rxjs": "~7.8.0",
    "tslib": "^2.6.3",
    "zone.js": "~0.14.8"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^18.1.1",
    "@angular/cli": "^18.1.1",
    "@angular/compiler-cli": "^18.1.1",
    "@types/jasmine": "~5.1.0",
    "jasmine-core": "~5.2.0",
    "karma": "~6.4.3",
    "karma-chrome-launcher": "~3.2.0",
    "karma-coverage": "~2.2.0",
    "karma-jasmine": "~5.1.0",
    "karma-jasmine-html-reporter": "~2.1.0",
    "typescript": "~5.5.3",
    "run-script-os": "^1.1.6"
  }
}

套件的 scripts 區段。json 檔案可用來定義 start 腳本。 npm start 命令會使用此腳本來啟動 Angularclient 應用程式。 start 腳本設定為使用 run-script-os 套件來設定埠,這會根據OS適用的語法,將委派給傳遞適當 --port 參數的 ng serve 命令。

為了對「weatherapi」服務進行 HTTP 呼叫,必須將 Angularclient 應用程式設定為提供用於依賴注入的 AngularHttpClient。 這可透過在 app.config.ts 檔案中配置應用程式時,使用 provideHttpClient 輔助函式來達成。

import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideHttpClient()
  ]
};

最後,Angularclient 應用程式必須呼叫 /api/WeatherForecast 端點,以擷取天氣預報數據。 有數個 HTML、CSS 和 TypeScript 更新,這些更新全都對下列檔案進行:

import { Component, Injectable } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterOutlet } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { WeatherForecasts } from '../types/weatherForecast';

@Injectable()
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, RouterOutlet],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
  title = 'weather';
  forecasts: WeatherForecasts = [];

  constructor(private http: HttpClient) {
    http.get<WeatherForecasts>('api/weatherforecast').subscribe({
      next: result => this.forecasts = result,
      error: console.error
    });
  }
}

Angular應用程式執行中

若要將 Angularclient 應用程式可視化,請流覽至 .NET Aspire 儀錶板中的「angular」端點。 下圖描述 Angularclient 應用程式:

Angularclient 應用程式,以表格形式顯示假預報天氣數據。

探索 Reactclient

React 應用程式並未使用範本撰寫,而是手動撰寫。 您可以在 dotnet/aspire-samples 存放庫中找到完整的原始程式碼,。 在 src/App.js 檔案中可以找到一些重點:

import { useEffect, useState } from "react";
import "./App.css";

function App() {
  const [forecasts, setForecasts] = useState([]);

  const requestWeather = async () => {
    const weather = await fetch("api/weatherforecast");
    console.log(weather);

    const weatherJson = await weather.json();
    console.log(weatherJson);

    setForecasts(weatherJson);
  };

  useEffect(() => {
    requestWeather();
  }, []);

  return (
    <div className="App">
      <header className="App-header">
        <h1>React Weather</h1>
        <table>
          <thead>
            <tr>
              <th>Date</th>
              <th>Temp. (C)</th>
              <th>Temp. (F)</th>
              <th>Summary</th>
            </tr>
          </thead>
          <tbody>
            {(
              forecasts ?? [
                {
                  date: "N/A",
                  temperatureC: "",
                  temperatureF: "",
                  summary: "No forecasts",
                },
              ]
            ).map((w) => {
              return (
                <tr key={w.date}>
                  <td>{w.date}</td>
                  <td>{w.temperatureC}</td>
                  <td>{w.temperatureF}</td>
                  <td>{w.summary}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </header>
    </div>
  );
}

export default App;

App 函式是 Reactclient 應用程式的進入點。 它會使用 useStateuseEffect 掛鉤來管理天氣預報資料的狀態。 fetch API 可用來對 /api/WeatherForecast 端點提出 HTTP 要求。 然後,回應會轉換成 JSON,並設定為天氣預報數據的狀態。

const HTMLWebpackPlugin = require("html-webpack-plugin");

module.exports = (env) => {
  return {
    entry: "./src/index.js",
    devServer: {
      port: env.PORT || 4001,
      allowedHosts: "all",
      proxy: [
        {
          context: ["/api"],
          target:
            process.env.services__weatherapi__https__0 ||
            process.env.services__weatherapi__http__0,
          pathRewrite: { "^/api": "" },
          secure: false,
        },
      ],
    },
    output: {
      path: `${__dirname}/dist`,
      filename: "bundle.js",
    },
    plugins: [
      new HTMLWebpackPlugin({
        template: "./src/index.html",
        favicon: "./src/favicon.ico",
      }),
    ],
    module: {
      rules: [
        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: {
            loader: "babel-loader",
            options: {
              presets: [
                "@babel/preset-env",
                ["@babel/preset-react", { runtime: "automatic" }],
              ],
            },
          },
        },
        {
          test: /\.css$/,
          exclude: /node_modules/,
          use: ["style-loader", "css-loader"],
        },
      ],
    },
  };
};

上述程式代碼會定義 module.exports,如下所示:

  • entry 屬性設為 src/index.js 檔案。
  • devServer 依賴 Proxy 將要求轉送至 「weatherapi」 服務、將埠設定為 PORT 環境變數,並允許所有主機。
  • output 會產生一個包含 bundle.js 檔案的 dist 資料夾。
  • plugins 會將 src/index.html 檔案設定為範本,並公開 favicon.ico 檔案。

對以下檔案進行了最後的更新:

React 應用程式執行中

若要將 Reactclient 應用程式可視化,請流覽至 .NET Aspire 儀錶板中的「react」端點。 下圖描述 Reactclient 應用程式:

Reactclient 應用程式,顯示為表格的假天氣預報數據。

探索 Vueclient

與原始的 Vue 範本相比,進行了數個重要修改。 主要更新是在 TheWelcome 中新增 fetch 呼叫。vue 檔案,從 /api/WeatherForecast 端點擷取氣象預報數據。 下列代碼段示範 fetch 呼叫:

<script lang="ts">
interface WeatherForecast {
  date: string
  temperatureC: number
  temperatureF: number
  summary: string
};

type Forecasts = WeatherForecast[];

export default {
  name: 'TheWelcome',
  data() {
    return {
      forecasts: [],
      loading: true,
      error: null
    }
  },
  mounted() {
    fetch('api/weatherforecast')
      .then(response => response.json())
      .then(data => {
        this.forecasts = data
      })
      .catch(error => {
        this.error = error
      })
      .finally(() => (this.loading = false))
  }
}
</script>

<template>
  <table>
    <thead>
      <tr>
        <th>Date</th>
        <th>Temp. (C)</th>
        <th>Temp. (F)</th>
        <th>Summary</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="forecast in (forecasts as Forecasts)">
        <td>{{ forecast.date }}</td>
        <td>{{ forecast.temperatureC }}</td>
        <td>{{ forecast.temperatureF }}</td>
        <td>{{ forecast.summary }}</td>
      </tr>
    </tbody>
  </table>
</template>

<style>
table {
  border: none;
  border-collapse: collapse;
}

th {
  font-size: x-large;
  font-weight: bold;
  border-bottom: solid .2rem hsla(160, 100%, 37%, 1);
}

th,
td {
  padding: 1rem;
}

td {
  text-align: center;
  font-size: large;
}

tr:nth-child(even) {
  background-color: var(--vt-c-black-soft);
}
</style>

TheWelcome 整合 mounted時,它會呼叫 /api/weatherforecast 端點來擷取天氣預報數據。 然後,回應會設定為 forecasts 數據屬性。 若要設定 server 埠,Vueclient 應用程式會使用 PORT 環境變數。 藉由更新 vite.config.ts 檔案來達成此目的:

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  server: {
    host: true,
    port: parseInt(process.env.PORT ?? "5173"),
    proxy: {
      '/api': {
        target: process.env.services__weatherapi__https__0 || process.env.services__weatherapi__http__0,
        changeOrigin: true,
        rewrite: path => path.replace(/^\/api/, ''),
        secure: false
      }
    }
  }
})

此外,Vite 配置中指定了 server.proxy 屬性,以將請求轉發至「weatherapi」服務。 這是使用 services__weatherapi__http__0 環境變數來達成,而環境變數是由 .NET.NET Aspire 應用程式主機所設定。

從範本進行最終更新至 TheWelcome。vue 檔案。 此檔案會呼叫 /api/WeatherForecast 端點來擷取氣象預報數據,並在數據表中顯示數據。 其中包含 CSS、HTML 和 TypeScript 更新

Vue 應用程式執行中

若要將 Vueclient 應用程式可視化,請流覽至 .NET Aspire 儀錶板中的「vue」端點。 下圖描述 Vueclient 應用程式:

Vueclient 應用程式,顯示以表格形式呈現的虛假天氣預報資料。

部署考慮

本文的範例原始碼是設計為在本機執行。 每個 client 應用程式都會部署為容器映像檔。 每個 client 應用程式的 Dockerfile 會用來建置容器映像。 每個 Dockerfile 都相同,使用多階段組建來建立可用於生產環境的容器映像檔。

FROM node:20 as build

WORKDIR /app

COPY package.json package.json
COPY package-lock.json package-lock.json

RUN npm install

COPY . .

RUN npm run build

FROM nginx:alpine

COPY --from=build /app/default.conf.template /etc/nginx/templates/default.conf.template
COPY --from=build /app/dist/weather/browser /usr/share/nginx/html

# Expose the default nginx port
EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

client 應用程式目前已設定為正宗 SPA 應用程式,且未配置為以 server端轉譯模式 (SSR) 執行。 它們位於 nginx後面,用來伺服靜態檔案。 他們會使用 default.conf.template 檔案將 nginx 設定為代理 client 應用程式的請求。

server {
    listen       ${PORT};
    listen  [::]:${PORT};
    server_name  localhost;

    access_log  /var/log/nginx/server.access.log  main;

    location / {
        root /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
    }

    location /api/ {
        proxy_pass ${services__weatherapi__https__0};
        proxy_http_version 1.1;
        proxy_ssl_server_name on;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        rewrite ^/api(/.*)$ $1 break;
    }
}

Node.js server 應用程式考量

雖然本文著重於 client 應用程式,但您可能需要託管 Node.jsserver 應用程式。 要裝載 Node.jsserver 應用程式,使其像 SPA client 應用程式一樣運行,需要相同的語義。 .NET .NET Aspire 應用程式主機需要 Aspire的 .Hosting.NodeJS NuGet 套件的參考,並且程式代碼必須呼叫 AddNodeAppAddNpmApp。 這些 API 適用於將現有的 JavaScript 應用程式新增至 .NET.NET Aspire 應用程式主機。

設定秘密並將環境變數傳遞至 JavaScript 型應用程式時,無論是 client 還是 server 應用程式,請使用參數。 如需詳細資訊,請參閱 .NET.NET Aspire:外部參數— 秘密

使用 OpenTelemetry JavaScript SDK

若要從 Node.jsserver 應用程式匯出 OpenTelemetry 記錄、追蹤和計量,請使用 OpenTelemetry JavaScript SDK

如需使用 OpenTelemetry JavaScript SDK 之 Node.jsserver 應用程式的完整範例,您可以參考 程式代碼範例:.NET AspireNode.js 範例 頁面。 請考慮範例的 instrumentation.js 檔案,示範如何設定 OpenTelemetry JavaScript SDK 來導出記錄、追蹤和計量:

import { env } from 'node:process';
import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc';
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc';
import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-grpc';
import { SimpleLogRecordProcessor } from '@opentelemetry/sdk-logs';
import { PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics';
import { HttpInstrumentation } from '@opentelemetry/instrumentation-http';
import { ExpressInstrumentation } from '@opentelemetry/instrumentation-express';
import { RedisInstrumentation } from '@opentelemetry/instrumentation-redis-4';
import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api';
import { credentials } from '@grpc/grpc-js';

const environment = process.env.NODE_ENV || 'development';

// For troubleshooting, set the log level to DiagLogLevel.DEBUG
//diag.setLogger(new DiagConsoleLogger(), environment === 'development' ? DiagLogLevel.INFO : DiagLogLevel.WARN);

const otlpServer = env.OTEL_EXPORTER_OTLP_ENDPOINT;

if (otlpServer) {
    console.log(`OTLP endpoint: ${otlpServer}`);

    const isHttps = otlpServer.startsWith('https://');
    const collectorOptions = {
        credentials: !isHttps
            ? credentials.createInsecure()
            : credentials.createSsl()
    };

    const sdk = new NodeSDK({
        traceExporter: new OTLPTraceExporter(collectorOptions),
        metricReader: new PeriodicExportingMetricReader({
            exportIntervalMillis: environment === 'development' ? 5000 : 10000,
            exporter: new OTLPMetricExporter(collectorOptions),
        }),
        logRecordProcessor: new SimpleLogRecordProcessor({
            exporter: new OTLPLogExporter(collectorOptions)
        }),
        instrumentations: [
            new HttpInstrumentation(),
            new ExpressInstrumentation(),
            new RedisInstrumentation()
        ],
    });

    sdk.start();
}

提示

若要設定 .NET.NET Aspire 儀錶板的OTEL CORS設置,請參閱 .NET.NET Aspire 儀錶板的OTEL CORS設置 頁面。

總結

雖然有數個超出本文範圍的考慮事項,但您已經學習如何建置使用 Node.js 和 Node Package Manager(npm)的 .NET Aspire 專案。 您也瞭解如何使用 AddNpmApp API 來裝載 Node.js 應用程式和從 套件執行的應用程式,分別包含於json和 檔案中。 最後,您已瞭解如何使用 npm CLI 來建立 Angular、React和 Vueclient 應用程式,以及如何設定它們在不同的埠上執行。

另請參閱