Partager via


Orchestrer des applications Node.js dans .NET Aspire

Dans cet article, vous allez apprendre à utiliser des applications Node.js et Node Package Manager (npm) dans un projet .NET.NET Aspire. L’exemple d’application de cet article illustre les expériences clients Angular, Reactet Vue. Les API de .NET.NET Aspire suivantes existent pour prendre en charge ces scénarios et font partie du Aspire.Hosting.NodeJS package NuGet :

La différence entre ces deux API est que la première est utilisée pour héberger des applications Node.js, tandis que la seconde est utilisée pour héberger des applications qui s'exécutent à partir de la section d'un fichier scripts et de la commande npm run <script-name> correspondante.

Pourboire

L’exemple de code source de cet article est disponible sur GitHubet des détails sont disponibles sur les exemples de code : .NET Aspire avec Angular, React et Vue page.

Important

Bien que cet article se concentre sur les éléments du front-end de l'application Single-Page (SPA), un échantillon supplémentaire de Node.js est disponible sur la page d'exemples de code : .NET AspireNode.js, qui montre comment utiliser Node.js comme application serveur avec express.

Conditions préalables

Pour utiliser .NET.NET Aspire, vous avez besoin de l’installation locale suivante :

Pour plus d'informations, consultez la configuration .NET.NET Aspire etd'outils, et le SDK .NET.NET Aspire.

En outre, vous devez installer Node.js sur votre ordinateur. L’exemple d’application de cet article a été créé avec Node.js version 20.12.2 et npm version 10.5.1. Pour vérifier vos versions Node.js et npm, exécutez les commandes suivantes :

node --version
npm --version

Pour télécharger Node.js (y compris npm), consultez la page de téléchargement Node.js.

Cloner un exemple de code source

Pour cloner l’exemple de code source à partir de GitHub, exécutez la commande suivante :

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

Après avoir cloné le référentiel, accédez au dossier samples/AspireWithJavaScript :

cd samples/AspireWithJavaScript

Dans ce répertoire, il existe six répertoires enfants décrits dans la liste suivante :

  • AspireJavaScript.Angular: application Angular qui consomme l’API de prévision météorologique et affiche les données d’une table.
  • AspireJavaScript.AppHost: projet .NET.NET Aspire qui orchestre les autres applications de cet exemple. Pour plus d’informations, consultez .NET.NET Aspire vue d’ensemble de l’orchestration.
  • AspireJavaScript.MinimalApi: API HTTP qui retourne des données de prévision météorologique générées de manière aléatoire.
  • AspireJavaScript.React: application React qui consomme l’API de prévision météorologique et affiche les données d’une table.
  • AspireJavaScript.ServiceDefaults: projet partagé par défaut pour les projets .NET.NET Aspire. Pour plus d'informations, consultez les paramètres par défaut du service .NET.NET Aspire.
  • AspireJavaScript.Vue: application Vue qui consomme l’API de prévision météorologique et affiche les données d’une table.

Installer les dépendances du client

L’exemple d’application montre comment utiliser des applications clientes JavaScript basées sur Node.js. Chaque application cliente a été écrite à l’aide d’une commande de modèle npm create ou manuellement. Le tableau suivant répertorie les commandes de modèle utilisées pour créer chaque application cliente, ainsi que le port par défaut :

Type d’application Créer une commande de modèle Port par défaut
Angular npm create @angular@latest 4200
React N’a pas utilisé de modèle. PORT env var
Vue npm create vue@latest 5173

Pourboire

Vous n’avez pas besoin d’exécuter l’une de ces commandes, car l’exemple d’application inclut déjà les clients. Au lieu de cela, il s’agit d’un point de référence à partir duquel les clients ont été créés. Pour plus d’informations, consultez npm-init.

Pour exécuter l’application, vous devez d’abord installer les dépendances pour chaque client. Pour ce faire, accédez à chaque dossier client et exécutez npm install (ou les commandes d’alias d’installation npm i).

Installer les dépendances Angular

npm i ./AspireJavaScript.Angular/

Pour plus d’informations sur l’application Angular, consultez explorer le client Angular.

Installer dépendances React

npm i ./AspireJavaScript.React/

Pour plus d’informations sur l’application React, consultez explorer le client React.

Installer les dépendances Vue

