Dela via


Samordna Node.js appar i .NET Aspire

I den här artikeln får du lära dig hur du använder Node.js- och Node Package Manager-appar (npm) i ett .NET.NET Aspire projekt. Exempelappen i den här artikeln visar Angular, Reactoch Vueclient upplevelser. Följande .NET.NET Aspire API:er finns för att stödja dessa scenarier – och de ingår i Aspire. Hosting.NodeJS NuGet-paket:

Skillnaden mellan dessa två API:er är att den förra används som värd för Node.js appar, medan den senare används som värd för appar som körs från ett -paket.json filavsnittet scripts – och motsvarande npm run <script-name> kommando.

Tips

Exempelkällkoden för den här artikeln finns på GitHuboch det finns information på sidan Code Samples: .NET Aspire med Angular, React och Vue.

Viktig

Även om den här artikeln fokuserar på Single-Page App(SPA) frontenddelar finns det ytterligare ett Node.js exempel tillgängligt på Kodexempel: .NET AspireNode.js exempelsida som visar hur du använder Node.js som en server app med express.

Förutsättningar

Om du vill arbeta med .NET.NET Aspirebehöver du följande installerat lokalt:

Mer information finns i .NET.NET Aspire installation och verktygoch .NET.NET Aspire SDK.

Dessutom måste du installera Node.js på datorn. Exempelappen i den här artikeln skapades med Node.js version 20.12.2 och npm version 10.5.1. Kör följande kommandon för att verifiera dina Node.js- och npm-versioner:

node --version
npm --version

För att ladda ned Node.js (inklusive npm), se Node.js nedladdningssidan.

Klona källkodsexempel

Om du vill klona exempelkällkoden från GitHubkör du följande kommando:

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

När du har klonade lagringsplatsen går du till mappen samples/AspireWithJavaScript:

cd samples/AspireWithJavaScript

Från den här katalogen finns det sex underordnade kataloger som beskrivs i följande lista:

  • AspireJavaScript.Angular: En Angular app som använder väderprognos-API:et och visar data i en tabell.
  • AspireJavaScript.AppHost: Ett .NET.NET Aspire projekt som samordnar de andra apparna i det här exemplet. Mer information finns i .NET.NET Aspire översikt över orkestrering.
  • AspireJavaScript.MinimalApi: Ett HTTP-API som returnerar slumpmässigt genererade väderprognosdata.
  • AspireJavaScript.React: En React app som använder väderprognos-API:et och visar data i en tabell.
  • AspireJavaScript.ServiceDefaults: Standarddelade projektet för .NET.NET Aspire projekt. För mer information, se tjänstens standardvärden .NET.NET Aspire.
  • AspireJavaScript.Vue: En Vue app som använder väderprognos-API:et och visar data i en tabell.

Installera client beroenden

Exempelappen visar hur du använder JavaScript client appar som bygger på Node.js. Varje client app skrevs antingen med hjälp av ett npm create-mallkommando eller manuellt. I följande tabell visas de mallkommandon som används för att skapa varje client app, tillsammans med standardporten:

Apptyp Kommandot Skapa mall Standardport
Angular npm create @angular@latest 4200
React Det gick inte att använda en mall. PORT env var
Vue npm create vue@latest 5173

Tips

Du behöver inte köra något av dessa kommandon, eftersom exempelappen redan innehåller klienterna. I stället är detta en referenspunkt som klienterna skapades från. Mer information finns i npm-init.

Om du vill köra appen måste du först installera beroendena för varje client. Det gör du genom att gå till varje client mapp och köra kommandona npm install (eller installationsaliaset npm i).

Installera Angular beroenden

npm i ./AspireJavaScript.Angular/

Mer information om appen Angular finns i utforska Angularclient.

Installera React beroenden

npm i ./AspireJavaScript.React/

Mer information om appen React hittar du i utforska Reactclient.

Installera beroenden till Vue

npm i ./AspireJavaScript.Vue/

Mer information om appen Vue finns i och kan utforskas i Vueclient.

Kör exempelappen

Om du vill köra exempelappen anropar du kommandot dotnet run med orchestrator-applikationsvärden AspireJavaScript.AppHost.csproj som --project parameter:

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

.NET .NET Aspire-instrumentpanelen startas i standardwebbläsaren och varje client appslutpunkt visas under kolumnen Slutpunkter på sidan Resurser. Följande bild visar instrumentpanelen för den här exempelappen:

.NET Aspire instrumentpanel med flera JavaScript-client-appar.

Tjänstslutpunkten weatherapi leder till en Swagger UI-sida som dokumenterar HTTP API:et. Varje client app använder den här tjänsten för att visa väderprognosdata. Du kan visa varje client app genom att navigera till motsvarande slutpunkt på .NET Aspire instrumentpanelen. Deras skärmbilder och de ändringar som görs från mallstartpunkten beskrivs i följande avsnitt.

