Delen via


Apps Node.js in .NET Aspire organiseren

In dit artikel leert u hoe u Node.js- en Node Package Manager-apps (npm) gebruikt in een .NET.NET Aspire project. De voorbeeld-app in dit artikel laat zien Angular, Reacten Vueclient ervaringen. De volgende .NET.NET Aspire API's bestaan om deze scenario's te ondersteunen, en ze maken deel uit van de Aspire. Hosting.NodeJS NuGet-pakket:

Het verschil tussen deze twee API's is dat de vorige wordt gebruikt voor het hosten van Node.js apps, terwijl de laatste wordt gebruikt voor het hosten van apps die worden uitgevoerd vanuit een -pakket.json sectie scripts bestand en de bijbehorende npm run <script-name> opdracht.

Tip

De voorbeeldbroncode voor dit artikel is beschikbaar op GitHuben er zijn details beschikbaar op de Codevoorbeelden: .NET Aspire met Angular, React en Vue pagina.

Belangrijk

Hoewel dit artikel is gericht op de front-end-onderdelen van de Single-Page App (SPA), is er een extra Node.js voorbeeld beschikbaar op de codevoorbeeldenpagina: .NET AspireNode.js voorbeeld, dat laat zien hoe je Node.js kunt gebruiken als een server-app met express.

Voorwaarden

Als u met .NET.NET Aspirewilt werken, hebt u het volgende lokaal geïnstalleerd:

Zie .NET.NET Aspire setup en hulpprogramma'sen .NET.NET Aspire SDK-voor meer informatie.

Daarnaast moet u Node.js installeren op uw computer. De voorbeeld-app in dit artikel is gebouwd met Node.js versie 20.12.2 en npm versie 10.5.1. Voer de volgende opdrachten uit om uw Node.js- en NPM-versies te controleren:

node --version
npm --version

Als u Node.js (inclusief npm) wilt downloaden, raadpleegt u de Node.js downloadpagina.

Voorbeeldbroncode klonen

Voer de volgende opdracht uit om de voorbeeldbroncode uit GitHubte klonen:

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

Navigeer na het klonen van de opslagplaats naar de map samples/AspireWithJavaScript map:

cd samples/AspireWithJavaScript

In deze map zijn er zes submappen vermeld in de volgende lijst:

  • AspireJavaScript.Angular: een Angular-app die de API voor weersvoorspelling gebruikt en de gegevens in een tabel weergeeft.
  • AspireJavaScript.AppHost: een .NET.NET Aspire project waarmee de andere apps in dit voorbeeld worden ingedeeld. Voor meer informatie, zie .NET.NET Aspire orchestratieoverzicht.
  • AspireJavaScript.MinimalApi: een HTTP-API die willekeurig gegenereerde weersvoorspellingsgegevens retourneert.
  • AspireJavaScript.React: een React-app die de API voor weersvoorspelling gebruikt en de gegevens in een tabel weergeeft.
  • AspireJavaScript.ServiceDefaults: het standaard gedeelde project voor .NET.NET Aspire projecten. Zie .NET.NET Aspire servicestandaardenvoor meer informatie.
  • AspireJavaScript.Vue: een Vue-app die de API voor weersvoorspelling gebruikt en de gegevens in een tabel weergeeft.

Afhankelijkheden client installeren

De voorbeeld-app laat zien hoe u JavaScript client-apps gebruikt die zijn gebouwd op Node.js. Elke client-app is geschreven met behulp van een npm create sjabloonopdracht of handmatig. De volgende tabel bevat de sjabloonopdrachten die worden gebruikt om elke client app te maken, samen met de standaardpoort:

App-type Opdracht Sjabloon maken Standaardpoort
Angular npm create @angular@latest 4200
React Er is geen sjabloon gebruikt. PORT env var
Vue npm create vue@latest 5173

Tip

U hoeft geen van deze opdrachten uit te voeren, omdat de voorbeeld-app al de clients bevat. In plaats daarvan is dit een referentiepunt waaruit de klanten zijn voortgekomen. Zie npm-init-voor meer informatie.

Als u de app wilt uitvoeren, moet u eerst de afhankelijkheden voor elke clientinstalleren. Hiervoor gaat u naar elke client map en voert u npm install opdrachten (of de installatiealias npm i) uit.

