次の方法で共有


Node.js で .NET Aspire アプリを調整する

この記事では、Node.jsnpm プロジェクトで .NET および Node Package Manager (.NET Aspire) アプリを使用する方法について説明します。 この記事のサンプル アプリでは、クライアント エクスペリエンス AngularReactVue について説明します。 次の .NET.NET Aspire API は、これらのシナリオをサポートするために存在し、Aspireの一部です。Hosting.NodeJS NuGet パッケージ:

これら 2 つの API の違いは、前者が Node.js アプリをホストするために使用されるのに対し、後者は package.json ファイルの scripts セクションから実行されるアプリと、対応する npm run <script-name> コマンドをホストするために使用される点です。

アドバイス

この記事のサンプル ソース コードは GitHubで入手できます。.NET Aspire ページを使用した Angular を参照してください。

重要

この記事では、Single-Page アプリ (SPA) フロントエンド ビットに焦点を当てていますが、Node.js ページには、.NET Aspireを使用したサーバー アプリとして Node.js を使用する方法を示す追加の サンプルがあります。

前提 条件

.NET .NET Aspireを使用するには、次のものがローカルにインストールされている必要があります。

詳細については、 セットアップとツールの、および SDK を参照してください。

さらに、コンピューターに Node.js をインストールする必要があります。 この記事のサンプル アプリは、Node.js バージョン 20.12.2 と npm バージョン 10.5.1 でビルドされています。 Node.js と npm のバージョンを確認するには、次のコマンドを実行します。

node --version
npm --version

Node.js (npmを含む) をダウンロードするには、Node.js ダウンロード ページを参照してください。

サンプル ソース コードを複製する

GitHubからサンプル ソース コードを複製するには、次のコマンドを実行します。

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

リポジトリを複製した後、samples/AspireWithJavaScript フォルダーに移動します。

cd samples/AspireWithJavaScript

このディレクトリには、次の一覧で説明する 6 つの子ディレクトリがあります。

  • AspireJavaScript.Angular: 天気予報 API を利用してデータを取得し、テーブルに表示する Angular アプリ。
  • AspireJavaScript.AppHost: このサンプルの他のアプリを調整する .NET.NET Aspire プロジェクトです。 詳細については、オーケストレーションの概要 参照してください。
  • AspireJavaScript.MinimalApi: ランダムに生成された天気予報データを返す HTTP API。
  • AspireJavaScript。React: 天気予報 API を取得し、データを表形式で表示する React アプリ。
  • AspireJavaScript.ServiceDefaults: .NET.NET Aspire プロジェクトの既定の共有プロジェクト。 詳細については、「.NET.NET Aspire サービスの既定値」を参照してください。
  • AspireJavaScript。Vue: 天気予報 API を取得し、データを表形式で表示する Vue アプリ。

クライアントの依存関係をインストールする

サンプル アプリでは、Node.js上に構築された JavaScript クライアント アプリの使用方法を示します。 各クライアント アプリは、npm create テンプレート コマンドを使用するか、手動で作成されました。 次の表に、各クライアント アプリの作成に使用するテンプレート コマンドと、既定のポートを示します。

アプリの種類 テンプレートの作成コマンド 既定のポート
Angular npm create @angular@latest 4200
React テンプレートを使用しませんでした。 PORT環境変数
Vue npm create vue@latest 5173

アドバイス

サンプル アプリにはクライアントが既に含まれているので、これらのコマンドを実行する必要はありません。 むしろ、これはクライアントが作成される基準となる参照ポイントです。 詳細については、npm-init参照してください。

アプリを実行するには、まず各クライアントの依存関係をインストールする必要があります。 これを行うには、各クライアント フォルダーに移動し、npm installnpm i (またはインストール エイリアス ) コマンドを実行します。

Angular 依存関係をインストールする

npm i ./AspireJavaScript.Angular/

Angular アプリの詳細については、Angular クライアント 参照してください。

React 依存関係をインストールする

npm i ./AspireJavaScript.React/

React アプリの詳細については、React クライアント 参照してください。

Vue 依存関係をインストールする

npm i ./AspireJavaScript.Vue/

Vue アプリの詳細については、Vue クライアント 参照してください。

サンプル アプリを実行する

サンプル アプリを実行するには、 スイッチとして Orchestrator アプリ ホスト AspireJavaScript.AppHost.csproj で、--project コマンドを呼び出します。

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

.NET .NET Aspire ダッシュボード が既定のブラウザーで起動し、[リソース] ページの [エンドポイント] 列に各クライアント アプリ エンドポイントが表示されます。 次の図は、このサンプル アプリのダッシュボードを示しています。

ダッシュボード .NET.NET Aspire は、複数の JavaScript クライアント アプリを含みます。