I samma terminalsession som du använde för att köra appen trycker du på Ctrl + C- för att stoppa appen.

Utforska appvärden

För att förstå hur varje client-appresurs samordnas, bör du vända dig till appens värdprojekt. Appvärden kräver NuGet-paketet Aspire.Hosting.NodeJS för att vara värd för apparna Node.js:

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

Projektfilen definierar också ett byggmål som säkerställer att npm-beroendena installeras innan appvärden skapas. Appvärdkoden (Program.cs) deklarerar client appresurser med hjälp av AddNpmApp(IDistributedApplicationBuilder, String, String, String, String[])-API:et.

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

Föregående kod:

  • Skapar en DistributedApplicationBuilder.
  • Lägger till tjänsten "weatherapi" som ett projekt till appvärden.
    • Markerar HTTP-slutpunkterna som externa.
  • Med referens till tjänsten weatherapi lägger man till apparnaangular,react, ochvueclient som npm-appar.
    • Varje client app är konfigurerad att köras på en annan containerport och använder PORT miljövariabeln för att fastställa porten.
    • Alla client appar förlitar sig också på en Dockerfile för att skapa sin containeravbildning och är konfigurerade för att uttrycka sig i publiceringsmanifestet som en container från PublishAsDockerFile-API:et.

Mer information om nätverk i inre loopar finns i .NET.NET Aspire översikt över inre loopnätverk. Mer information om hur du distribuerar appar finns i .NET.NET Aspire manifestformat för distributionsverktygsbyggare.

När appvärden samordnar lanseringen av varje client app använder den kommandot npm run start. Det här kommandot definieras i avsnittet scripts i -paketet.json fil för varje client app. Skriptet start används för att starta client-appen på den angivna porten. Varje client app förlitar sig på en proxy för att begära tjänsten "weatherapi".

Proxyn har konfigurerats i:

  • Filen proxy.conf.js för Angularclient.
  • Filen webpack.config.js för Reactclient.
  • Filen vite.config.ts för Vueclient.

Utforska Angularclient

Det finns flera viktiga ändringar från den ursprungliga Angular mallen. Den första är tillägget av en proxy.conf.js fil. Den här filen används för proxybegäranden från Angularclient till tjänsten "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 appvärden anger services__weatherapi__http__0-miljövariabeln som används för att anropa tjänstslutpunkten "weatherapi". Den föregående konfigurationen dirigerar om HTTP-begäranden som börjar med /api till måladressen som anges i miljövariabeln.

Den andra uppdateringen är till -paketet.json fil. Den här filen används för att konfigurera Angularclient att köras på en annan port än standardporten. Detta uppnås med hjälp av miljövariabeln PORT och run-script-os npm-paketet för att ange porten.

{
  "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"
  }
}

Avsnittet scripts i -paketet.json fil används för att definiera start skriptet. Det här skriptet används av kommandot npm start för att starta appen Angularclient. Skriptet start är konfigurerat att använda run-script-os-paketet för att ställa in porten, vilket delegerar till ng serve-kommandot genom att skicka den passande --port-växeln baserat på OS-lämplig syntax.

För att kunna göra HTTP-anrop till tjänsten "weatherapi" måste Angularclient-appen konfigureras för att tillhandahålla AngularHttpClient för beroendeinmatning. Detta uppnås med hjälp av hjälpfunktionen provideHttpClient när programmet konfigureras i app.config.ts-filen.

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

Slutligen måste Angularclient-appen anropa /api/WeatherForecast slutpunkten för att hämta väderprognosdata. Det finns flera HTML-, CSS- och TypeScript-uppdateringar, som alla görs till följande filer:

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 appen är igång

Om du vill visualisera Angularclient-appen går du till slutpunkten "angular" i .NET Aspire instrumentpanelen. Följande bild visar appen Angularclient:

Angularclient app med falska väderdata som visas som en tabell.

Utforska Reactclient

Den React appen skrevs inte med hjälp av en mall och skrevs i stället manuellt. Den fullständiga källkoden finns i lagringsplatsen dotnet/aspire-samples. Några av de viktigaste intressanta punkterna finns i filen 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;

Funktionen App är startpunkten för Reactclient-appen. Den använder hookar useState och useEffect för att hantera tillståndet av de väderprognosdata. fetch-API:et används för att göra en HTTP-begäran till /api/WeatherForecast slutpunkten. Svaret konverteras sedan till JSON och anges som tillstånd för väderprognosdata.

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