Afhankelijkheden Angular installeren

npm i ./AspireJavaScript.Angular/

Voor meer informatie over de Angular-app, zie verken de Angularclient.

Afhankelijkheden React installeren

npm i ./AspireJavaScript.React/

Voor meer informatie over de React-app, raadpleeg om de Reactclientte verkennen.

Afhankelijkheden Vue installeren

npm i ./AspireJavaScript.Vue/

Voor meer informatie over de Vue-app, zie om de Vueclientte verkennen.

De voorbeeld-app uitvoeren

Als u de voorbeeld-app wilt uitvoeren, gebruikt u het -commando met de orchestrator-app-host AspireJavaScript.AppHost.csproj als de --project-switch.

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

Het .NET.NET Aspire dashboard wordt gestart in uw standaardbrowser en ieder client app-eindpunt wordt weergegeven onder de kolom Eindpunten van de pagina Resources. In de volgende afbeelding ziet u het dashboard voor deze voorbeeld-app:

.NET Aspire dashboard met meerdere JavaScript-client-apps.

Het weatherapi service-eindpunt leidt naar een Swagger UI-pagina die de HTTP-API documenteert. Elke client-app gebruikt deze service om de weersvoorspellingsgegevens weer te geven. U kunt elke client-app bekijken door naar het bijbehorende eindpunt te navigeren in het .NET Aspire dashboard. De schermopnamen en de wijzigingen die zijn aangebracht op basis van het sjabloonstartpunt, worden in de volgende secties beschreven.

Druk in dezelfde terminalsessie die u hebt gebruikt om de app uit te voeren op Ctrl + C- om de app te stoppen.

De app-host verkennen

Als u wilt weten hoe elke client app-resource wordt ingedeeld, kijkt u naar het hostproject van de app. De app-host vereist het NuGet-pakket Aspire. Hosting.NodeJS om Node.js apps te hosten.

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

Het projectbestand definieert ook een builddoel dat ervoor zorgt dat de npm-afhankelijkheden worden geïnstalleerd voordat de app-host wordt gebouwd. De app-hostcode (Program.cs) declareert de client app-resources met behulp van de 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();

De voorgaande code:

  • Hiermee maakt u een DistributedApplicationBuilder.
  • Voegt de 'weatherapi'-service als een project toe aan de app-host.
    • Markeert de HTTP-eindpunten als extern.
  • Met een verwijzing naar de 'weatherapi'-service voegt u de 'angular', 'react' en 'vue' client apps toe als npm-apps.
    • Elke client-app is geconfigureerd voor uitvoering op een andere containerpoort en gebruikt de omgevingsvariabele PORT om de poort te bepalen.
    • Alle client-apps zijn ook afhankelijk van een Dockerfile om hun containerimage te bouwen en zijn geconfigureerd om in het publicatiemanifest als een container van de PublishAsDockerFile-API voor te komen.

Voor meer informatie over interne-lusnetwerken, zie .NET.NET Aspire overzicht van interne-lusnetwerken. Voor meer informatie over het implementeren van apps, zie .NET.NET Aspire manifestindeling voor implementatietoolbouwers.

Wanneer de app-host het starten van elke client app organiseert, wordt de opdracht npm run start gebruikt. Deze opdracht wordt gedefinieerd in de sectie scripts van het -pakket.json bestand voor elke client-app. Het start script wordt gebruikt om de client-app op de opgegeven poort te starten. Elke client-app is afhankelijk van een proxy om de 'weatherapi'-service aan te vragen.

De proxy is geconfigureerd in:

  • Het bestand proxy.conf.js voor de Angularclient.
  • Het bestand webpack.config.js voor de Reactclient.
  • Het .ts-bestand vite.config voor de Vueclient.

De Angularclient verkennen

Er zijn verschillende belangrijke wijzigingen van de oorspronkelijke Angular-sjabloon. De eerste is het toevoegen van een proxy.conf.js bestand. Dit bestand wordt gebruikt voor proxyaanvragen van de Angularclient naar de 'weatherapi'-service.

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