npm i ./AspireJavaScript.Vue/

Pour plus d’informations sur l’application Vue, consultez explorer le client Vue.

Exécuter l’exemple d’application

Pour exécuter l’exemple d’application, exécutez la commande dotnet run en utilisant l’hôte de l’application d’orchestration AspireJavaScript.AppHost.csproj comme le commutateur --project :

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

Le tableau de bord .NET.NET Aspire démarre dans votre navigateur par défaut, et chaque point de terminaison d’application cliente s’affiche sous la colonne Points de terminaison de la page Ressources . L’image suivante illustre le tableau de bord de cet exemple d’application :

.NET.NET Aspire tableau de bord avec plusieurs applications clientes JavaScript.

Le point de terminaison de service weatherapi redirige vers une page de l'interface utilisateur Swagger qui documente l'API HTTP. Chaque application cliente consomme ce service pour afficher les données de prévision météorologique. Vous pouvez afficher chaque application cliente en accédant au point de terminaison correspondant dans le tableau de bord .NET.NET Aspire. Leurs captures d’écran et les modifications apportées à partir du point de départ du modèle sont détaillées dans les sections suivantes.

Dans la même session de terminal que vous avez utilisée pour exécuter l’application, appuyez sur Ctrl + C pour arrêter l’application.

Explorer l’hôte de l’application

Pour comprendre comment chaque ressource d’application cliente est orchestrée, recherchez le projet hôte d’application. L’hôte de l’application nécessite le Aspire. Hosting.NodeJS package NuGet pour héberger des applications Node.js :

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

  <Sdk Name="Aspire.AppHost.Sdk" Version="9.1.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.1.0" />
    <PackageReference Include="Aspire.Hosting.NodeJs" Version="9.1.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>

Le fichier projet définit également une cible de build qui garantit que les dépendances npm sont installées avant la génération de l’hôte de l’application. Le code hôte de l’application (Program.cs) déclare les ressources de l’application cliente à l’aide de l’API AddNpmApp(IDistributedApplicationBuilder, String, String, String, String[]).

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();

Code précédent :

  • Crée un DistributedApplicationBuilder.
  • Ajoute le service « weatherapi » comme projet à l'hôte d'application.
    • Marque les points de terminaison HTTP comme externes.
  • Avec une référence au service « weatherapi », ajoute les applications clientes « angular », « react » et « vue » comme applications npm.
    • Chaque application cliente est configurée pour s’exécuter sur un autre port de conteneur et utilise la variable d’environnement PORT pour déterminer le port.
    • Toutes les applications clientes s’appuient également sur un Dockerfile pour générer leur image conteneur et sont configurées pour s’exprimer dans le manifeste de publication en tant que conteneur à partir de l’API PublishAsDockerFile.

Pour plus d’informations sur la mise en réseau en boucle interne, consultez .NET.NET Aspire vue d’ensemble de la mise en réseau en boucle interne. Pour plus d’informations sur le déploiement d’applications, consultez .NET.NET Aspire format de manifeste pour les générateurs d’outils de déploiement.

Lorsque l’hôte de l’application orchestre le lancement de chaque application cliente, il utilise la commande npm run start. Cette commande est définie dans la section scripts du fichier package.json pour chaque application cliente. Le script start est utilisé pour démarrer l’application cliente sur le port spécifié. Chaque application cliente s’appuie sur un proxy pour demander le service « weatherapi ».

Le proxy est configuré dans :

  • Fichier proxy.conf.js pour le client Angular.
  • Fichier webpack.config.js pour le client React.
  • Fichier vite.config.ts pour le client Vue.

Explorer le client Angular

Il existe plusieurs modifications clés du modèle de Angular d’origine. Le premier est l’ajout d’un fichier proxy.conf.js. Ce fichier est utilisé pour proxyr les requêtes du client Angular vers le service « 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": "",
    },
  },
};

L’hôte d’application .NET.NET Aspire définit la variable d’environnement services__weatherapi__http__0, utilisée pour résoudre le point de terminaison de service « weatherapi ». La configuration précédente redirige les requêtes HTTP commençant par /api vers l'URL cible spécifiée dans la variable d'environnement.

