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 Vue clientervaringen. 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 eerste wordt gebruikt voor het hosten van Node.js-apps, terwijl de laatste wordt gebruikt voor het hosten van apps die worden uitgevoerd vanuit de scripts
-sectie van een package.json-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 (SPA) frontend-gedeeltes van de Single-Page App, is er een extra Node.js voorbeeld beschikbaar op de pagina van de codevoorbeelden: het .NET AspireNode.js voorbeeld, dat laat zien hoe u Node.js als een server-app kunt gebruiken met express.
Voorwaarden
Als u met .NET.NET Aspirewilt werken, hebt u het volgende lokaal geïnstalleerd:
- .NET 8,0 of .NET 9,0
- Een OCI-compatibele containerruntime, zoals:
- Docker Desktop of Podman. Zie voor meer informatie Container Runtime.
- Een IDE (Integrated Developer Environment) of code-editor, zoals:
- Visual Studio 2022 versie 17.9 of hoger (optioneel)
-
Visual Studio Code (optioneel)
- C# Dev Kit: extensie- (optioneel)
- JetBrains Rider met .NET.NET Aspire Plugin (Optioneel)
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
Vanuit deze map zijn er zes submappen beschreven 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.
Clientafhankelijkheden 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 client installeren. Hiervoor gaat u naar elke clientmap en voert u npm install
(of de installatiealias npm i
) uit.
Afhankelijkheden Angular installeren
npm i ./AspireJavaScript.Angular/
Zie de Angular-clientverkennen voor meer informatie over de Angular-app.
Afhankelijkheden React installeren
npm i ./AspireJavaScript.React/
Zie de React-clientverkennen voor meer informatie over de React-app.
Afhankelijkheden Vue installeren
npm i ./AspireJavaScript.Vue/
Zie de Vue-clientverkennen voor meer informatie over de Vue-app.
De voorbeeld-app uitvoeren
Als u de voorbeeld-app wilt uitvoeren, roept u het commando dotnet run aan, waarbij de orchestrator-app-versie AspireJavaScript.AppHost.csproj wordt gebruikt als de --project
-switch.
dotnet run --project ./AspireJavaScript.AppHost/AspireJavaScript.AppHost.csproj
Het .NET.NET Aspire-dashboard wordt in uw standaardbrowser gestart en elk eindpunt van de client-app wordt weergegeven in de kolom Eindpunten op de pagina Resources. In de volgende afbeelding ziet u het dashboard voor deze voorbeeld-app:
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.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 app-hostproject. 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.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>
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 resources van de client-app 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 client-apps 'angular', 'react' en 'vue' 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 containerafbeeldingen te bouwen en zijn geconfigureerd om zichzelf te presenteren in het publicatiemanifest als een container van de PublishAsDockerFile-API.
- Elke client-app is geconfigureerd voor uitvoering op een andere containerpoort en gebruikt de omgevingsvariabele
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 package.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 proxy.conf.js-bestand voor de Angular-client.
- Het webpack.config.js-bestand voor de React-client.
- Het vite.config.ts-bestand voor de Vue-client.
De Angular-client 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 Angular-client 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.
Voeg vervolgens het proxybestand toe aan het angular.json-bestand.
Werk het serve
doel bij om de proxyConfig
optie op te nemen, die verwijst naar het gemaakte proxy.conf.js-bestand.
De Angular CLI gebruikt nu de proxyconfiguratie tijdens het leveren van de Angular client-app.
"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"
}
},
De derde update is naar het package.json-bestand. Dit bestand wordt gebruikt om de Angular-client 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": "^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"
}
}
De scripts
sectie van het package.json-bestand wordt gebruikt om het start
script te definiëren. Dit script wordt gebruikt door de opdracht npm start
om de Angular-client-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 Angular-client-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 Angular client-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:
- app.component.css: de CSS bijwerken om de tabel te stylen.
- app.component.html: de HTML bijwerken om de weersvoorspellingsgegevens in een tabel weer te geven.
-
app.component.ts: Het TypeScript bijwerken om het
/api/WeatherForecast
-eindpunt aan te roepen en de gegevens in de tabel weer te geven.
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 draait
Als u de Angular-client-app wilt visualiseren, gaat u naar het eindpunt 'angular' in het .NET Aspire-dashboard. In de volgende afbeelding ziet u de Angular client-app:
De React-client verkennen
De React-app is niet geschreven met behulp van een sjabloon en in plaats daarvan handmatig geschreven. De volledige broncode is te vinden 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 React-client-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 omgevingsvariabelePORT
en staat alle hosts toe. - De
output
resulteert in een dist 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:
- App.css: de CSS bijwerken om de tabel te stylen.
-
App.js: JavaScript bijwerken om het
/api/WeatherForecast
-eindpunt aan te roepen en de gegevens in de tabel weer te geven.
React app draait
Als u de React-client-app wilt visualiseren, gaat u naar het eindpunt 'react' in het .NET Aspire-dashboard. In de volgende afbeelding ziet u de React client-app:
De Vue-client verkennen
Er zijn verschillende belangrijke wijzigingen van de oorspronkelijke Vue-sjabloon. De primaire updates waren de toevoeging van de fetch
-aanroep in het bestand TheWelcome.vue om de weervoorspellingsgegevens op te halen uit 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 mounted
is, wordt het /api/weatherforecast
eindpunt aanroepen om de weersvoorspellingsgegevens op te halen. Het antwoord wordt vervolgens ingesteld als de forecasts
-eigenschap voor gegevens. De Vue-client-app gebruikt de omgevingsvariabele PORT
om de serverpoort 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 het bestand TheWelcome.vue. 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 is aan het draaien
Als u de Vue-client-app wilt visualiseren, gaat u naar het eindpunt 'vue' in het .NET Aspire-dashboard. In de volgende afbeelding ziet u de Vue client-app:
Overwegingen bij de implementatie
De voorbeeldbroncode voor dit artikel is ontworpen om lokaal te worden uitgevoerd. Elke client-applicatie wordt uitgevoerd als een container-image. 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-toepassingen te draaien en zijn niet geconfigureerd om in een server-side rendering (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 naar 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 met betrekking tot Node.js server-apps
Hoewel dit artikel is gericht op client-apps, hebt u mogelijk scenario's waarin u een Node.js server-app moet hosten. Dezelfde semantiek is vereist voor het hosten van een Node.js-serverapp als van een SPA-clientapp. De .NET.NET Aspire app-host vereist een pakketreferentie naar het Aspire.Hosting.NodeJS NuGet-pakket en de code moet AddNodeApp
of AddNpmApp
aanroepen. Deze API's zijn handig voor het toevoegen van bestaande JavaScript-apps aan de .NET.NET Aspire app-host.
Bij het configureren van geheimen en het doorgeven van omgevingsvariabelen aan op JavaScript gebaseerde apps, ongeacht of het 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.js server-app wilt exporteren, gebruikt u de OpenTelemetry JavaScript SDK-.
Voor een volledig voorbeeld van een Node.js-server-app met behulp van de OpenTelemetry JavaScript SDK kunt u verwijzen naar de codevoorbeelden: .NET AspireNode.js voorbeeldpagina van. 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();
}
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 voor het hosten van Node.js apps en apps die worden uitgevoerd vanuit een package.json bestand. Ten slotte hebt u geleerd hoe u de npm
CLI kunt gebruiken om Angular, Reacten Vue client-apps te maken en hoe u deze configureert voor uitvoering op verschillende poorten.