De .NET.NET Aspire-app-host stelt de services__weatherapi__http__0 omgevingsvariabele in, die wordt gebruikt om het service-eindpunt 'weatherapi' op te lossen. De voorgaande configuratieproxy's sturen HTTP-verzoeken die beginnen met /api door naar de doel-URL die is opgegeven in de omgevingsvariabele.

De tweede update is voor het -pakket.json bestand. Dit bestand wordt gebruikt om de Angularclient te configureren voor uitvoering op een andere poort dan de standaardpoort. Dit wordt bereikt met behulp van de omgevingsvariabele PORT en het run-script-os npm-pakket om de poort in te stellen.

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

De scripts sectie van het -pakket.json bestand wordt gebruikt om het start script te definiëren. Dit script wordt gebruikt door de opdracht npm start om de Angularclient-app te starten. Het start-script is geconfigureerd om het run-script-os-pakket te gebruiken om de poort in te stellen, waarbij het wordt gedelegeerd aan de ng serve-opdracht die de juiste --port-switch doorgeeft op basis van de syntaxis van het besturingssysteem.

Als u HTTP-aanroepen wilt uitvoeren naar de 'weatherapi'-service, moet de Angularclient-app worden geconfigureerd om de AngularHttpClient voor afhankelijkheidsinjectie te bieden. Dit wordt bereikt met behulp van de provideHttpClient helperfunctie tijdens het configureren van de toepassing in het app.config.ts-bestand.

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

Ten slotte moet de Angularclient-app het /api/WeatherForecast-eindpunt aanroepen om de weersvoorspellingsgegevens op te halen. Er zijn verschillende HTML-, CSS- en TypeScript-updates, die allemaal worden aangebracht in de volgende bestanden:

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

Als u de Angularclient-app wilt visualiseren, gaat u naar het eindpunt 'angular' in het .NET Aspire-dashboard. In de volgende afbeelding ziet u de Angularclient-app:

Angularclient app met valse weersvoorspellingen weergegeven als een tabel.

De Reactclient verkennen

De React-app is niet geschreven met behulp van een sjabloon en in plaats daarvan handmatig geschreven. De volledige broncode vindt u in de dotnet/aspire-samples-opslagplaats. Enkele belangrijke bezienswaardigheden vindt u in het bestand 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;

De App-functie is het toegangspunt voor de Reactclient-app. Het maakt gebruik van de useState en useEffect hooks om de status van de weersvoorspellingsgegevens te beheren. De fetch-API wordt gebruikt om een HTTP-aanvraag naar het /api/WeatherForecast-eindpunt te verzenden. Het antwoord wordt vervolgens geconverteerd naar JSON en ingesteld als de status van de weersvoorspellingsgegevens.

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

De voorgaande code definieert de module.exports als volgt:

  • De eigenschap entry is ingesteld op het bestand src/index.js.
  • De devServer is afhankelijk van een proxy om aanvragen door te sturen naar de 'weatherapi'-service, stelt de poort in op de omgevingsvariabele PORT en staat alle hosts toe.
  • De output resulteert in een map met een bundle.js bestand.
  • Stel plugins het src/index.html-bestand in als sjabloon en stel het favicon.ico-bestand beschikbaar.

De laatste updates zijn voor de volgende bestanden:

React-app draait

Als u de Reactclient-app wilt visualiseren, gaat u naar het eindpunt 'react' in het .NET Aspire-dashboard. In de volgende afbeelding ziet u de Reactclient-app:

Reactclient app met valse weersvoorspellingen weergegeven als een tabel.

De Vueclient verkennen

Er zijn verschillende belangrijke wijzigingen van de oorspronkelijke Vue-sjabloon. De belangrijkste updates betroffen de toevoeging van de fetch-aanroep in het TheWelcome.vue-bestand voor het ophalen van de weersvoorspellinggegevens van het /api/WeatherForecast-eindpunt. In het volgende codefragment ziet u de fetch aanroep:

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

Omdat de TheWelcome-integratie mountedis, wordt het /api/weatherforecast eindpunt aanroepen om de weersvoorspellingsgegevens op te halen. Het antwoord wordt vervolgens ingesteld als de forecasts-eigenschap voor gegevens. De Vueclient-app gebruikt de omgevingsvariabele PORT om de server-poort in te stellen. Dit wordt bereikt door het vite.config.ts-bestand bij te werken:

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

