Управление приложениями Node.js в .NET Aspire
В этой статье вы узнаете, как использовать приложения Node.js и диспетчер пакетов узлов (npm
) в проекте .NET.NET Aspire. Пример приложения в этой статье демонстрирует Angular, Reactи Vue клиентский опыт. Следующие .NET.NET Aspire API существуют для поддержки этих сценариев, и они входят в пакет NuGet Aspire.Hosting.NodeJS:
Разница между этими двумя API заключается в том, что первый используется для размещения Node.js приложений, а последний используется для размещения приложений, выполняемых из раздела файла scripts
и соответствующей команды npm run <script-name>
.
Подсказка
Пример исходного кода для этой статьи доступен на GitHub, а дополнительные сведения доступны на странице в разделе Примеры кода: .NET Aspire с Angular, React и Vue.
Важный
Хотя эта статья посвящена частям интерфейса приложения (SPA) Single-Page, на странице Node.js представлен дополнительный пример Node.js, который демонстрирует, как серверное приложение с использованием express.
Необходимые условия
Для работы с .NET.NET Aspireвам потребуется следующее установить локально:
- .NET 8.0 или .NET 9.0
- Среда выполнения контейнера, совместимая с OCI, например:
- Docker рабочий стол или Podman. Для получения дополнительной информации см. контейнерная среда выполнения.
- Интегрированная среда разработки (IDE) или редактор кода, например:
- Visual Studio 2022 версия 17.9 или более поздняя (необязательно)
-
Visual Studio Code (необязательно)
- C# Dev Kit: расширение (необязательно)
- JetBrains Rider с плагином .NET.NET Aspire (необязательно)
Дополнительные сведения см. в разделе .NET.NET Aspire настройки и инструментови .NET.NET Aspire пакета SDK.
Кроме того, необходимо установить Node.js на компьютере. Пример приложения в этой статье создан с Node.js версии 20.12.2 и npm версии 10.5.1. Чтобы проверить ваши версии Node.js и npm, выполните следующие команды:
node --version
npm --version
Чтобы скачать Node.js (включая npm
), перейдите на страницу загрузки Node.js.
Клонировать пример исходного кода
Чтобы клонировать пример исходного кода из GitHub, выполните следующую команду:
git clone https://github.com/dotnet/aspire-samples.git
После клонирования репозитория перейдите к папке samples/AspireWithJavaScript:
cd samples/AspireWithJavaScript
В этом каталоге есть шесть дочерних каталогов, описанных в следующем списке:
- AspireJavaScript.Angular: приложение Angular, которое использует API прогнозирования погоды и отображает данные в таблице.
- AspireJavaScript.AppHost: проект .NET.NET Aspire, который управляет другими приложениями в этом примере. Для получения дополнительной информации см. обзор оркестрации .NET.NET Aspire.
- AspireJavaScript.MinimalApi: HTTP API, который возвращает данные прогноза погоды случайным образом.
- AspireJavaScript.React: приложение React, которое использует API прогнозирования погоды и отображает данные в таблице.
- AspireJavaScript.ServiceDefaults: общий проект по умолчанию для .NET.NET Aspire проектов. Для получения дополнительной информации см. настройки по умолчанию для службы .NET.NET Aspire.
- AspireJavaScript.Vue: приложение Vue, которое использует API прогнозирования погоды и отображает данные в таблице.
Установка зависимостей клиента
В примере приложения показано, как использовать клиентские приложения JavaScript, созданные на основе Node.js. Каждое клиентское приложение было написано либо с помощью команды шаблона npm create
, либо вручную. В следующей таблице перечислены команды шаблона, используемые для создания каждого клиентского приложения, а также порта по умолчанию:
Тип приложения | Команда создания шаблона | Порт по умолчанию |
---|---|---|
Angular | npm create @angular@latest |
4200 |
React | Не использовался шаблон. | PORT env var |
Vue | npm create vue@latest |
5173 |
Подсказка
Вам не нужно выполнять какие-либо из этих команд, так как пример приложения уже включает клиенты. Скорее, это отправная точка, от которой были созданы клиенты. Дополнительные сведения см. в разделе npm-init.
Чтобы запустить приложение, сначала необходимо установить зависимости для каждого клиента. Для этого перейдите к каждой клиентской папке и выполните команды npm install
(или псевдоним установки npm i
).
Установка зависимостей Angular
npm i ./AspireJavaScript.Angular/
Дополнительные сведения о приложении Angular см. в разделе исследования клиента Angular.
Установка зависимостей React
npm i ./AspireJavaScript.React/
Дополнительные сведения о приложении React см. в разделе исследования клиента React.
Установка зависимостей Vue
npm i ./AspireJavaScript.Vue/
Дополнительные сведения о приложении Vue см. в разделе исследования клиента Vue.
Запуск примера приложения
Чтобы запустить пример приложения, вызовите команду dotnet run, указав в качестве параметра хост приложения оркестратора --project
.
dotnet run --project ./AspireJavaScript.AppHost/AspireJavaScript.AppHost.csproj
Панель мониторинга .NET.NET Aspire запускается в браузере по умолчанию, а каждая конечная точка клиентского приложения отображается в столбце Конечные точки страницы Ресурсов. На следующем рисунке показана панель мониторинга для этого примера приложения:
Конечная точка службы weatherapi
ведет к странице Swagger UI, которая документирует HTTP API. Каждое клиентское приложение использует эту службу для отображения данных прогноза погоды. Вы можете просмотреть каждое клиентское приложение, перейдя к соответствующей конечной точке на панели мониторинга .NET.NET Aspire. Их снимки экрана и изменения, внесенные из начальной точки шаблона, подробно описаны в следующих разделах.
В том же сеансе терминала, который использовался для запуска приложения, нажмите клавиши CTRL + C, чтобы остановить приложение.
Изучение хоста приложения
Чтобы понять, как управляется каждый ресурс клиентского приложения, просмотрите проект узла приложения. Хост приложения требует пакета NuGet Aspire.Hosting.NodeJS для размещения приложений Node.js:
<Project Sdk="Microsoft.NET.Sdk">
<Sdk Name="Aspire.AppHost.Sdk" Version="9.1.0" />
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsAspireHost>true</IsAspireHost>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Aspire.Hosting.AppHost" Version="9.1.0" />
<PackageReference Include="Aspire.Hosting.NodeJs" Version="9.1.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AspireJavaScript.MinimalApi\AspireJavaScript.MinimalApi.csproj" />
</ItemGroup>
<Target Name="RestoreNpm" BeforeTargets="Build" Condition=" '$(DesignTimeBuild)' != 'true' ">
<ItemGroup>
<PackageJsons Include="..\*\package.json" />
</ItemGroup>
<!-- Install npm packages if node_modules is missing -->
<Message Importance="Normal" Text="Installing npm packages for %(PackageJsons.RelativeDir)" Condition="!Exists('%(PackageJsons.RootDir)%(PackageJsons.Directory)/node_modules')" />
<Exec Command="npm install" WorkingDirectory="%(PackageJsons.RootDir)%(PackageJsons.Directory)" Condition="!Exists('%(PackageJsons.RootDir)%(PackageJsons.Directory)/node_modules')" />
</Target>
</Project>
Файл проекта также определяет целевой объект сборки, обеспечивающий установку зависимостей npm перед сборкой узла приложения. Код узла приложения (Program.cs) объявляет ресурсы клиентского приложения с помощью 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();
Предыдущий код:
- Создает объект DistributedApplicationBuilder.
- Добавляет службу weatherapi как проект на хост приложения.
- Помечает конечные точки HTTP как внешние.
- Ссылаясь на службу «weatherapi», добавляет клиентские приложения angular, react и vue как приложения npm.
- Каждое клиентское приложение настроено для запуска на другом порту контейнера и использует переменную среды
PORT
для определения порта. - Все клиентские приложения также используют Dockerfile для создания контейнерного образа и настроены отображаться в манифесте публикации как контейнер из API PublishAsDockerFile.
- Каждое клиентское приложение настроено для запуска на другом порту контейнера и использует переменную среды
Дополнительные сведения о сети внутреннего цикла см. в .NET.NET Aspire обзоре сети внутреннего цикла. Дополнительные сведения о развертывании приложений см. в формате манифеста .NET.NET Aspire для разработчиков инструментов развертывания.
Когда хост приложения управляет запуском каждого клиентского приложения, он использует команду npm run start
. Эта команда определена в разделе scripts
файла package.json для каждого клиентского приложения. Скрипт start
используется для запуска клиентского приложения на указанном порту. Каждое клиентское приложение использует прокси-сервер для запроса службы weatherapi.
Прокси-сервер настроен в:
- Файл proxy.conf.js для клиента Angular.
- Файл webpack.config.js для клиента React.
- Файл vite.config.ts для клиента Vue.
Изучение клиента Angular
Существует несколько ключевых изменений исходного шаблона Angular. Первым является добавление файла proxy.conf.js. Этот файл используется для прокси-запросов от клиента Angular к службе 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 задает переменную среды services__weatherapi__http__0
, которая используется для определения адреса конечной точки сервиса weatherapi. Предыдущая конфигурация проксирует HTTP-запросы, начинающиеся с /api
, к целевому URL-адресу, указанному в переменной среды.
Затем добавьте прокси-файл в файл angular.json.
Обновите целевой объект serve
, чтобы включить параметр proxyConfig
, ссылаясь на созданный файл proxy.conf.js.
Теперь Angular CLI будет использовать конфигурацию прокси-сервера при обслуживании клиентского приложения Angular.
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"configurations": {
"production": {
"buildTarget": "weather:build:production"
},
"development": {
"buildTarget": "weather:build:development"
}
},
"defaultConfiguration": "development",
"options": {
"proxyConfig": "proxy.conf.js"
}
},
Третье обновление — это файл package.json. Этот файл используется для настройки Angular клиента для запуска на порте, отличном от порта по умолчанию. Это достигается с помощью переменной среды PORT
и пакета npm run-script-os
для задания порта.
{
"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"
}
}
Раздел scripts
файла package.json используется для определения скрипта start
. Этот скрипт используется командой npm start
для запуска клиентского приложения Angular. Скрипт start
настроен на использование пакета run-script-os
для задания порта, который делегирует команде ng serve
передачу соответствующего переключателя --port
, основываясь на синтаксисе, подходящем для ОС.
Чтобы выполнить HTTP-вызовы к службе weatherapi, необходимо настроить клиентское приложение Angular для предоставления AngularHttpClient
для внедрения зависимостей. Это достигается с помощью вспомогательной функции provideHttpClient
при настройке приложения в файле 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()
]
};
Наконец, клиентское приложение Angular должно вызвать конечную точку /api/WeatherForecast
, чтобы получить данные прогноза погоды. Существует несколько обновлений HTML, CSS и TypeScript, все из которых выполняются в следующие файлы:
- app.component.css: обновите CSS, чтобы стилизовать таблицу.
- app.component.html: обновить HTML для отображения данных прогноза погоды в таблице.
-
app.component.ts: Обновить TypeScript, чтобы вызвать конечную точку
/api/WeatherForecast
и отобразить данные в таблице.
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 приложение работает
Чтобы визуализировать клиентское приложение Angular, перейдите к разделу Angular на панели управления .NET Aspire. На следующем рисунке показано клиентское приложение Angular:
Изучение клиента React
Приложение React не было написано с помощью шаблона и вместо этого было написано вручную. Полный исходный код можно найти в репозитории dotnet/aspire-samples. Некоторые ключевые моменты интереса находятся в файле 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;
Функция App
— это точка входа для клиентского приложения React. Он использует useState
и useEffect
хуки для управления состоянием данных прогноза погоды. API fetch
используется для выполнения HTTP-запроса к конечной точке /api/WeatherForecast
. Затем ответ преобразуется в JSON и задает состояние данных прогноза погоды.
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"],
},
],
},
};
};
Приведенный выше код определяет module.exports
следующим образом:
- Свойство
entry
установлено на src/index.js-файл. -
devServer
использует прокси-сервер для перенаправления запросов к сервису weatherapi, устанавливает порт в соответствии с переменной окруженияPORT
и разрешает всем хостам. - Результат
output
заключается в наличии папки dist с файлом bundle.js. -
plugins
установил файл src/index.html в качестве шаблона и открыл файл favicon.ico.
Последние обновления относятся к следующим файлам:
- App.css: обновить CSS для оформления таблицы.
-
App.js: обновить JavaScript, чтобы вызвать конечную точку
/api/WeatherForecast
и отобразить данные в таблице.
React приложение работает
Чтобы визуализировать клиентское приложение React, перейдите к конечной точке React на панели мониторинга .NET Aspire. На следующем рисунке показано клиентское приложение React:
Изучение клиента Vue
Существует несколько ключевых изменений исходного шаблона Vue. Основными обновлениями были добавление вызова fetch
в файле TheWelcome.vue для получения данных прогноза погоды из конечной точки /api/WeatherForecast
. Следующий фрагмент кода демонстрирует вызов 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>
Поскольку интеграция TheWelcome
находится в состоянии mounted
, она обращается к конечной точке /api/weatherforecast
для получения данных прогноза погоды. Затем ответ задается в качестве свойства данных forecasts
. Чтобы задать порт сервера, клиентское приложение Vue использует переменную среды PORT
. Это достигается путем обновления файла 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
}
}
}
})
Кроме того, конфигурация Vite указывает свойство server.proxy
для пересылки запросов в службу weatherapi. Это достигается с помощью переменной среды services__weatherapi__http__0
, которая устанавливается узлом приложения .NET.NET Aspire.
Окончательное обновление из шаблона внесено в файл TheWelcome.vue. Этот файл вызывает конечную точку /api/WeatherForecast
для получения данных прогноза погоды и отображения данных в таблице. Он включает обновления CSS, HTML и TypeScript.
Vue приложение работает
Чтобы визуализировать клиентское приложение Vue, перейдите к точке доступа vue на панели мониторинга .NET Aspire. На следующем рисунке показано клиентское приложение Vue:
Рекомендации по развертыванию
Пример исходного кода для этой статьи предназначен для локального запуска. Каждое клиентское приложение развертывается как образ контейнера. Для создания образа контейнера используется Dockerfile для каждого клиентского приложения. Каждая Dockerfile идентична и создается с использованием многоэтапной сборки для получения контейнерного образа, готового к эксплуатации в производственной среде.
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;"]
Клиентские приложения в настоящее время настроены для запуска в качестве истинных SPA-приложений и не настроены для работы в режиме отрисовки на стороне сервера (SSR). Они сидят за nginx, который используется для обслуживания статических файлов. Они используют файл default.conf.template для настройки nginx для прокси-запросов к клиентскому приложению.
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
Хотя в этой статье основное внимание уделяется клиентским приложениям, могут возникнуть сценарии, в которых необходимо разместить Node.js серверное приложение. Для размещения серверного приложения Node.js требуются те же семантические требования, как и для клиентского приложения SPA. Для хоста приложения .NET.NET Aspire требуется ссылка на пакет NuGet Aspire.Hosting.NodeJS, а также необходимо, чтобы код вызывал либо AddNodeApp
, либо AddNpmApp
. Эти API полезны для добавления существующих приложений JavaScript в контейнер приложений .NET.NET Aspire.
При настройке секретов и передаче переменных среды в приложения на основе JavaScript, будь то клиентские или серверные приложения, используйте параметры. Дополнительные сведения см. в разделе .NET.NET Aspire: внешние параметры — секреты.
Используйте SDK JavaScript OpenTelemetry
Чтобы экспортировать журналы OpenTelemetry, трассировки и метрики из серверного приложения Node.js, используйте JavaScript SDK OpenTelemetry.
Полный пример серверного приложения Node.js с использованием пакета SDK для JavaScript OpenTelemetry можно найти на странице Примеры кода: .NET AspireNode.js. Рассмотрим файл примера instrumentation.js, который демонстрирует, как настроить SDK JavaScript OpenTelemetry для экспорта журналов, трассировок и метрик.
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();
}
Подсказка
Чтобы настроить параметры OTEL CORS панели мониторинга .NET.NET Aspire, см. страницу .NET.NET Aspire параметров OTEL CORS панели мониторинга.
Сводка
Хотя существует несколько соображений, которые выходят за рамки этой статьи, вы узнали, как создавать проекты .NET Aspire, использующие Node.js и Node Package Manager (npm
). Вы также узнали, как использовать API AddNpmApp для размещения Node.js приложений и приложений, выполняемых из файла package.json соответственно. Наконец, вы узнали, как использовать интерфейс командной строки npm
для создания Angular, Reactи Vue клиентских приложений, а также настройки их работы на разных портах.
См. также
- Примеры кода : .NET Aspire с Angular, Reactи Vue
- Примеры кода : .NET AspireNode.js Приложение
.NET Aspire