weatherapi サービス エンドポイントは、HTTP API を文書化する Swagger UI ページに解決されます。 各クライアント アプリは、このサービスを使用して天気予報データを表示します。 各クライアント アプリを表示するには、.NET.NET Aspire ダッシュボードで対応するエンドポイントに移動します。 これらのスクリーンショットと、テンプレートの開始点から行われた変更については、次のセクションで詳しく説明します。

アプリの実行に使用したのと同じターミナル セッションで、CtrlC 押してアプリを停止します。

アプリ ホストを探索する

各クライアント アプリ リソースの調整方法を理解するには、アプリ ホスト プロジェクトを参照してください。 アプリ ホストには、Aspireが必要です。Hosting.NodeJS NuGet パッケージを使用して、Node.js アプリをホストします。

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

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

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

  <ItemGroup>
    <PackageReference Include="Aspire.Hosting.AppHost" Version="9.2.0" />
    <PackageReference Include="Aspire.Hosting.NodeJs" Version="9.2.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 を使用してクライアント アプリ リソースを宣言します。

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" サービスへの参照を使用して、npm アプリとして "angular"、"react"、および "vue" クライアント アプリを追加します。
    • 各クライアント アプリは、異なるコンテナー ポートで実行するように構成され、PORT 環境変数を使用してポートを決定します。
    • また、すべてのクライアント アプリは、Dockerfile に依存してコンテナー イメージをビルドし、PublishAsDockerFile API からコンテナーとして発行マニフェストで自身を表現するように構成されています。

内部ループ ネットワークの詳細については、「内部ループ ネットワークの概要 .NET.NET Aspireを参照してください。 アプリの配置の詳細については、配置ツール ビルダーのマニフェスト形式 .NET.NET Aspireを参照してください。

アプリ ホストは、各クライアント アプリの起動を調整するときに、npm run start コマンドを使用します。 このコマンドは、各クライアント アプリの scripts ファイルの セクションで定義されています。 start スクリプトは、指定したポートでクライアント アプリを起動するために使用されます。 各クライアント アプリは、"weatherapi" サービスを要求するためにプロキシに依存します。

プロキシは次で構成されます。

  • クライアントの Angular ファイル。
  • クライアントの React ファイル。
  • クライアントの Vue ファイル。

Angular クライアントを調べる

元の Angular テンプレートからいくつかの重要な変更があります。 1 つ目は、proxy.conf.js ファイルの追加です。 このファイルは、Angular クライアントから "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 アプリ ホストは、"weatherapi" サービス エンドポイントの解決に使用される services__weatherapi__http__0 環境変数を設定します。 上記の構成は、環境変数で指定されたターゲット URL への /api で始まる HTTP 要求をプロキシします。

次に、angular.json ファイルにプロキシ ファイルを含めます。 serve ターゲットを更新して、proxyConfig オプションを含め、作成した proxy.conf.js ファイルを参照します。 Angular CLI では、Angular クライアント アプリの提供中にプロキシ構成が使用されるようになります。

"serve": {
  "builder": "@angular-devkit/build-angular:dev-server",
  "configurations": {
    "production": {
      "buildTarget": "weather:build:production"
    },
    "development": {
      "buildTarget": "weather:build:development"
    }
  },
  "defaultConfiguration": "development",
  "options": {
    "proxyConfig": "proxy.conf.js"
  }
},

3 番目の更新は、package.json ファイルに対する更新です。 このファイルは、既定のポートとは異なるポートで実行するように Angular クライアントを構成するために使用されます。 これは、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": "^19.2.1",
    "@angular/common": "^19.2.1",
    "@angular/compiler": "^19.2.1",
    "@angular/core": "^19.2.1",
    "@angular/forms": "^19.2.1",
    "@angular/platform-browser": "^19.2.1",
    "@angular/platform-browser-dynamic": "^19.2.1",
    "@angular/router": "^19.2.1",
    "rxjs": "~7.8.2",
    "tslib": "^2.8.1",
    "zone.js": "~0.15.0"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^19.2.1",
    "@angular/cli": "^19.2.1",
    "@angular/compiler-cli": "^19.2.1",
    "@types/jasmine": "~5.1.7",
    "jasmine-core": "~5.6.0",
    "karma": "~6.4.4",
    "karma-chrome-launcher": "~3.2.0",
    "karma-coverage": "~2.2.1",
    "karma-jasmine": "~5.1.0",
    "karma-jasmine-html-reporter": "~2.1.0",
    "typescript": "~5.8.2",
    "run-script-os": "^1.1.6"
  }
}

scripts ファイルの セクションを使用して、start スクリプトを定義します。 このスクリプトは、npm start クライアント アプリを起動するために、Angular コマンドによって使用されます。 start スクリプトは、run-script-os パッケージを使用してポートを設定するように構成されています。これは、OS に適した構文に基づいて適切な ng serve スイッチを渡す --port コマンドに委任します。

