Orquestre aplicativos de Node.js no .NET Aspire
Neste artigo, você aprenderá a usar os aplicativos Node.js e Node Package Manager (npm
) em um projeto .NET.NET Aspire. O aplicativo de exemplo neste artigo demonstra experiências Angular, Reacte Vueclient. As APIs .NET.NET Aspire a seguir existem para dar suporte a esses cenários, e elas fazem parte do Aspire. Hosting.NodeJS pacote NuGet:
A diferença entre essas duas APIs é que a primeira é usada para hospedar aplicativos Node.js, enquanto a segunda é usada para hospedar aplicativos que são executados a partir de um pacote .json seção scripts
do arquivo — e o comando npm run <script-name>
correspondente.
Dica
O código-fonte de exemplo para este artigo está disponível em GitHub, e há detalhes disponíveis no Code Samples: .NET Aspire com Angular, React e Vue página.
Importante
Embora este artigo esteja focado em bits de frontend do Single-Page App (SPA), há um exemplo de Node.js adicional disponível na página Code Samples: .NET AspireNode.js exemplo, que demonstra como usar Node.js como um aplicativo server com Express.
Pré-requisitos
Para trabalhar com .NET.NET Aspire, você precisa do seguinte instalado localmente:
- .NET 8,0 ou .NET 9,0
- Um ambiente de execução de contentor compatível com OCI, como:
- Docker Desktop ou Podman. Para obter mais informações, consulte Container runtime.
- Um ambiente de desenvolvedor integrado (IDE) ou editor de código, como:
- Visual Studio 2022 versão 17.9 ou superior (opcional)
-
Visual Studio Code (Opcional)
- C# Dev Kit: Extensão (Opcional)
- JetBrains Rider com .NET.NET Aspire plug-in (Opcional)
Para mais informações, consulte a configuração e ferramentas .NET.NET Aspiree o SDK .NET.NET Aspire.
Além disso, você precisa instalar Node.js em sua máquina. O aplicativo de exemplo neste artigo foi criado com Node.js versão 20.12.2 e npm versão 10.5.1. Para verificar as versões Node.js e npm, execute os seguintes comandos:
node --version
npm --version
Para descarregar Node.js (incluindo npm
), consulte a página de descarregamento de Node.js.
Exemplo de clonagem de código-fonte
Para clonar o código-fonte de exemplo do GitHub, execute o seguinte comando:
git clone https://github.com/dotnet/aspire-samples.git
Depois de clonar o repositório, navegue até a pasta
cd samples/AspireWithJavaScript
A partir deste diretório, há seis diretórios filho descritos na lista a seguir:
- AspireJavaScript.Angular: Um aplicativo Angular que consome a API de previsão do tempo e exibe os dados em uma tabela.
- AspireJavaScript.AppHost: Um projeto .NET.NET Aspire que orquestra os outros aplicativos neste exemplo. Para obter mais informações, consulte .NET.NET Aspire visão geral da orquestração.
- AspireJavaScript.MinimalApi: Uma API HTTP que retorna dados de previsão do tempo gerados aleatoriamente.
- AspireJavaScript.React: Um aplicativo React que consome a API de previsão do tempo e exibe os dados em uma tabela.
- AspireJavaScript.ServiceDefaults: O projeto compartilhado padrão para .NET.NET Aspire projetos. Para obter mais informações, consulte .NET.NET Aspire padrões de serviço.
- AspireJavaScript.Vue: Um aplicativo Vue que consome a API de previsão do tempo e exibe os dados em uma tabela.
Instalar dependências client
A aplicação de exemplo demonstra como usar as aplicações JavaScript client criadas em cima de Node.js. Cada aplicativo client foi escrito usando um comando de modelo npm create
ou manualmente. A tabela a seguir lista os comandos de modelo usados para criar cada aplicativo client, juntamente com a porta padrão:
Tipo de aplicativo | Comando Criar modelo | Porta padrão |
---|---|---|
Angular | npm create @angular@latest |
4200 |
React | Não usou um modelo. | PORTO env var |
Vue | npm create vue@latest |
5173 |
Dica
Você não precisa executar nenhum desses comandos, pois o aplicativo de exemplo já inclui os clientes. Em vez disso, este é um ponto de referência a partir do qual os clientes foram criados. Para obter mais informações, consulte npm-init.
Para executar o aplicativo, primeiro você precisa instalar as dependências para cada client. Para fazer isso, navegue até cada pasta client e execute npm install
comandos (ou o alias de instalação npm i
).
Instalar dependências Angular
npm i ./AspireJavaScript.Angular/
Para obter mais informações sobre o aplicativo Angular, consulte e explore o Angularclient.
Instalar dependências React
npm i ./AspireJavaScript.React/
Para obter mais informações sobre o aplicativo React, consulte para explorar o Reactclient.
Instalar dependências Vue
npm i ./AspireJavaScript.Vue/
Para obter mais informações sobre o aplicativo Vue, consulte o e explore o Vueclient.
Executar o aplicativo de exemplo
Para executar o aplicativo de exemplo, chame o comando dotnet run dado ao host do aplicativo orchestrator AspireJavaScript.AppHost.csproj como a opção --project
:
dotnet run --project ./AspireJavaScript.AppHost/AspireJavaScript.AppHost.csproj
O painel .NET.NET Aspire é iniciado no seu navegador padrão e cada endpoint da aplicação client é exibido sob a coluna Endpoints da página de Recursos . A imagem a seguir mostra o painel para este aplicativo de exemplo:
O ponto de extremidade do serviço weatherapi
resolve-se numa página de visualização Swagger que tem documentação sobre a API HTTP. Cada aplicativo client consome esse serviço para exibir os dados de previsão do tempo. Você pode visualizar cada aplicativo client, navegando até o endpoint correspondente no dashboard .NET Aspire. Suas capturas de tela e as modificações feitas a partir do ponto de partida do modelo são detalhadas nas seções a seguir.
Na mesma sessão de terminal que você usou para executar o aplicativo, pressione Ctrl + C para parar o aplicativo.
Explore o host do aplicativo
Para ajudar a entender como cada recurso de aplicativo client é orquestrado, consulte o projeto do host da aplicação. O host do aplicativo requer o Aspire. Hosting.NodeJS pacote NuGet para hospedar aplicativos 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>
O arquivo de projeto também define um destino de compilação que garante que as dependências do npm sejam instaladas antes que o host do aplicativo seja criado. O código de host do aplicativo (Program.cs) declara os recursos do aplicativo client usando a 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();
O código anterior:
- Cria um DistributedApplicationBuilder.
- Adiciona o serviço "weatherapi" como um projeto ao host do aplicativo.
- Marca os pontos de extremidade HTTP como externos.
- Com uma referência ao serviço "weatherapi", adiciona as apps client "angular", "react" e "vue" como aplicativos npm.
- Cada aplicativo client é configurado para ser executado em uma porta de contêiner diferente e usa a variável de ambiente
PORT
para determinar a porta. - Todos os aplicativos client também dependem de um Dockerfile para criar sua imagem de contêiner e são configurados para se expressar no manifesto de publicação como um contêiner da API PublishAsDockerFile.
- Cada aplicativo client é configurado para ser executado em uma porta de contêiner diferente e usa a variável de ambiente
Para obter mais informações sobre redes de loop interno, consulte .NET.NET Aspire visão geral da rede de loop interno. Para obter mais informações sobre como implantar aplicativos, consulte .NET.NET Aspire formato de manifesto para construtores de ferramentas de implantação.
Quando o host do aplicativo orquestra a inicialização de cada aplicativo client, ele usa o comando npm run start
. Este comando é definido na seção scripts
do pacote .json arquivo para cada aplicativo client. O script start
é usado para iniciar o aplicativo client na porta especificada. Cada aplicativo client depende de um proxy para solicitar o serviço "weatherapi".
O proxy está configurado em:
- O arquivo proxy.conf.js para o Angularclient.
- O arquivo webpack.config.js para o Reactclient.
- O arquivo vite.config.ts para o Vueclient.
Explore o Angularclient
Há várias modificações importantes do modelo Angular original. O primeiro é a adição de um arquivo proxy.conf.js. Este arquivo é usado para solicitações de proxy do Angularclient para o serviço "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": "",
},
},
};
O host da app .NET.NET Aspire define a variável de ambiente services__weatherapi__http__0
, que é usada para determinar o endpoint do serviço "weatherapi". A configuração anterior reencaminha as solicitações HTTP que começam com /api
para o URL de destino que está especificado na variável de ambiente.
A segunda atualização é para o pacote . O arquivojson. Esse arquivo é usado para configurar o Angularclient para ser executado em uma porta diferente da porta padrão. Isso é conseguido usando a variável de ambiente PORT
e o pacote npm run-script-os
para definir a porta.
{
"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"
}
}
A seção scripts
do pacote , o arquivojson é usado para definir o script start
. Esse script é usado pelo comando npm start
para iniciar o aplicativo Angularclient. O script start
é configurado para usar o pacote run-script-os
para definir a porta, que delega ao comando ng serve
passando a opção --port
apropriada com base na sintaxe apropriada ao SO.
Para fazer chamadas HTTP para o serviço "weatherapi", a aplicação Angularclient precisa ser configurada para fornecer o AngularHttpClient
para injeção de dependência. Isso é conseguido usando a função auxiliar provideHttpClient
ao configurar o aplicativo no arquivo 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()
]
};
Finalmente, a aplicação Angularclient precisa chamar o endpoint /api/WeatherForecast
para recuperar os dados da previsão do tempo. Há várias atualizações HTML, CSS e TypeScript, todas feitas para os seguintes arquivos:
- app.component.css: Atualize o CSS para estilizar a tabela.
- app.component.html: Atualize o HTML para exibir os dados da previsão do tempo em uma tabela.
-
app.component.ts: Atualiza o TypeScript para chamar o endpoint
/api/WeatherForecast
e exibir os dados na tabela.
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 aplicação em execução
Para visualizar a aplicação Angularclient, navegue até o endpoint "angular" no painel de controlo .NET Aspire. A imagem a seguir mostra o aplicativo Angularclient:
Explore Reactclient
O aplicativo React não foi escrito usando um modelo e, em vez disso, foi escrito manualmente. O código-fonte completo pode ser encontrado no repositório dotnet/aspire-samples. Alguns dos principais pontos de interesse encontram-se no arquivo 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;
A função App
é o ponto de entrada para o aplicativo Reactclient. Ele usa os ganchos de useState
e useEffect
para gerenciar o estado dos dados de previsão do tempo. A API fetch
é usada para fazer uma solicitação HTTP para o endpoint /api/WeatherForecast
. A resposta é então convertida em JSON e definida como o estado dos dados de previsão meteorológica.
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"],
},
],
},
};
};
O código anterior define o module.exports
da seguinte forma:
- A propriedade
entry
é atribuída ao ficheiro src/index.js. - O
devServer
utiliza um proxy para encaminhar pedidos para o serviço "weatherapi", configura a porta com a variável de ambientePORT
e permite todos os hosts. - O
output
resulta em uma pasta dist com um arquivo bundle.js. - O
plugins
definiu o ficheiro src/index.html como o modelo e expos o ficheiro favicon.ico.
As atualizações finais são para os seguintes arquivos:
- App.css: Atualize o CSS para estilizar a tabela.
-
App.js: Atualize o JavaScript para chamar o ponto de extremidade
/api/WeatherForecast
e exibir os dados na tabela.
React aplicação em execução
Para visualizar a aplicação Reactclient, navegue até o "endpoint"reactno painel .NET Aspire. A imagem a seguir mostra o aplicativo Reactclient:
Explore os Vueclient
Há várias modificações importantes do modelo Vue original. As principais atualizações foram a adição da chamada de fetch
no arquivo TheWelcome.vue para recuperar os dados de previsão do tempo do endpoint /api/WeatherForecast
. O trecho de código a seguir demonstra a chamada 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>
Como a integração de TheWelcome
é mounted
, chama o endpoint /api/weatherforecast
para obter os dados da previsão do tempo. A resposta é então definida como a propriedade de dados forecasts
. Para definir a porta server, o aplicativo Vueclient usa a variável de ambiente PORT
. Isto é conseguido através da atualização do ficheiro 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
}
}
}
})
Além disso, a configuração do Vite especifica a propriedade server.proxy
para encaminhar solicitações para o serviço "weatherapi". Isso é conseguido usando a variável de ambiente services__weatherapi__http__0
, que é definida pelo host do aplicativo .NET.NET Aspire.
A atualização final do modelo é aplicada ao arquivo TheWelcome.vue. Esse arquivo chama o ponto de extremidade /api/WeatherForecast
para recuperar os dados de previsão do tempo e exibe os dados em uma tabela. Inclui atualizações CSS, HTML e TypeScript.
Vue aplicação em execução
Para visualizar a aplicação Vueclient, navegue até ao endpoint "vue" no painel .NET Aspire. A imagem a seguir mostra o aplicativo Vueclient:
Considerações sobre implantação
O código-fonte de exemplo para este artigo foi projetado para ser executado localmente. Cada aplicação client é implantada como uma imagem de contentor. O Dockerfile para cada aplicativo client é usado para criar a imagem do contêiner. Cada Dockerfile é idêntico, utilizando uma construção em vários estágios para criar uma imagem de contenedor pronta para produção.
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;"]
Os aplicativos client estão atualmente configurados para serem executados como aplicativos SPA verdadeiros e não estão configurados para serem executados em um modo renderizado do lado server(SSR). Eles estão por trás de nginx, que é usado para servir os arquivos estáticos. Eles usam um arquivo de default.conf.template
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 considerações sobre o aplicativo
Embora este artigo se concentre em aplicativos client, você pode ter cenários em que precisa hospedar um aplicativo Node.jsserver. A mesma semântica é necessária para hospedar um aplicativo Node.jsserver como um aplicativo SPA client. O anfitrião da aplicação .NET.NET Aspire requer uma referência de pacote para o pacote NuGet Aspire.Hosting.NodeJS e o código precisa chamar AddNodeApp
ou AddNpmApp
. Essas APIs são úteis para adicionar aplicativos JavaScript existentes ao host do aplicativo .NET.NET Aspire.
Ao configurar segredos e passar variáveis de ambiente para aplicativos baseados em JavaScript, sejam eles client ou server aplicativos, use parâmetros. Para obter mais informações, consulte .NET.NET Aspire: Parâmetros externos — segredos.
Utilizar o OpenTelemetry JavaScript SDK
Para exportar logs, rastreamentos e métricas de OpenTelemetry de uma aplicação Node.jsserver, use o OpenTelemetry JavaScript SDK.
Para obter um exemplo completo de um aplicativo de Node.jsserver usando o OpenTelemetry JavaScript SDK, você pode consultar a página de exemplos Code Samples: .NET AspireNode.js. Considere o arquivo de instrumentation.js do exemplo, que demonstra como configurar o OpenTelemetry JavaScript SDK para exportar logs, rastreamentos e métricas:
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();
}
Dica
Para definir as configurações de OTEL CORS do painel .NET.NET Aspire, consulte a página de configurações de OTEL CORS do painel .NET.NET Aspire.
Resumo
Embora existam várias considerações que estão além do escopo deste artigo, aprendeste como criar projetos .NET Aspire que utilizam o Node.js e o Node Package Manager (npm
). Você também aprendeu como usar as APIs AddNpmApp para hospedar aplicativos Node.js e aplicativos que são executados a partir de um pacote .json ficheiro, respetivamente. Finalmente, você aprendeu como usar a npm
CLI para criar aplicativos Angular, Reacte Vueclient e como configurá-los para serem executados em portas diferentes.
Ver também
- exemplos de código: .NET Aspire com Angular, Reacte Vue
- Exemplos de código : .NET AspireNode.js App