Incluez ensuite le fichier proxy dans le fichier angular.json. Mettez à jour la cible serve pour inclure l’option proxyConfig, en référençant le fichier proxy.conf.js créé. L’interface CLI Angular utilise désormais la configuration du proxy tout en servant l’application cliente 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"
  }
},

La troisième mise à jour concerne le fichier package.json. Ce fichier est utilisé pour configurer le client Angular pour qu’il s’exécute sur un port différent de celui par défaut. Pour ce faire, utilisez la variable d’environnement PORT et le package npm run-script-os pour définir le port.

{
  "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.1.4",
    "@angular/common": "^19.1.4",
    "@angular/compiler": "^19.1.4",
    "@angular/core": "^19.1.4",
    "@angular/forms": "^19.1.4",
    "@angular/platform-browser": "^19.1.4",
    "@angular/platform-browser-dynamic": "^19.1.4",
    "@angular/router": "^19.1.4",
    "rxjs": "~7.8.1",
    "tslib": "^2.8.1",
    "zone.js": "~0.15.0"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^19.1.4",
    "@angular/cli": "^19.1.4",
    "@angular/compiler-cli": "^19.1.4",
    "@types/jasmine": "~5.1.5",
    "jasmine-core": "~5.5.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.7.3",
    "run-script-os": "^1.1.6"
  }
}

La section scripts du fichier package.json est utilisée pour définir le script start. Ce script est utilisé par la commande npm start pour démarrer l’application cliente Angular. Le script start est configuré pour utiliser le module run-script-os afin de définir le port, qui délègue à la commande ng serve en passant l'interrupteur --port approprié selon la syntaxe propre au système d'exploitation.

Pour effectuer des appels HTTP au service « weatherapi », l’application cliente Angular doit être configurée pour fournir les AngularHttpClient pour l’injection de dépendances. Pour ce faire, utilisez la fonction d’assistance provideHttpClient lors de la configuration de l’application dans le fichier app.config.ts.

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()
  ]
};

Enfin, l’application cliente Angular doit appeler le point de terminaison /api/WeatherForecast pour récupérer les données de prévision météorologique. Il existe plusieurs mises à jour HTML, CSS et TypeScript, qui sont toutes effectuées dans les fichiers suivants :

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
    });
  }
}

application Angular en cours d’exécution

Pour visualiser l’application cliente Angular, allez au point d'accès « angular » dans le tableau de bord .NET Aspire. L’image suivante illustre l’application cliente Angular :

Angular application cliente avec de fausses données météorologiques prévisionnistes affichées sous la forme d’une table.

Explorer le client React

L’application React n’a pas été écrite à l’aide d’un modèle et a été écrite manuellement. Le code source complet se trouve dans le référentiel dotnet/aspire-samples. Certains des principaux points d’intérêt se trouvent dans le fichier 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;

La fonction App est le point d’entrée de l’application cliente React. Il utilise les useState et useEffect hooks pour gérer l’état des données de prévision météorologique. L’API fetch est utilisée pour effectuer une requête HTTP au point de terminaison /api/WeatherForecast. La réponse est ensuite convertie en JSON et définie comme état des données de prévision météorologique.

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"],
        },
      ],
    },
  };
};

Le code précédent définit l'module.exports comme suit :

  • La propriété entry est définie sur le fichier src/index.js.
  • Le devServer s’appuie sur un proxy pour transférer des requêtes au service « weatherapi », définit le port sur la variable d’environnement PORT et autorise tous les hôtes.
  • Le output génère dans un dossier dist un fichier bundle.js.
  • Le plugins a défini le fichier src/index.html comme modèle et a exposé le fichier favicon.ico.

Les dernières mises à jour sont apportées aux fichiers suivants :

application React en cours d’exécution

Pour visualiser l’application cliente React, accédez au point de terminaison « react » dans le tableau de bord .NET Aspire. L’image suivante illustre l’application cliente React :

React application cliente avec de fausses données météorologiques prévisionnistes affichées sous la forme d’une table.

Explorer le client Vue

Il existe plusieurs modifications clés du modèle de Vue d’origine. Les mises à jour principales ont été l’ajout de l’appel fetch dans le fichier TheWelcome.vue pour récupérer les données de prévision météorologique à partir du point de terminaison /api/WeatherForecast. L’extrait de code suivant illustre l’appel 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>

