{"id":468765,"date":"2025-07-26T21:00:11","date_gmt":"2025-07-26T21:00:11","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=468765"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=468765","title":{"rendered":"<span>\u0421\u0442\u0430\u0440\u0442\u0430\u043f \u0437\u0430 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435: AI-\u0430\u0433\u0435\u043d\u0442 \u0434\u043b\u044f \u0411\u0414, \u0447\u0430\u0441\u0442\u044c 1<\/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<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/f4\/5y\/in\/f45yincs4b-ca3ua5af-gvwyeaq.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/f4\/5y\/in\/f45yincs4b-ca3ua5af-gvwyeaq.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/f4\/5y\/in\/f45yincs4b-ca3ua5af-gvwyeaq.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041d\u0443 \u043a\u0442\u043e \u043d\u0435 \u043c\u0435\u0447\u0442\u0430\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u0442\u0430\u043f \u0437\u0430 \u043e\u0434\u043d\u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435?<\/p>\n<p>\u0414\u0430\u0432\u043d\u043e \u0445\u043e\u0442\u0435\u043b \u0440\u0430\u0437\u0432\u0435\u044f\u0442\u044c\u0441\u044f, \u0438 \u0447\u0443\u0442\u043a\u0430 \u043e\u0442\u0432\u043b\u0435\u0447\u044c\u0441\u044f \u043e\u0442 \u0440\u0443\u0442\u0438\u043d\u044b \u0438 \u0440\u0430\u0431\u043e\u0442\u044b.<br \/> \u0410 \u0435\u0449\u0451 \u0434\u0430\u0432\u043d\u043e \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c Tauri v2, \u0438 \u043d\u043e\u0432\u043e\u043c\u043e\u0434\u043d\u044b\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f AI-\u0430\u0433\u0435\u043d\u0442\u043e\u0432 (<a href=\"https:\/\/ai-sdk.dev\" rel=\"noopener noreferrer nofollow\">ai-sdk<\/a> \/ <a href=\"https:\/\/mastra.ai\" rel=\"noopener noreferrer nofollow\">mastra<\/a> \/ <a href=\"https:\/\/ts.llamaindex.ai\" rel=\"noopener noreferrer nofollow\">llamaindex<\/a>.<\/p>\n<p>\u0418\u0434\u0435\u044f \u043f\u0440\u043e\u0441\u0442\u0430\u044f: \u0434\u0435\u0441\u043a\u0442\u043e\u043f\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0432\u043d\u0443\u0442\u0440\u0438 \u0418\u0418-\u0430\u0433\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043a \u0411\u0414, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\/\u0432\u044c\u044e\u0448\u0435\u043a. \u0421\u043f\u0440\u0430\u0432\u0430 \u0441\u0430\u0439\u0434\u0431\u0430\u0440: \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0447\u0430\u0442\u0430 \u0441 \u0430\u0433\u0435\u043d\u0442\u043e\u043c, \u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e &#8212; \u0445\u043e\u043b\u0441\u0442, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0430\u0433\u0435\u043d\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0435\u0442 \u0447\u0442\u043e \u0445\u043e\u0447\u0435\u0442 \u0441\u0430\u043c. \u0410 \u0438\u043c\u0435\u043d\u043d\u043e &#8212; \u0432\u0438\u0434\u0436\u0435\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u043b\u0430\u044e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0411\u0414, \u0438 \u0432\u044b\u0432\u043e\u0434\u044f\u0442 \u0438\u0445 \u0432 \u043f\u0440\u0438\u044f\u0442\u043d\u043e\u043c \u0433\u043b\u0430\u0437\u0443 \u0432\u0438\u0434\u0435.<br \/> \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u043e\u0433\u043e \u0431\u0435\u043a\u0435\u043d\u0434\u0430, open-source, \u0434\u043e\u0441\u0442\u0443\u043f\u044b \u043a \u0411\u0414 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0432\u0441\u0451 \u0441\u0435\u043a\u044c\u044e\u0440\u043d\u043e.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0439, \u0442\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u044f \u0431\u0443\u0434\u0443 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438: <a href=\"https:\/\/github.com\/ElKornacio\/qyp-mini\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/ElKornacio\/qyp-mini<\/a><\/p>\n<p>\u0424\u043b\u043e\u0443 \u0442\u0430\u043a\u043e\u0439:<\/p>\n<ol>\n<li>\n<p>\u042f \u0433\u043e\u0432\u043e\u0440\u044e \u0430\u0433\u0435\u043d\u0442\u0443 &#171;\u0434\u043e\u0431\u0430\u0432\u044c \u043d\u0430 \u0434\u0435\u0448\u0431\u043e\u0440\u0434 \u043f\u043b\u0430\u0448\u043a\u0443 \u0441 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043d\u043e\u0432\u044b\u0445 \u044e\u0437\u0435\u0440\u043e\u0432 \u0437\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043c\u0435\u0441\u044f\u0446&#187;.<\/p>\n<\/li>\n<li>\n<p>\u041e\u043d, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0437\u043d\u0430\u043d\u0438\u044f \u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0411\u0414, \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a \u043d\u0435\u0439 \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043c\u043e\u0435\u0439 \u0411\u0414, SQL-\u0437\u0430\u043f\u0440\u043e\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u0443\u044e \u0438\u043d\u0444\u0443<\/p>\n<\/li>\n<li>\n<p>\u041e\u043d \u043f\u0438\u0448\u0435\u0442 React-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043d\u0430 Tailwind + shadcn\/ui, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0438\u043c\u043f\u0430\u0442\u0438\u0447\u043d\u043e\u0439 \u043f\u043b\u0430\u0448\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c, \u043f\u0440\u044f\u043c\u043e \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435, react-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043a\u043e\u043c\u043f\u043b\u0438\u0440\u0438\u0443\u0435\u0442\u0441\u044f (esbuild + postcss), \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0434\u0435\u0448\u0431\u043e\u0440\u0434<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043e\u043a (\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0438\u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f sql) &#8212; \u043e\u043d\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u043c \u043b\u0435\u0442\u044f\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0430\u0433\u0435\u043d\u0442\u0443, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0447\u0438\u043d\u0438\u043b.<\/p>\n<\/li>\n<\/ol>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u044f \u0445\u043e\u0447\u0443 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0431\u0443\u0434\u0435\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0430\u043c \u0418\u0418 \u0430\u0433\u0435\u043d\u0442, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0441\u0430\u043c \u0440\u0435\u0448\u0430\u043b, \u043a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e.<\/p>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043f\u043e\u0442\u044b\u043a\u0430\u0442\u044c runtime \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e tailwind (\u044d\u0442\u043e \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e, \u0442.\u043a. \u043f\u043e \u0434\u0435\u0444\u043e\u043b\u0442\u0443 tailwind \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 css-\u043a\u043b\u0430\u0441\u0441\u044b \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u0434\u0430), \u0435\u0449\u0451 runtime \u0441 esbuild \u043f\u043e\u0434 \u044d\u0442\u043e \u0432\u0441\u0451 \u0443\u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c, \u043d\u0443 \u0438 \u044f \u0434\u0430\u0432\u043d\u043e \u0445\u043e\u0442\u0435\u043b Tauri v2 \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c.<\/p>\n<p>\u0410 \u0435\u0449\u0451 \u043c\u043d\u0435 \u043d\u0430\u043a\u0438\u0434\u0430\u043b\u0438 <a href=\"https:\/\/t.me\/elkornacio\/320\" rel=\"noopener noreferrer nofollow\">\u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u044b \u0432 \u0442\u0435\u043b\u0435\u0433\u0435<\/a> \u043d\u043e\u0432\u043e\u043c\u043e\u0434\u043d\u044b\u0435 AI-agent \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u0434\u043b\u044f TypeScript, \u0442\u0430\u043a \u0447\u0442\u043e \u0438\u0445 \u0442\u043e\u0436\u0435 \u0445\u043e\u0447\u0443 \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c \u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c, \u0440\u0430\u043d\u044c\u0448\u0435 \u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0447\u0438\u0441\u0442\u043e\u043c LangChain \u043f\u0438\u0441\u0430\u043b.<\/p>\n<p>\u0412\u0441\u0435\u0433\u043e \u0431\u0443\u0434\u0435\u0442 5 \u0447\u0430\u0441\u0442\u0435\u0439:<\/p>\n<ol>\n<li>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c \u0441\u043a\u0435\u043b\u0435\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u044d\u0442\u0430 \u0447\u0430\u0441\u0442\u044c)<\/p>\n<\/li>\n<li>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c runtime-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e TSX-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c AI-\u0430\u0433\u0435\u043d\u0442\u0430 \u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c AI-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u0423\u0447\u0438\u043c \u0430\u0433\u0435\u043d\u0442\u0430 \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u0438 \u0434\u0435\u043b\u0430\u0442\u044c SQL-\u0437\u0430\u043f\u0440\u043e\u0441\u044b<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0441\u0451 \u0432 \u043a\u0443\u0447\u0443 \u0438 \u043f\u0440\u0438\u0447\u0451\u0441\u044b\u0432\u0430\u0435\u043c<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0435\u0445\u0430\u043b\u0438!<\/p>\n<h3>Tauri v2 &#8212; \u0434\u0435\u0441\u043a\u0442\u043e\u043f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/h3>\n<p>Tauri &#8212; \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0439 Electron \u043d\u0430 \u0441\u0442\u0435\u0440\u043e\u0438\u0434\u0430\u0445. \u0420\u0435\u0431\u044f\u0442\u0430 \u043f\u043e\u0447\u0435\u0441\u0430\u043b\u0438 \u0433\u043e\u043b\u043e\u0432\u0443 \u0438 \u0441\u043f\u0440\u043e\u0441\u0438\u043b\u0438 \u0441\u0435\u0431\u044f &#171;\u0437\u0430\u0447\u0435\u043c \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u0435\u0441\u044c Chromium-\u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u0435\u0441\u043b\u0438 \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044e\u0437\u0435\u0440\u0430 \u043d\u0430 \u043a\u043e\u043c\u043f\u0435 \u0438\u0442\u0430\u043a \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440? \u043f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c html\/css\/js-\u0431\u0430\u043d\u0434\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c WebView?&#187;<\/p>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 Tauri, \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0447\u0435\u0433\u043e \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0435\u0441\u0438\u0442 \u043d\u0435 400 \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442, \u0430 5, \u0438 \u043b\u0435\u0442\u0430\u0435\u0442 \u0432 \u043f\u043b\u0430\u043d\u0435 \u0431\u044b\u0441\u0442\u0440\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f (\u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c &#8212; \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0434\u043b\u044f WebView, \u0438 Rust \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e &#171;\u0431\u0435\u043a\u0435\u043d\u0434\u0430&#187; Tauri).<\/p>\n<p>\u0414\u0430\u0432\u043d\u043e \u0445\u043e\u0442\u0435\u043b \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0441 \u043d\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u043f\u043e\u0435\u0445\u0430\u043b\u0438:<\/p>\n<p>\u0422\u044b\u043a\u0430\u0435\u043c <a href=\"https:\/\/v2.tauri.app\/start\/\" rel=\"noopener noreferrer nofollow\">\u0441\u044e\u0434\u0430<\/a>, \u0438 \u0441\u043b\u0435\u043f\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u043c \u0433\u0430\u0439\u0434\u0443.<br \/> \u042f \u044e\u0437\u0430\u044e pnpm, \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u043e\u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0435:<\/p>\n<pre><code class=\"bash\">pnpm create tauri-app <\/code><\/pre>\n<p>\u0412\u0435\u0437\u0434\u0435 \u0432\u044b\u0431\u0438\u0440\u0430\u043b Typescript\/React.<\/p>\n<p>\u0417\u0430\u0432\u0435\u043b\u043e\u0441\u044c \u0441 \u043f\u043e\u043b-\u043f\u0438\u043d\u043a\u0430, \u0434\u0430\u043b\u0435\u0435:<\/p>\n<pre><code class=\"bash\">pnpm tauri dev <\/code><\/pre>\n<p>\u0438 \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430 \u0434\u043b\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u0442\u0435\u043a\u0430 Tauri \u043f\u043e \u0434\u0435\u0444\u043e\u043b\u0442\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 Vite. \u041c\u0435\u043d\u044f \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442, \u044f \u0442\u043e\u0436\u0435 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0435\u0433\u043e \u043d\u0430 \u0441\u0432\u043e\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435, \u0437\u0430\u0432\u043e\u0437\u0438\u043c <a href=\"https:\/\/tailwindcss.com\/docs\/installation\/using-vite\" rel=\"noopener noreferrer nofollow\">Tailwind v4<\/a> \u0438 <a href=\"https:\/\/ui.shadcn.com\/\" rel=\"noopener noreferrer nofollow\">shadcn\/ui<\/a>:<\/p>\n<pre><code>pnpm i --save-dev tailwindcss @tailwindcss\/vite <\/code><\/pre>\n<p>\u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d \u0432 <code>vite.config.ts<\/code>:<\/p>\n<pre><code class=\"typescript\">import { defineConfig } from 'vite' import tailwindcss from '@tailwindcss\/vite'  export default defineConfig({ plugins: [ \/\/ ... tailwindcss(), \/\/ ... ], }) <\/code><\/pre>\n<p>\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c Tailwind \u0432 css (<code>src\/index.css<\/code>):<\/p>\n<pre><code class=\"css\">@import \"tailwindcss\"; <\/code><\/pre>\n<p>\u0434\u0430\u043b\u0435\u0435, \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>shadcn\/ui<\/code> \u043f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0432 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u043a\u043d\u043e\u043f\u043a\u0443:<\/p>\n<pre><code class=\"bash\">pnpm dlx shadcn@latest add button <\/code><\/pre>\n<p>\u0412\u0443\u0430\u043b\u044f, \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u0435\u0442\u0430\u043f \u0433\u043e\u0442\u043e\u0432. \u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c\u0441\u044f \u0441\u043e \u0441\u0440\u0435\u0434\u043e\u0439 \u0434\u043b\u044f runtime-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438.<\/p>\n<h3>\u041a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c React-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435<\/h3>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0418\u0418 \u043d\u0430\u043c \u0432\u044b\u0434\u0430\u043b \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"typescript\">import { Button } from  '@\/components\/ui\/button';  export default function MyComponent() { return ( &lt;Button&gt;Click me!&lt;\/Button&gt; ); } <\/code><\/pre>\n<p>\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0432 \u044d\u0442\u043e\u043c \u043a\u043e\u0434\u0435, \u0431\u044b\u043b \u0432\u044b\u0432\u0435\u0434\u0435\u043d \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<br \/> \u041d\u0430\u043f\u043e\u043c\u043d\u044e, \u0440\u0435\u0447\u044c \u043e \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435: \u0442\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u0434 \u0432\u044b\u0448\u0435 \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0441\u0430\u043c\u0438\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e:<\/p>\n<ol>\n<li>\n<p>TSX: \u043d\u0430\u0434\u043e \u0442\u0440\u0430\u043d\u0441\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c jsx-\u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0432 <code>React.createElement<\/code>-\u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u044b<\/p>\n<\/li>\n<li>\n<p>TypeScript: \u043d\u0430\u0434\u043e \u0442\u0440\u0430\u043d\u0441\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 JavaScript<\/p>\n<\/li>\n<li>\n<p>Tailwind\/PostCSS: \u0441\u0431\u043e\u0440\u0449\u0438\u043a Tailwind \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u043d\u0430 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f tailwind-\u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043d\u0438\u0445 css-\u043a\u043e\u0434.<\/p>\n<\/li>\n<li>\n<p>\u0411\u0430\u043d\u0434\u043b\u0438\u043d\u0433: \u043d\u0430\u0434\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u044b \u0432 \u0435\u0434\u0438\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u0430 \u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043f\u043e\u0434\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u0441\u0430\u043c\u0438 (\u0442\u0438\u043f\u0430 \u0442\u0435\u0445 \u0436\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 <code>shadcn\/ui<\/code>) &#8212; \u0438\u0445 \u043d\u0430\u0434\u043e \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 (\u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 <code>require<\/code>?)<\/p>\n<\/li>\n<\/ol>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <code>esbuild<\/code> &#8212; TSX\/TypeScript\/\u0431\u0430\u043d\u0434\u043b\u0438\u043d\u0433 \u043e\u043d \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u0432\u043e\u0437\u044c\u043c\u0451\u0442 \u043d\u0430 \u0441\u0435\u0431\u044f. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u0443 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u044f \u0434\u043b\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u043e\u0433\u043e-\u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0430 &#8212; <a href=\"https:\/\/www.npmjs.com\/package\/esbuild-wasm\" rel=\"noopener noreferrer nofollow\"><code>esbuild-wasm<\/code><\/a>.<\/p>\n<p>\u0410 \u0432\u043e\u0442 \u0441 Tailwind\/PostCSS \u0432\u0441\u0451 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0421 \u043f\u043e\u043b-\u043f\u0438\u043d\u043a\u0430 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u0435 \u043e\u043d\u043e \u043d\u0435 \u0437\u0430\u0432\u043e\u0434\u0438\u0442\u0441\u044f. \u0415\u0441\u043b\u0438 \u0434\u043e\u043b\u0433\u043e \u043f\u0438\u043d\u0430\u0442\u044c, \u0442\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u043c\u043e\u0436\u043d\u043e, \u0443 \u0441\u0430\u043c\u043e\u0433\u043e Tailwind \u0435\u0441\u0442\u044c <a href=\"https:\/\/play.tailwindcss.com\/\" rel=\"noopener noreferrer nofollow\">play.tailwindcss.com<\/a>, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043a\u0430\u043a \u0440\u0430\u0437 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0435\u0439 Tailwind \u043f\u0440\u044f\u043c\u043e \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435. \u041d\u043e \u0432\u043e\u0442 \u0431\u0435\u0434\u0430 &#8212; \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u0440\u0430\u043d\u044c\u0448\u0435 \u0431\u044b\u043b open-source, \u0430 \u043f\u043e\u0442\u043e\u043c \u0440\u0435\u0431\u044f\u0442\u0430 \u043f\u0435\u0440\u0435\u0434\u0443\u043c\u0430\u043b\u0438.<br \/> \u041d\u043e, \u043a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u0432\u0441\u0451 \u043f\u043e\u043c\u043d\u0438\u0442, \u0438 \u043d\u0430\u0439\u0442\u0438 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 Tailwind Play <a href=\"https:\/\/codesandbox.io\/p\/devbox\/play-tailwindcss-com-jvnel\" rel=\"noopener noreferrer nofollow\">\u043d\u0435 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0442\u0440\u0443\u0434\u0430<\/a>.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0445\u043e\u0440\u043e\u0448\u0435\u043d\u044c\u043a\u043e \u0438\u0445 \u043f\u043e\u043a\u043e\u043f\u0430\u0442\u044c, \u0442\u043e \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0442\u0430\u043c \u043d\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 4 \u0432\u0435\u0440\u0441\u0438\u0438, \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043e\u043d\u043e \u043e\u0447\u0435\u043d\u044c \u0433\u0440\u044f\u0437\u043d\u043e &#8212; \u0441 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0430\u043c\u0438 \u0432\u0441\u044f\u043a\u0438\u0445 Node.js-\u043c\u043e\u0434\u0443\u043b\u0435\u0439, &#171;\u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439&#187; \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439, \u043a\u0443\u0447\u0435\u0439 \u0445\u0430\u043a\u043e\u0432 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435.<br \/> \u0418\u0434\u0442\u0438 \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u0443\u0442\u0438 \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u044f \u043f\u0440\u0438\u043d\u044f\u043b \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 TSX+Tailwind \u0440\u0430\u0439\u0442\u0430\u0439\u043c Node.js. \u041e\u0441\u0442\u0430\u0432\u0430\u043b\u0441\u044f \u0432\u043e\u043f\u0440\u043e\u0441 &#8212; \u043a\u0430\u043a \u0437\u0430\u0432\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u0432 Tauri.<\/p>\n<h3>\u0417\u0430\u0432\u043e\u0434\u0438\u043c Node.js \u0432 Tauri<\/h3>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u0432 Tauri \u0435\u0441\u0442\u044c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c sidecars, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0438 \u0432 \u0435\u0434\u0438\u043d\u044b\u0439 \u0431\u0430\u043d\u0434\u043b \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c.<br \/> \u0410 \u0434\u043b\u044f Node.js \u0435\u0441\u0442\u044c <code>pkg<\/code> &#8212; \u0443\u0442\u0438\u043b\u0438\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u043c\u0435\u0435\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0442\u044c Node.js \u0441\u043a\u0440\u0438\u043f\u0442-\u0431\u0430\u043d\u0434\u043b \u0432 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0439 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439.<br \/> \u0418 \u0443 Tauri \u0434\u0430\u0436\u0435 \u0435\u0441\u0442\u044c <a href=\"https:\/\/tauri.app\/learn\/sidecar-nodejs\/\" rel=\"noopener noreferrer nofollow\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0433\u0430\u0439\u0434<\/a> \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0437\u0430\u0432\u0435\u0441\u0442\u0438 Node.js-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u043a sidecar \u0434\u043b\u044f Tauri-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 Node.js \u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u043e\u0431\u044a\u0451\u043c\u0430\u043c\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u044f \u0445\u043e\u0447\u0443 \u0437\u0430\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u0434 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0438\u0439 stdin-stdout \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c JSON-\u043f\u0430\u043a\u0435\u0442\u044b \u0443\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0432 base64.<\/p>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e, Node.js \u043a\u043e\u0434 \u044f \u0442\u043e\u0436\u0435 \u0445\u043e\u0447\u0443 \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043a\u0430\u043a TypeScript, \u0438 \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0434 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u0432 <code>pkg<\/code>.<br \/> \u0414\u0435\u043b\u0430\u0435\u043c <code>pnpm init<\/code> \u0432 <code>src-node<\/code> \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438, \u0431\u0430\u0445\u0430\u0435\u043c <code>src-node\/src\/index.ts<\/code> \u0441 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u0439 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u043e\u0439, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432 <code>src-node\/package.json<\/code>:<\/p>\n<pre><code class=\"json\">{ ... \"scripts\": { \"build-code\": \"tsc\", \"build-binary\": \"pnpm run build-code &amp;&amp; pkg dist\/index.js --output qyp-mini-node-backend\", \"package-binary\": \"node scripts\/build.js qyp-mini-node-backend\", \"build\": \"pnpm run build-binary &amp;&amp; pnpm run package-binary\" }, \"devDependencies\": { \"@yao-pkg\/pkg\": \"^5.15.0\" }, \"bin\": { \"qyp-mini-node-backend\": \"dist\/index.js\" }, \"pkg\": { \"targets\": [ \"latest-macos\" ], \"scripts\": [ \"dist\/index.js\" ] }, ... } <\/code><\/pre>\n<p>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u044f \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u0437\u0430\u0432\u0451\u043b \u0442\u043e\u043b\u044c\u043a\u043e MacOS &#8212; \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u0432\u043e\u0434\u0438\u0442\u044c \u043f\u043e\u0442\u043e\u043c.<br \/> \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0432 <code>src-node\/scripts\/build.js<\/code> \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e <code>pkg<\/code> \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0430 \u0432 Tauri (\u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0443 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u043e\u0432 \u0431\u044b\u043b\u043e \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0435 \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430 &#8212; Tauri \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443, \u043f\u043e\u0434 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d):<\/p>\n<pre><code class=\"javascript\">import { execSync } from 'child_process'; import fs from 'fs';  const ext = process.platform === 'win32' ? '.exe' : '';  const appName = process.argv[2];  const rustInfo = execSync('rustc -vV'); const targetTriple = \/host: (\\S+)\/g.exec(rustInfo)[1]; if (!targetTriple) { console.error('Failed to determine platform target triple'); } fs.renameSync(`${appName}${ext}`, `..\/src-tauri\/binaries\/${appName}-${targetTriple}${ext}`);  <\/code><\/pre>\n<p>\u0418 \u0434\u043e\u043a\u0438\u043d\u0435\u043c \u044d\u0442\u043e \u0432\u0441\u0451 \u0432\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u0438\u0435 \u0432 <code>package.json<\/code> \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<pre><code class=\"json\">\"scripts\": { \"dev\": \"cd src-node &amp;&amp; pnpm run build &amp;&amp; cd .. &amp;&amp; vite\", \"build\": \"cd src-node &amp;&amp; pnpm run build &amp;&amp; cd .. &amp;&amp; tsc &amp;&amp; vite build\", \"preview\": \"vite preview\", \"tauri\": \"tauri\" }, <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>pnpm tauri dev<\/code> \u043e\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u043c \u0434\u0451\u0440\u043d\u0435\u0442 \u0441\u0431\u043e\u0440\u043a\u0443 \u0447\u0435\u0440\u0435\u0437 <code>pkg<\/code> \u0441\u0432\u0435\u0436\u0435\u0433\u043e Node.js \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0430, \u0438 \u0441\u0440\u0430\u0437\u0443 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0451 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 stdin, \u0434\u0430 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0432\u044b\u0437\u043e\u0432 sidecar, \u0432\u0430\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b <code>src-tauri\/capabilities\/default.json<\/code>:<\/p>\n<pre><code class=\"json\">{ ... \"permissions\": [ \"core:default\", \"opener:default\", { \"identifier\": \"shell:allow-spawn\", \"allow\": [ { \"name\": \"binaries\/qyp-mini-node-backend\", \"cmd\": \"binaries\/qyp-mini-node-backend\", \"args\": true, \/\/ \u043d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u043f\u0440\u043e sidecar: true, \u0438\u043d\u0430\u0447\u0435 \u0431\u0443\u0434\u0435\u0442 scoped command not found \"sidecar\": true } ] }, \"shell:allow-stdin-write\", \/\/ \u0430 \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u0432 stdin \"shell:default\" ] } <\/code><\/pre>\n<h3>\u041f\u0438\u043b\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0438\u0439 JSON-\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0434\u043b\u044f \u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 Node.js<\/h3>\n<p>\u041a\u0430\u043a \u044f \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b, \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c JSON \u0432 utf-8 \u0441\u0442\u0440\u043e\u0447\u043a\u0443, \u0430 \u0435\u0451 \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0432 base64. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u0430-\u0440\u0435\u043c\u0438\u043d\u0430\u0442\u043e\u0440\u0430 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0441\u0442\u0440\u043e\u043a\u0438 (\\n).<\/p>\n<p>\u041d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 Node.js:<\/p>\n<pre><code class=\"typescript\">\/\/ \u0427\u0438\u0442\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u0437 stdin const rl = createInterface({ input: process.stdin, output: process.stdout, terminal: false, });  rl.on('line', async line =&gt; { try { \/\/ \u0414\u0435\u043a\u043e\u0434\u0438\u0440\u0443\u0435\u043c base64 const jsonString = SmartBuffer.ofBase64String(line.trim()).toUTF8String(); \/\/ \u041f\u0430\u0440\u0441\u0438\u043c JSON const request = JSON.parse(jsonString);  \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441 const response = await processRequest(request);  \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u0442\u0432\u0435\u0442 sendResponse(response);  \/\/ \u0417\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 process.exit(0); } catch (error) { console.error('\u041e\u0448\u0438\u0431\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430:', error); sendResponse({ status: 'error', message: `\u041e\u0448\u0438\u0431\u043a\u0430 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430: ${error instanceof Error ? error.message : String(error)}`, }); process.exit(1); } }); <\/code><\/pre>\n<p>\u041d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430:<\/p>\n<pre><code class=\"typescript\">import { SmartBuffer } from '@tiny-utils\/bytes';  export class SidecarEncoder { static encodeRequest(request: SidecarRequest): string { const jsonString = JSON.stringify(request); const base64String = SmartBuffer.ofUTF8String(jsonString).toBase64String(); return base64String + '\\n'; }  static decodeResponse(base64Response: string): any { try { const jsonString = SmartBuffer.ofBase64String(base64Response.trim()).toUTF8String(); return JSON.parse(jsonString); } catch (error) { throw new Error(`\u041e\u0448\u0438\u0431\u043a\u0430 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u043e\u0442 sidecar: ${error}`); } } }  <\/code><\/pre>\n<p>\u0418 executor:<\/p>\n<pre><code class=\"typescript\">import { Command, TerminatedPayload } from '@tauri-apps\/plugin-shell'; import { SidecarEncoder, SidecarRequest, SidecarResponse } from '.\/SidecarEncoder';  export class SidecarExecutor { private static readonly SIDECAR_NAME = 'binaries\/qyp-mini-node-backend';  static async execute&lt;T extends SidecarResponse&gt;(params: SidecarExecutionParams): Promise&lt;T&gt; { const command = Command.sidecar(this.SIDECAR_NAME, params.args);  let stdout = ''; let stderr = '';  command.stdout.on('data', data =&gt; { stdout += data; }); command.stderr.on('data', data =&gt; { stderr += data; });  const child = await command.spawn();  const encodedRequest = SidecarEncoder.encodeRequest(params.request);  const output = await new Promise&lt;TerminatedPayload&gt;(resolve =&gt; { command.on('close', out =&gt; resolve(out));  \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 child.write(encodedRequest); });  if (output.code !== 0) { throw new Error(`Sidecar \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f \u0441 \u043a\u043e\u0434\u043e\u043c: ${output.code}. Stderr: ${stderr}`); }  return SidecarEncoder.decodeResponse(stdout); } } <\/code><\/pre>\n<p>\u0412\u0443\u0430\u043b\u044f, \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0433\u043e\u0442\u043e\u0432. \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c (<code>pnpm tauri dev<\/code>, \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043c, \u0438 \u0440\u0430\u0434\u0443\u0435\u043c\u0441\u044f \u0447\u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442).<\/p>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u042d\u0442\u043e \u043f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u043b\u0438 \u0441\u043a\u0435\u043b\u0435\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412 \u0438\u0442\u043e\u0433\u0435, \u043d\u0430 \u0431\u0430\u0437\u0435 \u0441\u0442\u0435\u043a\u0430:<\/p>\n<ul>\n<li>\n<p>TypeScript<\/p>\n<\/li>\n<li>\n<p>Tauri v2<\/p>\n<\/li>\n<li>\n<p>Tailwind v4 \/ shadcn\/ui<\/p>\n<\/li>\n<li>\n<p>Vite 6 \/ React 18<\/p>\n<\/li>\n<li>\n<p>Node.js + pkg<\/p>\n<\/li>\n<\/ul>\n<p>\u0423 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c desktop-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0441 \u0444\u0440\u043e\u043d\u0442\u043e\u043c \u043d\u0430 React, Node.js \u043c\u0438\u043d\u0438-\u0431\u0435\u043a\u043e\u043c \u0434\u043b\u044f \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 TSX-\u043a\u043e\u0434\u0430 \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0435\u0441\u0438\u0442 \u0432 5 \u0440\u0430\u0437 \u043c\u0435\u043d\u044c\u0448\u0435 Electron \u0441\u0431\u043e\u0440\u043a\u0438, \u0438 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0448\u0443\u0441\u0442\u0440\u0435\u0435.<br \/> \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438: <a href=\"https:\/\/github.com\/ElKornacio\/qyp-mini\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/ElKornacio\/qyp-mini<\/a><\/p>\n<p>\u0411\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u044f \u043f\u0438\u0448\u0443 \u0443 \u0441\u0435\u0431\u044f \u0432 <a href=\"https:\/\/t.me\/+9b7Mk_JaZnI1ODIy\" rel=\"noopener noreferrer nofollow\">\u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c-\u043a\u0430\u043d\u0430\u043b\u0435<\/a> (\u0434\u0430 \u0438 \u0432 \u0446\u0435\u043b\u043e\u043c \u044f \u0442\u0430\u043c \u043c\u043d\u043e\u0433\u043e \u0432\u0441\u0435\u0433\u043e \u043f\u0438\u0448\u0443 \u043f\u0440\u043e \u0418\u0418, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0441 \u0418\u0418, \u0441\u0442\u0430\u0440\u0442\u0430\u043f\u044b \u0438 \u043f\u0440\u043e\u0447\u0435\u0435).<\/p>\n<p>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0437\u0430\u0432\u0442\u0440\u0430!<\/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\/931390\/\"> https:\/\/habr.com\/ru\/articles\/931390\/<\/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<figure class=\"\"><\/figure>\n<p>\u041d\u0443 \u043a\u0442\u043e \u043d\u0435 \u043c\u0435\u0447\u0442\u0430\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u0442\u0430\u043f \u0437\u0430 \u043e\u0434\u043d\u0438 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435?<\/p>\n<p>\u0414\u0430\u0432\u043d\u043e \u0445\u043e\u0442\u0435\u043b \u0440\u0430\u0437\u0432\u0435\u044f\u0442\u044c\u0441\u044f, \u0438 \u0447\u0443\u0442\u043a\u0430 \u043e\u0442\u0432\u043b\u0435\u0447\u044c\u0441\u044f \u043e\u0442 \u0440\u0443\u0442\u0438\u043d\u044b \u0438 \u0440\u0430\u0431\u043e\u0442\u044b.<br \/> \u0410 \u0435\u0449\u0451 \u0434\u0430\u0432\u043d\u043e \u0445\u043e\u0442\u0435\u043b \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c Tauri v2, \u0438 \u043d\u043e\u0432\u043e\u043c\u043e\u0434\u043d\u044b\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f AI-\u0430\u0433\u0435\u043d\u0442\u043e\u0432 (<a href=\"https:\/\/ai-sdk.dev\" rel=\"noopener noreferrer nofollow\">ai-sdk<\/a> \/ <a href=\"https:\/\/mastra.ai\" rel=\"noopener noreferrer nofollow\">mastra<\/a> \/ <a href=\"https:\/\/ts.llamaindex.ai\" rel=\"noopener noreferrer nofollow\">llamaindex<\/a>.<\/p>\n<p>\u0418\u0434\u0435\u044f \u043f\u0440\u043e\u0441\u0442\u0430\u044f: \u0434\u0435\u0441\u043a\u0442\u043e\u043f\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0432\u043d\u0443\u0442\u0440\u0438 \u0418\u0418-\u0430\u0433\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043a \u0411\u0414, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\/\u0432\u044c\u044e\u0448\u0435\u043a. \u0421\u043f\u0440\u0430\u0432\u0430 \u0441\u0430\u0439\u0434\u0431\u0430\u0440: \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0447\u0430\u0442\u0430 \u0441 \u0430\u0433\u0435\u043d\u0442\u043e\u043c, \u0430 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e &#8212; \u0445\u043e\u043b\u0441\u0442, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0430\u0433\u0435\u043d\u0442 \u0440\u0430\u0437\u043c\u0435\u0449\u0430\u0435\u0442 \u0447\u0442\u043e \u0445\u043e\u0447\u0435\u0442 \u0441\u0430\u043c. \u0410 \u0438\u043c\u0435\u043d\u043d\u043e &#8212; \u0432\u0438\u0434\u0436\u0435\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u043b\u0430\u044e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0411\u0414, \u0438 \u0432\u044b\u0432\u043e\u0434\u044f\u0442 \u0438\u0445 \u0432 \u043f\u0440\u0438\u044f\u0442\u043d\u043e\u043c \u0433\u043b\u0430\u0437\u0443 \u0432\u0438\u0434\u0435.<br \/> \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u0443\u0434\u0430\u043b\u0451\u043d\u043d\u043e\u0433\u043e \u0431\u0435\u043a\u0435\u043d\u0434\u0430, open-source, \u0434\u043e\u0441\u0442\u0443\u043f\u044b \u043a \u0411\u0414 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e, \u0432\u0441\u0451 \u0441\u0435\u043a\u044c\u044e\u0440\u043d\u043e.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0439, \u0442\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u044f \u0431\u0443\u0434\u0443 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438: <a href=\"https:\/\/github.com\/ElKornacio\/qyp-mini\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/ElKornacio\/qyp-mini<\/a><\/p>\n<p>\u0424\u043b\u043e\u0443 \u0442\u0430\u043a\u043e\u0439:<\/p>\n<ol>\n<li>\n<p>\u042f \u0433\u043e\u0432\u043e\u0440\u044e \u0430\u0433\u0435\u043d\u0442\u0443 &#171;\u0434\u043e\u0431\u0430\u0432\u044c \u043d\u0430 \u0434\u0435\u0448\u0431\u043e\u0440\u0434 \u043f\u043b\u0430\u0448\u043a\u0443 \u0441 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043d\u043e\u0432\u044b\u0445 \u044e\u0437\u0435\u0440\u043e\u0432 \u0437\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043c\u0435\u0441\u044f\u0446&#187;.<\/p>\n<\/li>\n<li>\n<p>\u041e\u043d, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0437\u043d\u0430\u043d\u0438\u044f \u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u0411\u0414, \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043a \u043d\u0435\u0439 \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043c\u043e\u0435\u0439 \u0411\u0414, SQL-\u0437\u0430\u043f\u0440\u043e\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u0443\u044e \u0438\u043d\u0444\u0443<\/p>\n<\/li>\n<li>\n<p>\u041e\u043d \u043f\u0438\u0448\u0435\u0442 React-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043d\u0430 Tailwind + shadcn\/ui, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0438\u043c\u043f\u0430\u0442\u0438\u0447\u043d\u043e\u0439 \u043f\u043b\u0430\u0448\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c, \u043f\u0440\u044f\u043c\u043e \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435, react-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043a\u043e\u043c\u043f\u043b\u0438\u0440\u0438\u0443\u0435\u0442\u0441\u044f (esbuild + postcss), \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0434\u0435\u0448\u0431\u043e\u0440\u0434<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0448\u0438\u0431\u043e\u043a (\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0438\u043b\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f sql) &#8212; \u043e\u043d\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u043c \u043b\u0435\u0442\u044f\u0442 \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0430\u0433\u0435\u043d\u0442\u0443, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0447\u0438\u043d\u0438\u043b.<\/p>\n<\/li>\n<\/ol>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u044f \u0445\u043e\u0447\u0443 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0431\u0443\u0434\u0435\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0430\u043c \u0418\u0418 \u0430\u0433\u0435\u043d\u0442, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0441\u0430\u043c \u0440\u0435\u0448\u0430\u043b, \u043a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e.<\/p>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043f\u043e\u0442\u044b\u043a\u0430\u0442\u044c runtime \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e tailwind (\u044d\u0442\u043e \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e, \u0442.\u043a. \u043f\u043e \u0434\u0435\u0444\u043e\u043b\u0442\u0443 tailwind \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 css-\u043a\u043b\u0430\u0441\u0441\u044b \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u0434\u0430), \u0435\u0449\u0451 runtime \u0441 esbuild \u043f\u043e\u0434 \u044d\u0442\u043e \u0432\u0441\u0451 \u0443\u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c, \u043d\u0443 \u0438 \u044f \u0434\u0430\u0432\u043d\u043e \u0445\u043e\u0442\u0435\u043b Tauri v2 \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c.<\/p>\n<p>\u0410 \u0435\u0449\u0451 \u043c\u043d\u0435 \u043d\u0430\u043a\u0438\u0434\u0430\u043b\u0438 <a href=\"https:\/\/t.me\/elkornacio\/320\" rel=\"noopener noreferrer nofollow\">\u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u044b \u0432 \u0442\u0435\u043b\u0435\u0433\u0435<\/a> \u043d\u043e\u0432\u043e\u043c\u043e\u0434\u043d\u044b\u0435 AI-agent \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u0434\u043b\u044f TypeScript, \u0442\u0430\u043a \u0447\u0442\u043e \u0438\u0445 \u0442\u043e\u0436\u0435 \u0445\u043e\u0447\u0443 \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c \u0438 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c, \u0440\u0430\u043d\u044c\u0448\u0435 \u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0447\u0438\u0441\u0442\u043e\u043c LangChain \u043f\u0438\u0441\u0430\u043b.<\/p>\n<p>\u0412\u0441\u0435\u0433\u043e \u0431\u0443\u0434\u0435\u0442 5 \u0447\u0430\u0441\u0442\u0435\u0439:<\/p>\n<ol>\n<li>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c \u0441\u043a\u0435\u043b\u0435\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f (\u044d\u0442\u0430 \u0447\u0430\u0441\u0442\u044c)<\/p>\n<\/li>\n<li>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c runtime-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044e TSX-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u0414\u0435\u043b\u0430\u0435\u043c AI-\u0430\u0433\u0435\u043d\u0442\u0430 \u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u043c AI-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u0423\u0447\u0438\u043c \u0430\u0433\u0435\u043d\u0442\u0430 \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u0438 \u0434\u0435\u043b\u0430\u0442\u044c SQL-\u0437\u0430\u043f\u0440\u043e\u0441\u044b<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0441\u0451 \u0432 \u043a\u0443\u0447\u0443 \u0438 \u043f\u0440\u0438\u0447\u0451\u0441\u044b\u0432\u0430\u0435\u043c<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0435\u0445\u0430\u043b\u0438!<\/p>\n<h3>Tauri v2 &#8212; \u0434\u0435\u0441\u043a\u0442\u043e\u043f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/h3>\n<p>Tauri &#8212; \u044d\u0442\u043e \u0442\u0430\u043a\u043e\u0439 Electron \u043d\u0430 \u0441\u0442\u0435\u0440\u043e\u0438\u0434\u0430\u0445. \u0420\u0435\u0431\u044f\u0442\u0430 \u043f\u043e\u0447\u0435\u0441\u0430\u043b\u0438 \u0433\u043e\u043b\u043e\u0432\u0443 \u0438 \u0441\u043f\u0440\u043e\u0441\u0438\u043b\u0438 \u0441\u0435\u0431\u044f &#171;\u0437\u0430\u0447\u0435\u043c \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u0435\u0441\u044c Chromium-\u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u0435\u0441\u043b\u0438 \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044e\u0437\u0435\u0440\u0430 \u043d\u0430 \u043a\u043e\u043c\u043f\u0435 \u0438\u0442\u0430\u043a \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440? \u043f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c html\/css\/js-\u0431\u0430\u043d\u0434\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c WebView?&#187;<\/p>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 Tauri, \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0447\u0435\u0433\u043e \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0432\u0435\u0441\u0438\u0442 \u043d\u0435 400 \u043c\u0435\u0433\u0430\u0431\u0430\u0439\u0442, \u0430 5, \u0438 \u043b\u0435\u0442\u0430\u0435\u0442 \u0432 \u043f\u043b\u0430\u043d\u0435 \u0431\u044b\u0441\u0442\u0440\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f (\u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c &#8212; \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0434\u043b\u044f WebView, \u0438 Rust \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e &#171;\u0431\u0435\u043a\u0435\u043d\u0434\u0430&#187; Tauri).<\/p>\n<p>\u0414\u0430\u0432\u043d\u043e \u0445\u043e\u0442\u0435\u043b \u0447\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0441 \u043d\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u043f\u043e\u0435\u0445\u0430\u043b\u0438:<\/p>\n<p>\u0422\u044b\u043a\u0430\u0435\u043c <a href=\"https:\/\/v2.tauri.app\/start\/\" rel=\"noopener noreferrer nofollow\">\u0441\u044e\u0434\u0430<\/a>, \u0438 \u0441\u043b\u0435\u043f\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u043c \u0433\u0430\u0439\u0434\u0443.<br \/> \u042f \u044e\u0437\u0430\u044e pnpm, \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u043e\u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0435:<\/p>\n<pre><code class=\"bash\">pnpm create tauri-app <\/code><\/pre>\n<p>\u0412\u0435\u0437\u0434\u0435 \u0432\u044b\u0431\u0438\u0440\u0430\u043b Typescript\/React.<\/p>\n<p>\u0417\u0430\u0432\u0435\u043b\u043e\u0441\u044c \u0441 \u043f\u043e\u043b-\u043f\u0438\u043d\u043a\u0430, \u0434\u0430\u043b\u0435\u0435:<\/p>\n<pre><code class=\"bash\">pnpm tauri dev <\/code><\/pre>\n<p>\u0438 \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430 \u0434\u043b\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u0442\u0435\u043a\u0430 Tauri \u043f\u043e \u0434\u0435\u0444\u043e\u043b\u0442\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 Vite. \u041c\u0435\u043d\u044f \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442, \u044f \u0442\u043e\u0436\u0435 \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0435\u0433\u043e \u043d\u0430 \u0441\u0432\u043e\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435, \u0437\u0430\u0432\u043e\u0437\u0438\u043c <a href=\"https:\/\/tailwindcss.com\/docs\/installation\/using-vite\" rel=\"noopener noreferrer nofollow\">Tailwind v4<\/a> \u0438 <a href=\"https:\/\/ui.shadcn.com\/\" rel=\"noopener noreferrer nofollow\">shadcn\/ui<\/a>:<\/p>\n<pre><code>pnpm i --save-dev tailwindcss @tailwindcss\/vite <\/code><\/pre>\n<p>\u043d\u0435 \u0437\u0430\u0431\u044b\u0432\u0430\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d \u0432 <code>vite.config.ts<\/code>:<\/p>\n<pre><code class=\"typescript\">import { defineConfig } from 'vite' import tailwindcss from '@tailwindcss\/vite'  export default defineConfig({ plugins: [ \/\/ ... tailwindcss(), \/\/ ... ], }) <\/code><\/pre>\n<p>\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c Tailwind \u0432 css (<code>src\/index.css<\/code>):<\/p>\n<pre><code class=\"css\">@import \"tailwindcss\"; <\/code><\/pre>\n<p>\u0434\u0430\u043b\u0435\u0435, \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>shadcn\/ui<\/code> \u043f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0432 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u043a\u043d\u043e\u043f\u043a\u0443:<\/p>\n<pre><code class=\"bash\">pnpm dlx shadcn@latest add button <\/code><\/pre>\n<p>\u0412\u0443\u0430\u043b\u044f, \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0441\u0435\u0442\u0430\u043f \u0433\u043e\u0442\u043e\u0432. \u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c\u0441\u044f \u0441\u043e \u0441\u0440\u0435\u0434\u043e\u0439 \u0434\u043b\u044f runtime-\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438.<\/p>\n<h3>\u041a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c React-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435<\/h3>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0418\u0418 \u043d\u0430\u043c \u0432\u044b\u0434\u0430\u043b \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"typescript\">import { Button } from  '@\/components\/ui\/button';  export default function MyComponent() { return ( &lt;Button&gt;Click me!&lt;\/Button&gt; ); } <\/code><\/pre>\n<p>\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0432 \u044d\u0442\u043e\u043c \u043a\u043e\u0434\u0435, \u0431\u044b\u043b \u0432\u044b\u0432\u0435\u0434\u0435\u043d \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<br \/> \u041d\u0430\u043f\u043e\u043c\u043d\u044e, \u0440\u0435\u0447\u044c \u043e \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435: \u0442\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u0434 \u0432\u044b\u0448\u0435 \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0441\u0430\u043c\u0438\u043c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e:<\/p>\n<ol>\n<li>\n<p>TSX: \u043d\u0430\u0434\u043e \u0442\u0440\u0430\u043d\u0441\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c jsx-\u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0432 <code>React.createElement<\/code>-\u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u044b<\/p>\n<\/li>\n<li>\n<p>TypeScript: \u043d\u0430\u0434\u043e \u0442\u0440\u0430\u043d\u0441\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 JavaScript<\/p>\n<\/li>\n<li>\n<p>Tailwind\/PostCSS: \u0441\u0431\u043e\u0440\u0449\u0438\u043a Tailwind \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u043d\u0430 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f tailwind-\u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043d\u0438\u0445 css-\u043a\u043e\u0434.<\/p>\n<\/li>\n<li>\n<p>\u0411\u0430\u043d\u0434\u043b\u0438\u043d\u0433: \u043d\u0430\u0434\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u044b \u0432 \u0435\u0434\u0438\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u0430 \u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043f\u043e\u0434\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u0441\u0430\u043c\u0438 (\u0442\u0438\u043f\u0430 \u0442\u0435\u0445 \u0436\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 <code>shadcn\/ui<\/code>) &#8212; \u0438\u0445 \u043d\u0430\u0434\u043e \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u043f\u0440\u043e\u0431\u0440\u043e\u0441\u0438\u0442\u044c \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 (\u0438\u043c\u043f\u043b\u0435\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 <code>require<\/code>?)<\/p>\n<\/li>\n<\/ol>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <code>esbuild<\/code> &#8212; TSX\/TypeScript\/\u0431\u0430\u043d\u0434\u043b\u0438\u043d\u0433 \u043e\u043d \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e \u0432\u043e\u0437\u044c\u043c\u0451\u0442 \u043d\u0430 \u0441\u0435\u0431\u044f. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u0443 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u044f \u0434\u043b\u044f \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u043e\u0433\u043e-\u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0430 &#8212; <a href=\"https:\/\/www.npmjs.com\/package\/esbuild-wasm\" rel=\"noopener noreferrer nofollow\"><code>esbuild-wasm<\/code><\/a>.<\/p>\n<p>\u0410 \u0432\u043e\u0442 \u0441 Tailwind\/PostCSS \u0432\u0441\u0451 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0421 \u043f\u043e\u043b-\u043f\u0438\u043d\u043a\u0430 \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043d\u043e\u0439 \u0441\u0440\u0435\u0434\u0435 \u043e\u043d\u043e \u043d\u0435 \u0437\u0430\u0432\u043e\u0434\u0438\u0442\u0441\u044f. \u0415\u0441\u043b\u0438 \u0434\u043e\u043b\u0433\u043e \u043f\u0438\u043d\u0430\u0442\u044c, \u0442\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u043c\u043e\u0436\u043d\u043e, \u0443 \u0441\u0430\u043c\u043e\u0433\u043e Tailwind \u0435\u0441\u0442\u044c <a href=\"https:\/\/play.tailwindcss.com\/\" rel=\"noopener noreferrer nofollow\">play.tailwindcss.com<\/a>, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043a\u0430\u043a \u0440\u0430\u0437 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0435\u0439 Tailwind \u043f\u0440\u044f\u043c\u043e \u0432 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435. \u041d\u043e \u0432\u043e\u0442 \u0431\u0435\u0434\u0430 &#8212; \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u0440\u0430\u043d\u044c\u0448\u0435 \u0431\u044b\u043b open-source, \u0430 \u043f\u043e\u0442\u043e\u043c \u0440\u0435\u0431\u044f\u0442\u0430 \u043f\u0435\u0440\u0435\u0434\u0443\u043c\u0430\u043b\u0438.<br \/> \u041d\u043e, \u043a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u0432\u0441\u0451 \u043f\u043e\u043c\u043d\u0438\u0442, \u0438 \u043d\u0430\u0439\u0442\u0438 \u0443\u0441\u0442\u0430\u0440\u0435\u0432\u0448\u0438\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 Tailwind Play <a href=\"https:\/\/codesandbox.io\/p\/devbox\/play-tailwindcss-com-jvnel\" rel=\"noopener noreferrer nofollow\">\u043d\u0435 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0442\u0440\u0443\u0434\u0430<\/a>.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0445\u043e\u0440\u043e\u0448\u0435\u043d\u044c\u043a\u043e \u0438\u0445 \u043f\u043e\u043a\u043e\u043f\u0430\u0442\u044c, \u0442\u043e \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u0442\u0430\u043c \u043d\u0435\u0442 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 4 \u0432\u0435\u0440\u0441\u0438\u0438, \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043e\u043d\u043e \u043e\u0447\u0435\u043d\u044c \u0433\u0440\u044f\u0437\u043d\u043e &#8212; \u0441 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0430\u043c\u0438 \u0432\u0441\u044f\u043a\u0438\u0445 Node.js-\u043c\u043e\u0434\u0443\u043b\u0435\u0439, &#171;\u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439&#187; \u0444\u0430\u0439\u043b\u043e\u0432\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439, \u043a\u0443\u0447\u0435\u0439 \u0445\u0430\u043a\u043e\u0432 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435.<br \/> \u0418\u0434\u0442\u0438 \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u0443\u0442\u0438 \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u044f \u043f\u0440\u0438\u043d\u044f\u043b \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 TSX+Tailwind \u0440\u0430\u0439\u0442\u0430\u0439\u043c Node.js. \u041e\u0441\u0442\u0430\u0432\u0430\u043b\u0441\u044f \u0432\u043e\u043f\u0440\u043e\u0441 &#8212; \u043a\u0430\u043a \u0437\u0430\u0432\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u0432 Tauri.<\/p>\n<h3>\u0417\u0430\u0432\u043e\u0434\u0438\u043c Node.js \u0432 Tauri<\/h3>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c, \u0432 Tauri \u0435\u0441\u0442\u044c \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c sidecars, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432\u043d\u0435\u0448\u043d\u0438\u0435 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0438 \u0432 \u0435\u0434\u0438\u043d\u044b\u0439 \u0431\u0430\u043d\u0434\u043b \u0441 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c.<br \/> \u0410 \u0434\u043b\u044f Node.js \u0435\u0441\u0442\u044c <code>pkg<\/code> &#8212; \u0443\u0442\u0438\u043b\u0438\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u043c\u0435\u0435\u0442 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0442\u044c Node.js \u0441\u043a\u0440\u0438\u043f\u0442-\u0431\u0430\u043d\u0434\u043b \u0432 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0439 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439.<br \/> \u0418 \u0443 Tauri \u0434\u0430\u0436\u0435 \u0435\u0441\u0442\u044c <a href=\"https:\/\/tauri.app\/learn\/sidecar-nodejs\/\" rel=\"noopener noreferrer nofollow\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0433\u0430\u0439\u0434<\/a> \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0437\u0430\u0432\u0435\u0441\u0442\u0438 Node.js-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u043a sidecar \u0434\u043b\u044f Tauri-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441 Node.js \u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u043e\u0431\u044a\u0451\u043c\u0430\u043c\u0438 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u044f \u0445\u043e\u0447\u0443 \u0437\u0430\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u0434 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0438\u0439 stdin-stdout \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c JSON-\u043f\u0430\u043a\u0435\u0442\u044b \u0443\u043f\u0430\u043a\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0432 base64.<\/p>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e, Node.js \u043a\u043e\u0434 \u044f \u0442\u043e\u0436\u0435 \u0445\u043e\u0447\u0443 \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043a\u0430\u043a TypeScript, \u0438 \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0434 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u0432 <code>pkg<\/code>.<br \/> \u0414\u0435\u043b\u0430\u0435\u043c <code>pnpm init<\/code> \u0432 <code>src-node<\/code> \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438, \u0431\u0430\u0445\u0430\u0435\u043c <code>src-node\/src\/index.ts<\/code> \u0441 \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u0439 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u043e\u0439, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432 <code>src-node\/package.json<\/code>:<\/p>\n<pre><code class=\"json\">{ ... \"scripts\": { \"build-code\": \"tsc\", \"build-binary\": \"pnpm run build-code &amp;&amp; pkg dist\/index.js --output qyp-mini-node-backend\", \"package-binary\": \"node scripts\/build.js qyp-mini-node-backend\", \"build\": \"pnpm run build-binary &amp;&amp; pnpm run package-binary\" }, \"devDependencies\": { \"@yao-pkg\/pkg\": \"^5.15.0\" }, \"bin\": { \"qyp-mini-node-backend\": \"dist\/index.js\" }, \"pkg\": { \"targets\": [ \"latest-macos\" ], \"scripts\": [ \"dist\/index.js\" ] }, ... } <\/code><\/pre>\n<p>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u044f \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u0437\u0430\u0432\u0451\u043b \u0442\u043e\u043b\u044c\u043a\u043e MacOS &#8212; \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u0432\u043e\u0434\u0438\u0442\u044c \u043f\u043e\u0442\u043e\u043c.<br \/> \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0432 <code>src-node\/scripts\/build.js<\/code> \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430 \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e <code>pkg<\/code> \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0430 \u0432 Tauri (\u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0443 \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u043e\u0432 \u0431\u044b\u043b\u043e \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0435 \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430 &#8212; Tauri \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443, \u043f\u043e\u0434 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d):<\/p>\n<pre><code class=\"javascript\">import { execSync } from 'child_process'; import fs from 'fs';  const ext = process.platform === 'win32' ? '.exe' : '';  const appName = process.argv[2];  const rustInfo = execSync('rustc -vV'); const targetTriple = \/host: (\\S+)\/g.exec(rustInfo)[1]; if (!targetTriple) { console.error('Failed to determine platform target triple'); } fs.renameSync(`${appName}${ext}`, `..\/src-tauri\/binaries\/${appName}-${targetTriple}${ext}`);  <\/code><\/pre>\n<p>\u0418 \u0434\u043e\u043a\u0438\u043d\u0435\u043c \u044d\u0442\u043e \u0432\u0441\u0451 \u0432\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u0438\u0435 \u0432 <code>package.json<\/code> \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<pre><code class=\"json\">\"scripts\": { \"dev\": \"cd src-node &amp;&amp; pnpm run build &amp;&amp; cd .. &amp;&amp; vite\", \"build\": \"cd src-node &amp;&amp; pnpm run build &amp;&amp; cd .. &amp;&amp; tsc &amp;&amp; vite build\", \"preview\": \"vite preview\", \"tauri\": \"tauri\" }, <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b <code>pnpm tauri dev<\/code> \u043e\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u043c \u0434\u0451\u0440\u043d\u0435\u0442 \u0441\u0431\u043e\u0440\u043a\u0443 \u0447\u0435\u0440\u0435\u0437 <code>pkg<\/code> \u0441\u0432\u0435\u0436\u0435\u0433\u043e Node.js \u0431\u0438\u043d\u0430\u0440\u043d\u0438\u043a\u0430, \u0438 \u0441\u0440\u0430\u0437\u0443 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0451 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u044d\u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 \u0437\u0430\u043f\u0438\u0441\u044c \u0432 stdin, \u0434\u0430 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0432\u044b\u0437\u043e\u0432 sidecar, \u0432\u0430\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u0441\u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b <code>src-tauri\/capabilities\/default.json<\/code>:<\/p>\n<pre><code class=\"json\">{ ... \"permissions\": [ \"core:default\", \"opener:default\", { \"identifier\": \"shell:allow-spawn\", \"allow\": [ { \"name\": \"binaries\/qyp-mini-node-backend\", \"cmd\": \"binaries\/qyp-mini-node-backend\", \"args\": true, \/\/ \u043d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u043f\u0440\u043e sidecar: true, \u0438\u043d\u0430\u0447\u0435 \u0431\u0443\u0434\u0435\u0442 scoped command not found \"sidecar\": true } ] }, \"shell:allow-stdin-write\", \/\/ \u0430 \u044d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u0432 stdin \"shell:default\" ] } <\/code><\/pre>\n<h3>\u041f\u0438\u043b\u0438\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0438\u0439 JSON-\u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b \u0434\u043b\u044f \u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 Node.js<\/h3>\n<p>\u041a\u0430\u043a \u044f \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b, \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c JSON \u0432 utf-8 \u0441\u0442\u0440\u043e\u0447\u043a\u0443, \u0430 \u0435\u0451 \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0432 base64. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u0430-\u0440\u0435\u043c\u0438\u043d\u0430\u0442\u043e\u0440\u0430 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0441\u0442\u0440\u043e\u043a\u0438 (\\n).<\/p>\n<p>\u041d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 Node.js:<\/p>\n<pre><code class=\"typescript\">\/\/ \u0427\u0438\u0442\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u0437 stdin const rl = createInterface({ input: process.stdin, output: process.stdout, terminal: false, });  rl.on('line', async line =&gt; { try { \/\/ \u0414\u0435\u043a\u043e\u0434\u0438\u0440\u0443\u0435\u043c base64 const jsonString = SmartBuffer.ofBase64String(line.trim()).toUTF8String(); \/\/ \u041f\u0430\u0440\u0441\u0438\u043c JSON const request = JSON.parse(jsonString);  \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441 const response = await processRequest(request);  \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u0442\u0432\u0435\u0442 sendResponse(response);  \/\/ \u0417\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 process.exit(0); } catch (error) { console.error('\u041e\u0448\u0438\u0431\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430:', error); sendResponse({ status: 'error', message: `\u041e\u0448\u0438\u0431\u043a\u0430 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430: ${error instanceof Error ? error.message : String(error)}`, }); process.exit(1); } }); <\/code><\/pre>\n<p>\u041d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0430:<\/p>\n<pre><code class=\"typescript\">import { SmartBuffer } from '@tiny-utils\/bytes';  export class SidecarEncoder { static encodeRequest(request: SidecarRequest): string { const jsonString = JSON.stringify(request); const base64String = SmartBuffer.ofUTF8String(jsonString).toBase64String(); return base64String + '\\n'; }  static decodeResponse(base64Response: string): any { try { const jsonString = SmartBuffer.ofBase64String(base64Response.trim()).toUTF8String(); return JSON.parse(jsonString); } catch (error) { throw<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\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-468765","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/468765","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=468765"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/468765\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=468765"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=468765"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=468765"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}