{"id":358565,"date":"2024-05-21T00:14:37","date_gmt":"2024-05-21T00:14:37","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=358565"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=358565","title":{"rendered":"<span>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c .NET \u0438\u0437 Javascript (React) \u0432 2023 \u0433\u043e\u0434\u0443<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u041c\u043e\u0442\u0438\u0432\u0430\u0446\u0438\u044f<\/h2>\n<p>\u042f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 <a href=\"http:\/\/webtools.unmanagedvisio.com\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0435\u043a\u0442<\/a> \u0441 \u0434\u0438\u043a\u043e\u0432\u0438\u043d\u043d\u044b\u043c\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0434\u043b\u044f \u0434\u0438\u043d\u043e\u0437\u0430\u0432\u0440\u043e\u0432. \u041a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0442\u043a\u0440\u044b\u0442 \u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 <a href=\"https:\/\/github.com\/nbelyh\/VisioWebTools\" rel=\"noopener noreferrer nofollow\">GitHub<\/a>. \u041e\u043d \u0443\u043c\u0435\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u043e\u0444\u0438\u0441\u0430 (Microsoft Visio) \u0431\u0435\u0437 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043e\u043d\u043e\u0433\u043e (\u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043e\u0444\u0438\u0441\u043d\u044b\u043c\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 OpenXml, PdfSharp). \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432\u0435\u0434\u0435\u0442\u0441\u044f \u043d\u0430 .NET (C#). <\/p>\n<p>\u0420\u0430\u043d\u044c\u0448\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043b\u0430\u0441\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 (\u0442.\u0435. \u0444\u0430\u0439\u043b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u043b\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0447\u0435\u0440\u0435\u0437 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442). \u041e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u043e \u0438\u043c\u0435\u0435\u0442, \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0438:<\/p>\n<ul>\n<li>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u043f\u043e \u0441\u0435\u0442\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0432\u0440\u0435\u043c\u044f,<\/p>\n<\/li>\n<li>\n<p>\u0425\u043e\u0441\u0442\u0438\u043d\u0433 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0435\u0431\u0435\u0441\u043f\u043b\u0430\u0442\u0435\u043d, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e Azure Function \u0438\u043b\u0438 AWS Lambda,<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0431\u043e\u044f\u0442\u0441\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0432\u043e\u0438 \u0434\u0440\u0430\u0433\u043e\u0446\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0435 \u043f\u043e\u0439\u043c\u0438 \u043a\u0443\u0434\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0441\u0435\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 .NET \u0432 WebAssembly, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0432 .NET 7. \u0420\u0430\u043d\u044c\u0448\u0435 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u0442\u043e\u0436\u0435 \u0431\u044b\u043b\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u043d\u043e \u0442\u0430\u043c \u043e\u0442\u043e\u0432\u0441\u044e\u0434\u0443 \u0442\u043e\u0440\u0447\u0430\u043b\u0438 \u0443\u0448\u0438 Blazor, \u0430 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0432 \u043e\u0431\u0449\u0435\u043c \u043d\u0435 \u0442\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435, \u043d\u0430\u0437\u043e\u0432\u0438\u0442\u0435 \u043c\u0435\u043d\u044f \u0441\u0443\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u043c, \u043d\u043e \u043c\u043d\u0435 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043d\u0440\u0430\u0432\u044f\u0442\u0441\u044f &#171;\u0445\u0430\u0439\u043f\u043e\u0432\u044b\u0435&#187; \u0448\u0442\u0443\u043a\u0438. \u0421\u0435\u0439\u0447\u0430\u0441, \u0432 .NET 7 Blazor &#171;\u043e\u0442\u0446\u0435\u043f\u0438\u043b\u0438&#187;, \u0438 \u043e\u043d\u043e \u043d\u0430\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 WASM \u0431\u0435\u0437 \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u0445 \u0434\u043e\u0432\u0435\u0441\u043a\u043e\u0432.<\/p>\n<p>\u041f\u043e \u0441\u0443\u0442\u0438 \u0432\u0441\u0435 \u0447\u0442\u043e \u043c\u043d\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0437\u043e\u0432 API \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u043a\u043e\u0434\u0430 \u0438\u0437 WASM (\u0438\u0437 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 React). \u0414\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e \u0448\u0430\u0433\u0430\u043c.<\/p>\n<h2>\u041f\u0440\u043e\u0435\u043a\u0442 \u0434\u043b\u044f .NET<\/h2>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 <a href=\"https:\/\/learn.microsoft.com\/ru-ru\/aspnet\/core\/client-side\/dotnet-interop?view=aspnetcore-7.0\" rel=\"noopener noreferrer nofollow\">Microsoft<\/a> \u0438\u043b\u0438 \u0432\u043e\u0442 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432 <a href=\"https:\/\/www.meziantou.net\/using-dotnet-code-from-javascript-using-webassembly.htm\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435<\/a>. \u0417\u0434\u0435\u0441\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0432\u044b\u0436\u0438\u043c\u043a\u0430. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 (\u044f \u0441\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e Visual Studio Code \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430). \u0418\u0442\u0430\u043a,<\/p>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432 WASM. \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 workload. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 .NET 7 <\/p>\n<pre><code class=\"bash\">dotnet workload install wasm-tools<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442<\/p>\n<pre><code class=\"bash\">dotnet new console<\/code><\/pre>\n<p>\u041f\u043e\u0434\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043b \u0432 WASM. \u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u043e, \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c `wasm-experimetal`, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0431\u0430\u0432\u0438\u0442 \u0448\u0430\u0431\u043b\u043e\u043d \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041d\u043e \u043f\u043e \u0441\u0443\u0442\u0438, \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e \u0432 WASM \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u043a. \u0414\u0435\u0442\u0430\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/learn.microsoft.com\/ru-ru\/aspnet\/core\/client-side\/dotnet-interop?view=aspnetcore-7.0\" rel=\"noopener noreferrer nofollow\">\u043d\u0430 \u0441\u0430\u0439\u0442\u0435 Microsoft<\/a>. \u041a\u0440\u043e\u043c\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043d\u0443\u0436\u043d\u043e \u0435\u0449\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c (\u043c\u043e\u0436\u043d\u043e \u043f\u0443\u0441\u0442\u043e\u0439) \u0444\u0430\u0439\u043b &#171;main.js&#187; (\u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0442\u0443\u043b\u0441\u0435\u0442\u0430, \u0434\u0443\u043c\u0430\u044e \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043f\u043e\u0447\u0438\u043d\u044f\u0442 \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432 \u043d\u0435\u043c \u043e\u0442\u043f\u0430\u0434\u0435\u0442). \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043b \u043f\u0443\u0441\u0442\u043e\u0439 \u0444\u0430\u0439\u043b.<\/p>\n<pre><code class=\"xml\">&lt;Project Sdk=\"Microsoft.NET.Sdk\">    &lt;PropertyGroup>     &lt;OutputType>Exe&lt;\/OutputType>     &lt;TargetFramework>net7.0&lt;\/TargetFramework>      &lt;!-- \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u043e\u0442 \u044d\u0442\u043e\u0442 \u043a\u0443\u0441\u043e\u043a -->     &lt;RuntimeIdentifier>browser-wasm&lt;\/RuntimeIdentifier>     &lt;AllowUnsafeBlocks>true&lt;\/AllowUnsafeBlocks>     &lt;WasmMainJSPath>main.js&lt;\/WasmMainJSPath>     &lt;!-- \u043a\u043e\u043d\u0435\u0446 -->          &lt;ImplicitUsings>enable&lt;\/ImplicitUsings>     &lt;Nullable>enable&lt;\/Nullable>   &lt;\/PropertyGroup>  &lt;\/Project> <\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435, \u043f\u0438\u0448\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a\u043e\u0434 \u0432 Program.cs. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e \u0434\u043b\u0438\u043d\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0433\u043e &#171;\u0444\u0430\u043b\u0430&#187;), \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u0447\u0442\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0440\u0430\u0437\u0443\u043c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430. \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0447\u0442\u043e \u0442\u0430\u043c \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 <a href=\"https:\/\/github.com\/nbelyh\/VisioWebTools\" rel=\"noopener noreferrer nofollow\">GitHub <\/a>(\u0444\u0430\u0439\u043b\u044b \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f\/\u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e OpenXml \u0438 PdfSharp).<\/p>\n<pre><code class=\"cs\">using System.Runtime.InteropServices.JavaScript; using System.Threading.Tasks;  \/\/ \u0415\u0449\u0435 \u043e\u0434\u0438\u043d \"\u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\". \u0421\u043e\u0437\u0434\u0430\u0435\u0442 Main, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0443\u0436\u0435 \u043d\u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0442\u0443\u043b\u0441\u0435\u0442\u0430 return;  public partial class FileProcessor {     \/\/ \u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434     [JSExport]     internal static async Task&lt;int> ProcessFile(byte[] file)     { await Task.Delay(100); \/\/ \u044d\u043c\u0443\u043b\u0438\u0440\u0443\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443         return file.Length;     } }<\/code><\/pre>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c (\u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 publish, \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043c\u0435\u043d\u044c\u0448\u0435)<\/p>\n<pre><code class=\"bash\">dotnet publish -c Release<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u0430\u043f\u043a\u0443 \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 &#171;bin\/Release\/net7.0\/browser-wasm\/AppBundle&#187;. \u0412\u0441\u0435 DLL \u0444\u0430\u0439\u043b\u044b \u043b\u0435\u0436\u0430\u0442 \u0432 &#171;managed&#187;. \u0418\u0437 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0440\u0430 \u043d\u0430 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0435 \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b &#171;dotnet.js&#187;, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0438 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 javascript. \u041d\u043e \u043d\u0430 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0437\u0430\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u044f \u043f\u0430\u043f\u043a\u0430, \u0442.\u0435. \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \u0432 \u043d\u0435\u0439, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438. \u0420\u0430\u0437\u043c\u0435\u0440 \u043d\u0435 \u0442\u0430\u043a\u043e\u0439 \u0441\u0442\u0440\u0430\u0448\u043d\u044b\u0439, \u0434\u043b\u044f &#171;Hello World&#187; \u044d\u0442\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/11d\/b8d\/61b\/11db8d61b3353d0fde345d5ba7fff2fa.png\" alt=\"\u0444\u0430\u0439\u043b\u044b \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438\" title=\"\u0444\u0430\u0439\u043b\u044b \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438\" width=\"591\" height=\"481\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/11d\/b8d\/61b\/11db8d61b3353d0fde345d5ba7fff2fa.png\"\/><\/p>\n<div><figcaption>\u0444\u0430\u0439\u043b\u044b \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438<\/figcaption><\/div>\n<\/figure>\n<h2>\u0412\u0435\u0431-\u043f\u0440\u043e\u0435\u043a\u0442 (vite\/react)<\/h2>\n<p>\u0414\u043b\u044f VisioWebTools \u0443 \u043c\u0435\u043d\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/astro.build\/\" rel=\"noopener noreferrer nofollow\">Astro<\/a>, \u043d\u043e \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u044c\u0438, \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c \u0447\u0442\u043e \u0444\u0440\u043e\u043d\u0442 \u0443 \u043d\u0430\u0441 \u044d\u0442\u043e vite + react. \u041d\u0438\u0436\u0435 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0435\u043b\u0430\u044e \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 &#171;myapp&#187; \u0434\u043b\u044f \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"bash\">npm create vite@latest -- myapp --template react-ts cd myapp npm install npm run dev<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0434\u043e\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c <s>\u043e\u0441\u0442\u0430\u0432\u0448\u0443\u044e\u0441\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u043e\u0432\u044b<\/s> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 .NET. \u041a\u043e\u0434 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u0432\u044b\u0437\u044b\u0432\u0430\u044f .NET \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432\u044b\u0448\u0435. \u041d\u0430 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u043d\u043e\u043f\u043a\u0430 \u0432\u044b\u0431\u043e\u0440\u0430 \u0444\u0430\u0439\u043b\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f.<\/p>\n<pre><code class=\"typescript\">import { useDotNet } from '.\/useDotNet'  function App() {    const { dotnet, loading } = useDotNet('\/path\/to\/your\/AppBundle\/dotnet.js')    const fileSelected = async (e: any) => {      const file = e.target.files[0];     const data = new Uint8Array(await file.arrayBuffer());      const result = await dotnet.FileProcessor.ProcessFile(data)      alert(`Result: ${result}`);   }    return (     &lt;>       &lt;input disabled={loading} type=\"file\" onChange={fileSelected}>&lt;\/input>     &lt;\/>   ) }  export default App<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0445\u0443\u043a (&#171;\u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a&#187;), useDotNet (\u043a\u043e\u0434 \u043d\u0438\u0436\u0435). \u042f \u043d\u0435 \u0441\u043c\u043e\u0433 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0431\u0430\u043d\u0434\u043b\u0435\u0440 (\u043d\u0438 vite, \u043d\u0438 webpack) \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0438\u0437 AppBundle (\u0432\u043a\u043b\u044e\u0447\u0430\u044f DLL \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 &#171;\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435&#187; \u0444\u0430\u0439\u043b\u044b), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0440\u0430 \u0447\u0435\u0440\u0435\u0437 await import(url). \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 &#171;url&#187; \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430 &#171;dotnet.js&#187;, \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 .NET<\/p>\n<pre><code class=\"typescript\">import { useEffect, useRef, useState } from 'react';  export const useDotNet = (url: string) => {    const dotnetUrl = useRef('');   const [dotnet, setDotNet] = useState&lt;any>(null);   const [loading, setLoading] = useState(true);    const load = async (currentUrl: string): Promise&lt;any> => {      const module = await import(\/* @vite-ignore *\/ currentUrl);      const { getAssemblyExports, getConfig } = await module       .dotnet       .withDiagnosticTracing(false)       .create();      const config = getConfig();     const exports = await getAssemblyExports(config.mainAssemblyName);     return exports;   }    useEffect(() => {     if (dotnetUrl.current !== url) { \/\/ safeguard to prevent double-loading       setLoading(true);       dotnetUrl.current = url;       load(url)         .then(exports => setDotNet(exports))         .finally(() => setLoading(false))     }   }, [url]);   return { dotnet, loading }; }<\/code><\/pre>\n<h2>\u0421\u0431\u043e\u0440\u043a\u0430 (CI) \u0438 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 GitHub<\/h2>\n<p>\u041c\u043e\u044f \u0446\u0435\u043b\u044c \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043b\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u0443 VisioWebTools \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433, \u043d\u043e \u0432\u0441\u0435 \u0435\u0449\u0435 \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u043e\u0434 .NET.<\/p>\n<p>\u0414\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b <a href=\"https:\/\/github.com\/features\/actions\" rel=\"noopener noreferrer nofollow\">GitHub Actions<\/a>, \u0434\u043b\u044f \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0430 &#8212; <a href=\"https:\/\/pages.github.com\/\" rel=\"noopener noreferrer nofollow\">GitHub Pages<\/a>. \u0411\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e \u043d\u0430 \u0441\u0431\u043e\u0440\u043a\u0443 \u043e\u043d\u043e \u0434\u0430\u0435\u0442 2000 \u043c\u0438\u043d\u0443\u0442 \u0432 \u043c\u0435\u0441\u044f\u0446, \u0447\u0442\u043e \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u041b\u043e\u0433\u0438\u043a\u0430 \u0442\u0430\u043a\u0430\u044f: <\/p>\n<ul>\n<li>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 .NET, <\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u0430\u043f\u043a\u0438 &#171;AppBundle&#187; \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0432 \u043f\u0430\u043f\u043a\u0443 &#171;public&#187; \u043f\u0440\u043e\u0435\u043a\u0442\u0430 React\/Vite. \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0432 \u043a\u043e\u0440\u0435\u043d\u044c \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u0442.\u0435. \u0432 \u043a\u043e\u0440\u0435\u043d\u044c \u043f\u0430\u043f\u043a\u0438 &#171;dist&#187; \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435),<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c React \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 &#171;\u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d&#187;. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 URL, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 dotnet.js \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;\/AppBundle\/dotnet.js&#187;, \u0442.\u0435. \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043e\u0440\u0435\u043d\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>GitHub Pages \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0442\u0430\u043a\u043e\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e, \u0442.\u0435. \u043d\u0435 \u0440\u0443\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0444\u0430\u0439\u043b\u043e\u0432 &#171;.dll&#187; \u0438\u043b\u0438 &#171;.blat&#187; (IIS \u0440\u0443\u0433\u0430\u0435\u0442\u0441\u044f, \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0438\u0445 \u043d\u0430\u0434\u043e \u044f\u0432\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c). \u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f GitHub Actions \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/nbelyh\/VisioWebTools\/blob\/master\/.github\/workflows\/deploy.yml\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0422\u0435\u0441\u0442\u043e\u0432\u044b\u0439 (&#171;\u0438\u0433\u0440\u0443\u0448\u0435\u0447\u043d\u044b\u0439&#187;) \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 <a href=\"https:\/\/github.com\/nbelyh\/article-demo-dotnet-react-app\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>. \u041d\u0430 \u043c\u043e\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \ud83d\ude42 \u041d\u0430 \u0431\u0435\u0437\u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u043f\u0440\u0435\u0442\u0435\u043d\u0434\u0443\u044e, \u0431\u0443\u0434\u0443 \u0440\u0430\u0434 \u043b\u044e\u0431\u044b\u043c \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f\u043c \u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c. \u041d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441\u044b, \u0430\u0431\u044b \u0442\u0430\u043a\u0438\u0435 \u0431\u0443\u0434\u0443\u0442, \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0432 \u043c\u0435\u0440\u0443 \u0441\u0432\u043e\u0435\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f. \u0411\u0443\u0434\u0443 \u0440\u0430\u0434 \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0432\u0430\u043c \u043f\u043e\u043b\u0435\u0437\u043d\u0430.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/770058\/\"> https:\/\/habr.com\/ru\/articles\/770058\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u041c\u043e\u0442\u0438\u0432\u0430\u0446\u0438\u044f<\/h2>\n<p>\u042f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 <a href=\"http:\/\/webtools.unmanagedvisio.com\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0435\u043a\u0442<\/a> \u0441 \u0434\u0438\u043a\u043e\u0432\u0438\u043d\u043d\u044b\u043c\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0434\u043b\u044f \u0434\u0438\u043d\u043e\u0437\u0430\u0432\u0440\u043e\u0432. \u041a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0442\u043a\u0440\u044b\u0442 \u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 <a href=\"https:\/\/github.com\/nbelyh\/VisioWebTools\" rel=\"noopener noreferrer nofollow\">GitHub<\/a>. \u041e\u043d \u0443\u043c\u0435\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u044b \u043e\u0444\u0438\u0441\u0430 (Microsoft Visio) \u0431\u0435\u0437 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043e\u043d\u043e\u0433\u043e (\u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043e\u0444\u0438\u0441\u043d\u044b\u043c\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 OpenXml, PdfSharp). \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0432\u0435\u0434\u0435\u0442\u0441\u044f \u043d\u0430 .NET (C#). <\/p>\n<p>\u0420\u0430\u043d\u044c\u0448\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043b\u0430\u0441\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 (\u0442.\u0435. \u0444\u0430\u0439\u043b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u043b\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0447\u0435\u0440\u0435\u0437 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442). \u041e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u043e \u0438\u043c\u0435\u0435\u0442, \u043a\u0430\u043a \u043c\u0438\u043d\u0438\u043c\u0443\u043c, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043a\u0438:<\/p>\n<ul>\n<li>\n<p>\u041e\u0442\u043f\u0440\u0430\u0432\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u043f\u043e \u0441\u0435\u0442\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0432\u0440\u0435\u043c\u044f,<\/p>\n<\/li>\n<li>\n<p>\u0425\u043e\u0441\u0442\u0438\u043d\u0433 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0435\u0431\u0435\u0441\u043f\u043b\u0430\u0442\u0435\u043d, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e Azure Function \u0438\u043b\u0438 AWS Lambda,<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0431\u043e\u044f\u0442\u0441\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0432\u043e\u0438 \u0434\u0440\u0430\u0433\u043e\u0446\u0435\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0435 \u043f\u043e\u0439\u043c\u0438 \u043a\u0443\u0434\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0441\u0435\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 .NET \u0432 WebAssembly, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0432 .NET 7. \u0420\u0430\u043d\u044c\u0448\u0435 \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u0442\u043e\u0436\u0435 \u0431\u044b\u043b\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u043d\u043e \u0442\u0430\u043c \u043e\u0442\u043e\u0432\u0441\u044e\u0434\u0443 \u0442\u043e\u0440\u0447\u0430\u043b\u0438 \u0443\u0448\u0438 Blazor, \u0430 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0432 \u043e\u0431\u0449\u0435\u043c \u043d\u0435 \u0442\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435. \u041a \u0442\u043e\u043c\u0443 \u0436\u0435, \u043d\u0430\u0437\u043e\u0432\u0438\u0442\u0435 \u043c\u0435\u043d\u044f \u0441\u0443\u0431\u044a\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u043c, \u043d\u043e \u043c\u043d\u0435 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043d\u0440\u0430\u0432\u044f\u0442\u0441\u044f &#171;\u0445\u0430\u0439\u043f\u043e\u0432\u044b\u0435&#187; \u0448\u0442\u0443\u043a\u0438. \u0421\u0435\u0439\u0447\u0430\u0441, \u0432 .NET 7 Blazor &#171;\u043e\u0442\u0446\u0435\u043f\u0438\u043b\u0438&#187;, \u0438 \u043e\u043d\u043e \u043d\u0430\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 WASM \u0431\u0435\u0437 \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u0445 \u0434\u043e\u0432\u0435\u0441\u043a\u043e\u0432.<\/p>\n<p>\u041f\u043e \u0441\u0443\u0442\u0438 \u0432\u0441\u0435 \u0447\u0442\u043e \u043c\u043d\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u044b\u0437\u043e\u0432 API \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u043a\u043e\u0434\u0430 \u0438\u0437 WASM (\u0438\u0437 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 React). \u0414\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e \u0448\u0430\u0433\u0430\u043c.<\/p>\n<h2>\u041f\u0440\u043e\u0435\u043a\u0442 \u0434\u043b\u044f .NET<\/h2>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 <a href=\"https:\/\/learn.microsoft.com\/ru-ru\/aspnet\/core\/client-side\/dotnet-interop?view=aspnetcore-7.0\" rel=\"noopener noreferrer nofollow\">Microsoft<\/a> \u0438\u043b\u0438 \u0432\u043e\u0442 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432 <a href=\"https:\/\/www.meziantou.net\/using-dotnet-code-from-javascript-using-webassembly.htm\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435<\/a>. \u0417\u0434\u0435\u0441\u044c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0432\u044b\u0436\u0438\u043c\u043a\u0430. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 (\u044f \u0441\u0430\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e Visual Studio Code \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430). \u0418\u0442\u0430\u043a,<\/p>\n<p>\u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432 WASM. \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 workload. \u0420\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 .NET 7 <\/p>\n<pre><code class=\"bash\">dotnet workload install wasm-tools<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442<\/p>\n<pre><code class=\"bash\">dotnet new console<\/code><\/pre>\n<p>\u041f\u043e\u0434\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043b \u0432 WASM. \u0410\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u043e, \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c `wasm-experimetal`, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0431\u0430\u0432\u0438\u0442 \u0448\u0430\u0431\u043b\u043e\u043d \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041d\u043e \u043f\u043e \u0441\u0443\u0442\u0438, \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e \u0432 WASM \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u043a. \u0414\u0435\u0442\u0430\u043b\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c <a href=\"https:\/\/learn.microsoft.com\/ru-ru\/aspnet\/core\/client-side\/dotnet-interop?view=aspnetcore-7.0\" rel=\"noopener noreferrer nofollow\">\u043d\u0430 \u0441\u0430\u0439\u0442\u0435 Microsoft<\/a>. \u041a\u0440\u043e\u043c\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043d\u0443\u0436\u043d\u043e \u0435\u0449\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c (\u043c\u043e\u0436\u043d\u043e \u043f\u0443\u0441\u0442\u043e\u0439) \u0444\u0430\u0439\u043b &#171;main.js&#187; (\u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0442\u0443\u043b\u0441\u0435\u0442\u0430, \u0434\u0443\u043c\u0430\u044e \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043f\u043e\u0447\u0438\u043d\u044f\u0442 \u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u0432 \u043d\u0435\u043c \u043e\u0442\u043f\u0430\u0434\u0435\u0442). \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043b \u043f\u0443\u0441\u0442\u043e\u0439 \u0444\u0430\u0439\u043b.<\/p>\n<pre><code class=\"xml\">&lt;Project Sdk=\"Microsoft.NET.Sdk\">    &lt;PropertyGroup>     &lt;OutputType>Exe&lt;\/OutputType>     &lt;TargetFramework>net7.0&lt;\/TargetFramework>      &lt;!-- \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u043e\u0442 \u044d\u0442\u043e\u0442 \u043a\u0443\u0441\u043e\u043a -->     &lt;RuntimeIdentifier>browser-wasm&lt;\/RuntimeIdentifier>     &lt;AllowUnsafeBlocks>true&lt;\/AllowUnsafeBlocks>     &lt;WasmMainJSPath>main.js&lt;\/WasmMainJSPath>     &lt;!-- \u043a\u043e\u043d\u0435\u0446 -->          &lt;ImplicitUsings>enable&lt;\/ImplicitUsings>     &lt;Nullable>enable&lt;\/Nullable>   &lt;\/PropertyGroup>  &lt;\/Project> <\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435, \u043f\u0438\u0448\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a\u043e\u0434 \u0432 Program.cs. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e \u0434\u043b\u0438\u043d\u0443 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 (\u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0433\u043e &#171;\u0444\u0430\u043b\u0430&#187;), \u043f\u043e\u043d\u044f\u0442\u043d\u043e \u0447\u0442\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u0440\u0430\u0437\u0443\u043c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430. \u0412 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0447\u0442\u043e \u0442\u0430\u043c \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 <a href=\"https:\/\/github.com\/nbelyh\/VisioWebTools\" rel=\"noopener noreferrer nofollow\">GitHub <\/a>(\u0444\u0430\u0439\u043b\u044b \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f\/\u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e OpenXml \u0438 PdfSharp).<\/p>\n<pre><code class=\"cs\">using System.Runtime.InteropServices.JavaScript; using System.Threading.Tasks;  \/\/ \u0415\u0449\u0435 \u043e\u0434\u0438\u043d \"\u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\". \u0421\u043e\u0437\u0434\u0430\u0435\u0442 Main, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0443\u0436\u0435 \u043d\u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0442\u0443\u043b\u0441\u0435\u0442\u0430 return;  public partial class FileProcessor {     \/\/ \u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434     [JSExport]     internal static async Task&lt;int> ProcessFile(byte[] file)     { await Task.Delay(100); \/\/ \u044d\u043c\u0443\u043b\u0438\u0440\u0443\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443         return file.Length;     } }<\/code><\/pre>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c (\u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 publish, \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043c\u0435\u043d\u044c\u0448\u0435)<\/p>\n<pre><code class=\"bash\">dotnet publish -c Release<\/code><\/pre>\n<p>\u041d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u0430\u043f\u043a\u0443 \u0441 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 &#171;bin\/Release\/net7.0\/browser-wasm\/AppBundle&#187;. \u0412\u0441\u0435 DLL \u0444\u0430\u0439\u043b\u044b \u043b\u0435\u0436\u0430\u0442 \u0432 &#171;managed&#187;. \u0418\u0437 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0440\u0430 \u043d\u0430 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0435 \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b &#171;dotnet.js&#187;, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0438 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 javascript. \u041d\u043e \u043d\u0430 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0437\u0430\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u044f \u043f\u0430\u043f\u043a\u0430, \u0442.\u0435. \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \u0432 \u043d\u0435\u0439, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438. \u0420\u0430\u0437\u043c\u0435\u0440 \u043d\u0435 \u0442\u0430\u043a\u043e\u0439 \u0441\u0442\u0440\u0430\u0448\u043d\u044b\u0439, \u0434\u043b\u044f &#171;Hello World&#187; \u044d\u0442\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0444\u0430\u0439\u043b\u044b \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438<\/figcaption><\/div>\n<\/figure>\n<h2>\u0412\u0435\u0431-\u043f\u0440\u043e\u0435\u043a\u0442 (vite\/react)<\/h2>\n<p>\u0414\u043b\u044f VisioWebTools \u0443 \u043c\u0435\u043d\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/astro.build\/\" rel=\"noopener noreferrer nofollow\">Astro<\/a>, \u043d\u043e \u0434\u043b\u044f \u0441\u0442\u0430\u0442\u044c\u0438, \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b, \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c \u0447\u0442\u043e \u0444\u0440\u043e\u043d\u0442 \u0443 \u043d\u0430\u0441 \u044d\u0442\u043e vite + react. \u041d\u0438\u0436\u0435 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u0435\u043b\u0430\u044e \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 &#171;myapp&#187; \u0434\u043b\u044f \u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0430\u0446\u0438\u0438.<\/p>\n<pre><code class=\"bash\">npm create vite@latest -- myapp --template react-ts cd myapp npm install npm run dev<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0434\u043e\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c <s>\u043e\u0441\u0442\u0430\u0432\u0448\u0443\u044e\u0441\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u043e\u0432\u044b<\/s> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 .NET. \u041a\u043e\u0434 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0440\u0430\u0437\u043c\u0435\u0440 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u0432\u044b\u0437\u044b\u0432\u0430\u044f .NET \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438\u0437 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432\u044b\u0448\u0435. \u041d\u0430 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u043d\u043e\u043f\u043a\u0430 \u0432\u044b\u0431\u043e\u0440\u0430 \u0444\u0430\u0439\u043b\u0430 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f.<\/p>\n<pre><code class=\"typescript\">import { useDotNet } from '.\/useDotNet'  function App() {    const { dotnet, loading } = useDotNet('\/path\/to\/your\/AppBundle\/dotnet.js')    const fileSelected = async (e: any) => {      const file = e.target.files[0];     const data = new Uint8Array(await file.arrayBuffer());      const result = await dotnet.FileProcessor.ProcessFile(data)      alert(`Result: ${result}`);   }    return (     &lt;>       &lt;input disabled={loading} type=\"file\" onChange={fileSelected}>&lt;\/input>     &lt;\/>   ) }  export default App<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0445\u0443\u043a (&#171;\u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a&#187;), useDotNet (\u043a\u043e\u0434 \u043d\u0438\u0436\u0435). \u042f \u043d\u0435 \u0441\u043c\u043e\u0433 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0431\u0430\u043d\u0434\u043b\u0435\u0440 (\u043d\u0438 vite, \u043d\u0438 webpack) \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0438\u0437 AppBundle (\u0432\u043a\u043b\u044e\u0447\u0430\u044f DLL \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 &#171;\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435&#187; \u0444\u0430\u0439\u043b\u044b), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0440\u0430 \u0447\u0435\u0440\u0435\u0437 await import(url). \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 &#171;url&#187; \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430 &#171;dotnet.js&#187;, \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 .NET<\/p>\n<pre><code class=\"typescript\">import { useEffect, useRef, useState } from 'react';  export const useDotNet = (url: string) => {    const dotnetUrl = useRef('');   const [dotnet, setDotNet] = useState&lt;any>(null);   const [loading, setLoading] = useState(true);    const load = async (currentUrl: string): Promise&lt;any> => {      const module = await import(\/* @vite-ignore *\/ currentUrl);      const { getAssemblyExports, getConfig } = await module       .dotnet       .withDiagnosticTracing(false)       .create();      const config = getConfig();     const exports = await getAssemblyExports(config.mainAssemblyName);     return exports;   }    useEffect(() => {     if (dotnetUrl.current !== url) { \/\/ safeguard to prevent double-loading       setLoading(true);       dotnetUrl.current = url;       load(url)         .then(exports => setDotNet(exports))         .finally(() => setLoading(false))     }   }, [url]);   return { dotnet, loading }; }<\/code><\/pre>\n<h2>\u0421\u0431\u043e\u0440\u043a\u0430 (CI) \u0438 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 GitHub<\/h2>\n<p>\u041c\u043e\u044f \u0446\u0435\u043b\u044c \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043b\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u0443 VisioWebTools \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433, \u043d\u043e \u0432\u0441\u0435 \u0435\u0449\u0435 \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a\u043e\u0434 .NET.<\/p>\n<p>\u0414\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b <a href=\"https:\/\/github.com\/features\/actions\" rel=\"noopener noreferrer nofollow\">GitHub Actions<\/a>, \u0434\u043b\u044f \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0430 &#8212; <a href=\"https:\/\/pages.github.com\/\" rel=\"noopener noreferrer nofollow\">GitHub Pages<\/a>. \u0411\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e \u043d\u0430 \u0441\u0431\u043e\u0440\u043a\u0443 \u043e\u043d\u043e \u0434\u0430\u0435\u0442 2000 \u043c\u0438\u043d\u0443\u0442 \u0432 \u043c\u0435\u0441\u044f\u0446, \u0447\u0442\u043e \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. \u041b\u043e\u0433\u0438\u043a\u0430 \u0442\u0430\u043a\u0430\u044f: <\/p>\n<ul>\n<li>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442 .NET, <\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043f\u0430\u043f\u043a\u0438 &#171;AppBundle&#187; \u0432\u044b\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0432 \u043f\u0430\u043f\u043a\u0443 &#171;public&#187; \u043f\u0440\u043e\u0435\u043a\u0442\u0430 React\/Vite. \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0432 \u043a\u043e\u0440\u0435\u043d\u044c \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u0442.\u0435. \u0432 \u043a\u043e\u0440\u0435\u043d\u044c \u043f\u0430\u043f\u043a\u0438 &#171;dist&#187; \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435),<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c React \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 &#171;\u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d&#187;. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 URL, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 dotnet.js \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f &#171;\/AppBundle\/dotnet.js&#187;, \u0442.\u0435. \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043e\u0440\u0435\u043d\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ul>\n<p>GitHub Pages \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0442\u0430\u043a\u043e\u0435 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e, \u0442.\u0435. \u043d\u0435 \u0440\u0443\u0433\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0444\u0430\u0439\u043b\u043e\u0432 &#171;.dll&#187; \u0438\u043b\u0438 &#171;.blat&#187; (IIS \u0440\u0443\u0433\u0430\u0435\u0442\u0441\u044f, \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0438\u0445 \u043d\u0430\u0434\u043e \u044f\u0432\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c). \u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f GitHub Actions \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/nbelyh\/VisioWebTools\/blob\/master\/.github\/workflows\/deploy.yml\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0422\u0435\u0441\u0442\u043e\u0432\u044b\u0439 (&#171;\u0438\u0433\u0440\u0443\u0448\u0435\u0447\u043d\u044b\u0439&#187;) \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 <a href=\"https:\/\/github.com\/nbelyh\/article-demo-dotnet-react-app\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>. \u041d\u0430 \u043c\u043e\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \ud83d\ude42 \u041d\u0430 \u0431\u0435\u0437\u043e\u0448\u0438\u0431\u043e\u0447\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u043f\u0440\u0435\u0442\u0435\u043d\u0434\u0443\u044e, \u0431\u0443\u0434\u0443 \u0440\u0430\u0434 \u043b\u044e\u0431\u044b\u043c \u0437\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u044f\u043c \u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c. \u041d\u0430 \u0432\u043e\u043f\u0440\u043e\u0441\u044b, \u0430\u0431\u044b \u0442\u0430\u043a\u0438\u0435 \u0431\u0443\u0434\u0443\u0442, \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0432 \u043c\u0435\u0440\u0443 \u0441\u0432\u043e\u0435\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f. \u0411\u0443\u0434\u0443 \u0440\u0430\u0434 \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0432\u0430\u043c \u043f\u043e\u043b\u0435\u0437\u043d\u0430.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/770058\/\"> https:\/\/habr.com\/ru\/articles\/770058\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-358565","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/358565","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=358565"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/358565\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=358565"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=358565"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=358565"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}