Daarnaast geeft de vite-configuratie de eigenschap server.proxy op om aanvragen door te sturen naar de 'weatherapi'-service. Dit wordt bereikt met behulp van de services__weatherapi__http__0 omgevingsvariabele, die wordt ingesteld door de .NET.NET Aspire app-host.

De laatste update van de sjabloon wordt gemaakt in de TheWelcome.vue bestand. Dit bestand roept het /api/WeatherForecast-eindpunt aan om de weersvoorspellingsgegevens op te halen en de gegevens in een tabel weer te geven. Het bevat CSS-, HTML- en TypeScript-updates.

Vue-app draait

Als u de Vueclient-app wilt visualiseren, gaat u naar het eindpunt 'vue' in het .NET Aspire-dashboard. In de volgende afbeelding ziet u de Vueclient-app:

Vueclient app met valse weersvoorspellingen weergegeven als een tabel.

Overwegingen bij de implementatie

De voorbeeldbroncode voor dit artikel is ontworpen om lokaal te worden uitgevoerd. Elke client-app wordt uitgerold als een containerimage. De Dockerfile voor elke client-app wordt gebruikt om de containerafbeelding te bouwen. Elke Dockerfile is identiek en gebruikt een multistage build om een containerafbeelding te maken die gereed is voor productie.

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-apps zijn momenteel geconfigureerd om als echte SPA-applicaties te draaien en zijn niet geconfigureerd om in een serverzijde-gerenderde (SSR) modus te draaien. Ze zitten achter nginx, die wordt gebruikt om de statische bestanden te bedienen. Ze gebruiken een default.conf.template-bestand om nginx- te configureren voor proxyaanvragen voor de client-app.

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

overwegingen voor Node.jsserver-apps

Hoewel dit artikel gericht is op client apps, hebt u mogelijk scenario's waarin u een Node.jsserver-app moet hosten. Dezelfde semantiek is vereist voor het hosten van een Node.jsserver-app als een SPA-client-app. De .NET.NET Aspire app-host vereist een pakketreferentie naar het Aspire.Hosting.NodeJS NuGet-pakket en de code moet AddNodeApp of AddNpmAppaanroepen. Deze API's zijn handig voor het toevoegen van bestaande JavaScript-apps aan de .NET.NET Aspire app-host.

Wanneer u geheimen configureert en omgevingsvariabelen doorgeeft aan op JavaScript gebaseerde apps, ongeacht of ze client of server apps zijn, gebruikt u parameters. Zie voor meer informatie .NET.NET Aspire: Externe parameters, geheimen.

De OpenTelemetry JavaScript SDK gebruiken

Als u OpenTelemetry logboeken, traceringen en metrische gegevens uit een Node.jsserver-app wilt exporteren, gebruikt u de OpenTelemetry JavaScript SDK-.

Voor een volledig voorbeeld van een Node.jsserver-app met behulp van de OpenTelemetry JavaScript SDK kunt u verwijzen naar de codevoorbeelden: .NET AspireNode.js voorbeeldpagina. Bekijk het instrumentation.js-bestand van het voorbeeld, waarin wordt gedemonstreert hoe u de OpenTelemetry JavaScript SDK configureert voor het exporteren van logboeken, traceringen en metrische gegevens:

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

Tip

Zie de .NET.NET Aspire dashboard OTEL CORS-instellingen pagina om de .NET.NET Aspire dashboard OTEL CORS-instellingen te configureren.

Samenvatting

Hoewel er verschillende overwegingen zijn die buiten het bereik van dit artikel vallen, hebt u geleerd hoe u .NET Aspire projecten bouwt die gebruikmaken van Node.js en Node Package Manager (npm). U hebt ook geleerd hoe u de AddNpmApp-API's gebruikt om Node.js apps en apps te hosten die worden uitgevoerd vanuit een -pakket.json bestand respectievelijk. Ten slotte hebt u geleerd hoe u de npm CLI kunt gebruiken om Angular, Reacten Vueclient-apps te maken en hoe u deze configureert voor uitvoering op verschillende poorten.

Zie ook