Koden ovan definierar module.exports enligt följande:

  • Egenskapen entry är inställd på filen src/index.js.
  • devServer förlitar sig på en proxy för att vidarebefordra begäranden till tjänsten "weatherapi", anger porten till PORT miljövariabel och tillåter alla värdar.
  • output resulterar i en dist mapp med en bundle.js fil.
  • plugins ange filen src/index.html som mall och exponera favicon.ico-filen.

De sista uppdateringarna gäller följande filer:

React appen körs

Om du vill visualisera Reactclient-appen går du till slutpunkten "react" i .NET Aspire instrumentpanelen. Följande bild visar appen Reactclient:

Reactclient app med falska väderdata som visas som en tabell.

Utforska Vueclient

Det finns flera viktiga ändringar från den ursprungliga Vue mallen. De huvudsakliga uppdateringarna var tillägget av anropet fetch i TheWelcomevue-filen för att hämta väderprognosdata från slutpunkten /api/WeatherForecast. Följande kodfragment visar fetch-anropet:

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

Eftersom TheWelcome integration är mounted, så anropas /api/weatherforecast slutpunkten för att hämta väderprognosdata. Svaret ställs sedan in som dataegenskapen forecasts. Om du vill ange server port använder Vueclient-appen PORT miljövariabeln. Detta uppnås genom att uppdatera vite.config.ts-filen:

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

Dessutom anger Vite-konfigurationen egenskapen server.proxy för att vidarebefordra begäranden till tjänsten "weatherapi". Detta uppnås med hjälp av miljövariabeln services__weatherapi__http__0, som anges av .NET.NET Aspire appvärd.

Den sista uppdateringen från mallen görs till TheWelcome.vue fil. Den här filen anropar /api/WeatherForecast slutpunkten för att hämta väderprognosdata och visar data i en tabell. Den innehåller CSS-, HTML- och TypeScript-uppdateringar.

Vue appen är igång

Om du vill visualisera Vueclient-appen går du till slutpunkten "vue" i .NET Aspire instrumentpanelen. Följande bild visar appen Vueclient:

Vueclient app med falska väderdata som visas som en tabell.

Distributionsöverväganden

Exempelprogramkoden för den här artikeln är utformad för att köras lokalt. Varje client app distribueras som en containeravbildning. Dockerfile för varje client app används för att skapa containeravbildningen. Varje Dockerfile är identisk och använder en flerstegsbyggprocess för att skapa en produktionsklar containerbild.

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

De client-apparna är för närvarande konfigurerade att köras som riktiga SPAs och är inte konfigurerade att köras i SSR-läge server. De sitter bakom nginx, som används för att hantera statiska filer. De använder en default.conf.template-fil för att konfigurera nginx- till proxybegäranden till client-appen.

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 appöverväganden

Den här artikeln fokuserar på client appar, men du kan ha scenarier där du behöver vara värd för en Node.jsserver app. Samma semantik krävs för att vara värd för en Node.jsserver app som en SPA-client app. .NET .NET Aspire-appvärden kräver en paketreferens till Aspire.Hosting.NodeJS NuGet-paketet och koden måste anropa antingen AddNodeApp eller AddNpmApp. Dessa API:erna är användbara för att lägga till befintliga JavaScript-appar till .NET.NET Aspire appvärdsmiljö.

När du konfigurerar hemligheter och skickar miljövariabler till JavaScript-baserade appar, oavsett om de är client eller server appar, använder du parametrar. Mer information finns i .NET.NET Aspire: Externa parametrar – hemligheter.

Använda OpenTelemetry JavaScript SDK

Om du vill exportera OpenTelemetry loggar, spårningar och mått från en Node.jsserver app använder du OpenTelemetry JavaScript SDK-.

Ett fullständigt exempel på en Node.jsserver-app med hjälp av OpenTelemetry JavaScript SDK finns i Kodexempel: .NET AspireNode.js exempel sidan. Överväg exemplets instrumentation.js-fil, som visar hur du konfigurerar OpenTelemetry JavaScript SDK för att exportera loggar, spårningar och mått:

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

Tips

För att konfigurera OTEL CORS-inställningarna för .NET.NET Aspire instrumentpanelen, se sidan för .NET.NET Aspire OTEL CORS-inställningar på instrumentpanelen.

Sammanfattning

Det finns flera saker som ligger utanför den här artikelns omfång, men du har lärt dig hur du skapar .NET Aspire projekt som använder Node.js och Node Package Manager (npm). Du har också lärt dig hur du använder AddNpmApp API:er för att vara värd för Node.js-appar och appar som körs från ett -paket, samtjsonoch-fil. Slutligen lärde du dig hur du använder npm CLI för att skapa Angular, Reactoch Vueclient appar och hur du konfigurerar dem att köras på olika portar.

Se även