"weatherapi" サービスに対して HTTP 呼び出しを行うには、依存関係の挿入に AngularAngular を提供するように HttpClient クライアント アプリを構成する必要があります。 これは、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()
  ]
};

最後に、Angular クライアント アプリは、/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アプリ 実行中

Angular クライアント アプリを視覚化するには、.NET Aspire ダッシュボードで "angular" エンドポイントに移動します。 次の図は、Angular クライアント アプリを示しています。

Angular 偽の天気予報データがテーブルとして表示されたクライアント アプリ。

React クライアントを調べる

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 関数は、React クライアント アプリのエントリ ポイントです。 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 はプロキシに依存して要求を "weatherapi" サービスに転送し、ポートを PORT 環境変数に設定し、すべてのホストを許可します。
  • output は、bundle.js ファイルを含む dist フォルダーになります。
  • plugins src/index.html ファイルをテンプレートとして設定し、favicon.ico ファイルを公開します。

最終的な更新は、次のファイルに対して行われます。

Reactアプリ 実行中

React クライアント アプリを視覚化するには、.NET Aspire ダッシュボードで "react" エンドポイントに移動します。 次の図は、React クライアント アプリを示しています。

React 偽の天気予報データがテーブルとして表示されたクライアント アプリ。

Vue クライアントを調べる

元の Vue テンプレートからいくつかの重要な変更があります。 主要な更新プログラムは、fetch エンドポイントから天気予報データを取得するために、TheWelcome.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 データ プロパティとして設定されます。 サーバー ポートを設定するために、Vue クライアント アプリは 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 構成では、要求を "weatherapi" サービスに転送する server.proxy プロパティを指定します。 これは、services__weatherapi__http__0.NET アプリ ホストによって設定される .NET Aspire 環境変数を使用して実現されます。

テンプレートの最後の更新は、theWelcome.vue ファイル に対して行われます。 このファイルは、/api/WeatherForecast エンドポイントを呼び出して天気予報データを取得し、テーブルにデータを表示します。 これには、CSS 、HTML、TypeScript の更新が含まれています。

Vueアプリ 実行中

Vue クライアント アプリを視覚化するには、.NET Aspire ダッシュボードで "vue" エンドポイントに移動します。 次の図は、Vue クライアント アプリを示しています。

Vue 偽の天気予報データがテーブルとして表示されたクライアント アプリ。

デプロイに関する考慮事項

この記事のサンプル ソース コードは、ローカルで実行するように設計されています。 各クライアント アプリは、コンテナー イメージとしてデプロイされます。 各クライアント アプリの 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;"]

クライアント アプリは現在、真の SPA アプリとして実行するように構成されており、サーバー側レンダリング (SSR) モードで実行するように構成されていません。 これらは、静的ファイル 提供するために使用される nginxの背後に配置されます。 default.conf.template ファイルを使用して、nginx を構成し、クライアントアプリへの要求をプロキシします。

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 サーバー アプリに関する考慮事項

この記事ではクライアント アプリに焦点を当てていますが、Node.js サーバー アプリをホストする必要があるシナリオが考えられます。 Node.js サーバー アプリを SPA クライアント アプリとしてホストするには、同じセマンティクスが必要です。 .NET .NET Aspire アプリ ホストには、Aspireへのパッケージ参照が必要です。Hosting.NodeJS NuGet パッケージとコードは、AddNodeApp または AddNpmAppを呼び出す必要があります。 これらの API は、既存の JavaScript アプリを .NET.NET Aspire アプリ ホストに追加する場合に便利です。

シークレットを構成し、JavaScript ベースのアプリに環境変数を渡すときは、クライアント アプリでもサーバー アプリでも、パラメーターを使用します。 詳細については、「.NET.NET Aspire: 外部パラメーター - シークレット」を参照してください。

OpenTelemetry JavaScript SDK を使用する

OpenTelemetry サーバー アプリから Node.js ログ、トレース、メトリックをエクスポートするには、OpenTelemetry JavaScript SDKを使用します。

Node.js JavaScript SDK を使用した OpenTelemetry サーバー アプリの完全な例については、「コード サンプル: .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 設定 ページを参照してください。

概要

この記事の範囲外の考慮事項がいくつかありますが、.NET Aspire とノード パッケージ マネージャー (Node.js) を使用する npm プロジェクトをビルドする方法について学習しました。 また、AddNpmApp API を使用して Node.js アプリをホストする方法や、package.json ファイルから実行するアプリをホストする方法も学びました。 最後に、npm CLI を使用して、Angular、React、および Vue クライアント アプリを作成する方法と、それらをさまざまなポートで実行するように構成する方法について説明しました。

関連項目