Étant donné que l’intégration TheWelcome est mounted, elle appelle le point de terminaison /api/weatherforecast pour récupérer les données de prévision météorologique. La réponse est ensuite définie comme propriété de données forecasts. Pour définir le port du serveur, l’application cliente Vue utilise la variable d’environnement PORT. Pour ce faire, mettez à jour le fichier 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
      }
    }
  }
})

En outre, la configuration Vite spécifie la propriété server.proxy pour transférer les demandes au service « weatherapi ». Pour ce faire, utilisez la variable d’environnement services__weatherapi__http__0, définie par l’hôte de l’application .NET.NET Aspire.

La dernière mise à jour du modèle est effectuée dans le fichier TheWelcome.vue. Ce fichier appelle le point de terminaison /api/WeatherForecast pour récupérer les données de prévision météorologique et affiche les données d’une table. Elle inclut mises à jour CSS, HTML et TypeScript.

application Vue en cours d’exécution

Pour visualiser l'application cliente Vue, rendez-vous sur le point d'accès « vue » dans le tableau de bord .NET Aspire. L’image suivante illustre l’application cliente Vue :

Vue application cliente avec de fausses données météorologiques prévisionnistes affichées sous la forme d’une table.

Considérations relatives au déploiement

L’exemple de code source de cet article est conçu pour s’exécuter localement. Chaque application cliente se déploie en tant qu’image conteneur. La Dockerfile pour chaque application cliente est utilisée pour générer l’image conteneur. Chaque Dockerfile est identique, utilisant une compilation multistage pour créer une image de conteneur prête pour la production.

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;"]

Les applications clientes sont actuellement configurées pour s’exécuter en tant qu’applications SPA vraies et ne sont pas configurées pour s’exécuter en mode rendu côté serveur (SSR). Ils se trouvent derrière nginx, qui est utilisé pour servir les fichiers statiques. Ils utilisent un fichier default.conf.template pour configurer nginx pour les demandes proxy à l’application cliente.

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;
    }
}

Considérations relatives à l’application serveur Node.js

Bien que cet article se concentre sur les applications clientes, vous pouvez avoir des scénarios où vous devez héberger une application serveur Node.js. La même sémantique est nécessaire pour héberger une application serveur Node.js en tant qu’application cliente SPA. L'hôte d'application .NET.NET Aspire nécessite une référence de paquet au package NuGet Aspire.Hosting.NodeJS et le code doit appeler soit AddNodeApp soit AddNpmApp. Ces API sont utiles pour ajouter des applications JavaScript existantes à l’hôte d’application .NET.NET Aspire.

Lors de la configuration des secrets et de la transmission de variables d’environnement à des applications JavaScript, qu’elles soient des applications clientes ou serveurs, utilisez des paramètres. Pour plus d’informations, consultez .NET.NET Aspire: paramètres externes : secrets.

Utiliser le Kit de développement logiciel (SDK) JavaScript OpenTelemetry

Pour exporter OpenTelemetry journaux, traces et métriques depuis une application serveur Node.js, vous utilisez le kit de développement logiciel (SDK) JavaScript OpenTelemetry.

Pour obtenir un exemple complet d’une application serveur Node.js à l’aide du KIT de développement logiciel (SDK) JavaScript OpenTelemetry, vous pouvez consulter les exemples de code : .NET AspireNode.js exemple de page. Considérez le fichier instrumentation.js de l'exemple, qui illustre comment configurer le SDK JavaScript OpenTelemetry pour exporter les journaux, les traces et les métriques.

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();
}

Pourboire

Pour configurer les paramètres OTEL CORS du tableau de bord .NET.NET Aspire, consultez la page des paramètres OTEL CORS du tableau de bord .NET.NET Aspire.

Résumé

Bien qu’il existe plusieurs considérations qui dépassent la portée de cet article, vous avez appris à générer des projets .NET Aspire qui utilisent Node.js et node Package Manager (npm). Vous avez également appris à utiliser les API AddNpmApp pour héberger des applications et des applications Node.js qui s’exécutent à partir d’un fichier package.json, respectivement. Enfin, vous avez appris à utiliser l’interface CLI npm pour créer des Angular, des Reactet des applications clientes Vue, et comment les configurer pour qu’elles s’exécutent sur différents ports.

Voir aussi