{"id":349637,"date":"2023-06-30T15:04:16","date_gmt":"2023-06-30T15:04:16","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=349637"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=349637","title":{"rendered":"<span>Zod: \u0422\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u0412\u0430\u0448\u0435\u0433\u043e .env (Vite + React \u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e)<\/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>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041d\u0435\u0440\u0435\u0434\u043a\u043e \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u0432\u043e\u0434\u0438\u0442\u044c <strong>\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f (environment variables)<\/strong>. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e &#171;inline&#187;, \u043a\u0430\u043a <code>MY_VAR=\"my value\" node index.js<\/code> \u0438\u043b\u0438 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u0442\u044c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <code>source<\/code>. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u0438\u043c\u0435\u044e\u0442 \u0434\u0430\u0436\u0435 \u0446\u0435\u043b\u044b\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f (\u043f\u0440\u0438\u043c. <a href=\"https:\/\/docs.nestjs.com\/techniques\/configuration\" rel=\"noopener noreferrer nofollow\">nest.js<\/a>). \u041d\u043e \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0437\u0430 \u0433\u043e\u0434\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0441\u0444\u0435\u0440\u0435 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043c\u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 <strong>.env<\/strong> \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u0422\u0430\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u0438\u043c\u0435\u044e\u0442 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0432\u0438\u0434\u0430 <code>KEY=VALUE<\/code>:<\/p>\n<pre><code class=\"bash\"># .env  APP_TITLE=\"My application\" PORT=3000<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0447\u0435\u0433\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0443\u0436\u043d\u044b \u044d\u0442\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 \u043a\u0430\u043a\u043e\u0433\u043e \u0440\u043e\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043d\u0438\u0445 \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c? \u041e\u0442\u0432\u0435\u0442:<\/p>\n<ul>\n<li>\n<p>\u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438. <br \/>\u041f\u0440\u0438\u043c\u0435\u0440: <code>KEY_SECRET<\/code> \u043e\u0442 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e API \u0438\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0411\u0414;<\/p>\n<\/li>\n<li>\n<p>\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0440\u0435\u0436\u0438\u043c\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u0440\u0438\u043c\u0435\u0440: <code>BASE_URL<\/code> \u0434\u043b\u044f:<\/p>\n<ul>\n<li>\n<p>dev-\u0441\u0442\u0435\u043d\u0434\u0430 \u2014 <em>https:\/\/<\/em><strong><em>dev<\/em><\/strong><em>.my-amazing-resource.com<\/em> <\/p>\n<\/li>\n<li>\n<p>test-\u0441\u0442\u0435\u043d\u0434\u0430 \u2014 <em>https:\/\/<\/em><strong><em>stage<\/em><\/strong><em>.my-amazing-resource.com<\/em> <\/p>\n<\/li>\n<li>\n<p>production \u2014 <em>https:\/\/my-amazing-resource.com<\/em><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0438\u043b\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b. \u041f\u0440\u0438\u043c\u0435\u0440: <code>PORT<\/code>, <code>PROXY_URL<\/code>, <code>FEATURE_TOGGLE<\/code> \u0438 \u0442.\u0434.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043a\u0440\u044b\u0442\u044b \u043e\u0442 \u0447\u0443\u0436\u0438\u0445 \u0433\u043b\u0430\u0437 \u0438 \u043c\u043e\u0433\u0443\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 (\u0438 \u0432\u043d\u0435) \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0435\u0436\u0438\u043c\u0430 \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b. \u0423\u0434\u043e\u0431\u043d\u043e!<\/p>\n<h2>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/h2>\n<p>\u0410 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 env-\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043d\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u043d\u0430\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u043d\u0435 \u0434\u0430\u0435\u0442 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043e \u0435\u0433\u043e \u0442\u0438\u043f\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412\u0437\u0433\u043b\u044f\u043d\u0438\u0442\u0435 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u043d\u0444\u0438\u0433:<\/p>\n<pre><code class=\"bash\"># .env  APP_TITLE=\"My app\" APP_VERSION=1 SHOW_VERSION=true # COMMENTED_REQUIRED_VALUE=<\/code><\/pre>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e <code>APP_TITLE<\/code>, <code>APP_VERSION<\/code> \u0438 <code>SHOW_VERSION<\/code> \u2014 \u044d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430, \u0447\u0438\u0441\u043b\u043e \u0438 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0436\u0435 \u0434\u0435\u043b\u0435 \u0412\u0421\u0415 \u044d\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438.<\/p>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0437\u0430\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <code>COMMENTED_REQUIRED_VALUE<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435\u0441\u043f\u0440\u043e\u0441\u0442\u0430 \u043d\u0430\u0437\u0432\u0430\u043d\u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0427\u0442\u043e \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043f\u043e \u0438\u0442\u043e\u0433\u0443:<\/p>\n<ol>\n<li>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0437\u0430\u0434\u0443\u043c\u0430\u043d\u043d\u044b\u043c \u0438\u043c \u0442\u0438\u043f\u0430\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0438\u0445 \u043a \u044d\u0442\u0438\u043c \u0442\u0438\u043f\u0430\u043c:<\/p>\n<ul>\n<li>\n<p><code>const title = process.env.APP_TITLE; \/\/ all is ok<\/code><\/p>\n<\/li>\n<li>\n<p><code>const version = Number(process.env.APP_VERSION);<\/code><\/p>\n<\/li>\n<li>\n<p><code>const showVersion = JSON.parse(process.env.SHOW_VERSION);<\/code><\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u043e\u043c\u0430\u0442\u044c \u0441\u0430\u043c\u0430\u044f \u043c\u0430\u043b\u0430\u044f \u043e\u043f\u0435\u0447\u0430\u0442\u043a\u0430 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>False<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>false<\/code> \u0438\u043b\u0438 <code>1,0<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>1<\/code>. \u0421\u0442\u043e\u0438\u0442 \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c \u043d\u0430 \u0441\u0447\u0435\u0442 \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0438 \u043f\u0440\u043e\u0447\u0435\u043c.<\/p>\n<\/li>\n<li>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a <em>.env<\/em> \u043d\u0435 \u0434\u0430\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043c\u044b, \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>COMMENTED_REQUIRED_VALUE<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u0430, \u041d\u041e \u043f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u0430\u0441\u044c \u0437\u0430\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443. \u041e\u043a\u0435\u0439, \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0449\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u043e\u0432, \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0442\u0438\u043f\u043e\u0432.<\/p>\n<\/li>\n<\/ol>\n<p><s>\u0414\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u043e\u0432, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u0434&#8230;<\/s><\/p>\n<p>\u041d\u0435\u0442.<\/p>\n<h2>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 v0<\/h2>\n<p>\u041d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430, \u0432\u044b \u0443\u0436\u0435 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u0434\u0443\u043c\u0430\u043b\u0438, \u0447\u0442\u043e \u0431\u044b\u043b\u043e \u0434\u0430\u043b\u044c\u0448\u0435. \u0422\u0430\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c-\u0442\u043e \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u0438 \u0443\u0434\u043e\u0431\u043d\u043e. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0430\u0441\u043f\u0435\u043a\u0442\u044b. \u0412 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u044f \u0445\u043e\u0447\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c ? \u0445\u043e\u0440\u043e\u0448\u0435\u0435 ? \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u0430\u043c \u043f\u043e\u0434\u0445\u043e\u0434, \u0430 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0435\u0433\u043e &#171;\u0434\u043e\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0439 \u0434\u043e \u0443\u043c\u0430&#187; \u0432\u0435\u0440\u0441\u0438\u0438 \u2014 \u2728 <strong>\u043e\u0442\u043b\u0438\u0447\u043d\u043e\u043c <\/strong>\u2728 \u0440\u0435\u0448\u0435\u043d\u0438\u0438.<\/p>\n<p>\u0417\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u0431\u0443\u0434\u0435\u0442 \u0432\u0437\u044f\u0442 \u043f\u0440\u043e\u0435\u043a\u0442, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 <a href=\"https:\/\/vitejs.dev\" rel=\"noopener noreferrer nofollow\">Vite<\/a> \u043f\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0443 <code>react-swc-ts<\/code>, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 <a href=\"https:\/\/react.dev\" rel=\"noopener noreferrer nofollow\">React<\/a> + <a href=\"https:\/\/swc.rs\" rel=\"noopener noreferrer nofollow\">SWC<\/a> + <a href=\"https:\/\/www.typescriptlang.org\" rel=\"noopener noreferrer nofollow\">TypeScript<\/a>. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u044d\u0442\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043a \u043b\u044e\u0431\u043e\u043c\u0443 \u0441\u0442\u0435\u043a\u0443. <\/p>\n<p><span class=\"habrahidden\">\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b prettier, \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b\u00a0\u043b\u0438\u043d\u0442\u0438\u043d\u0433, \u043e\u0442\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u043a\u043e\u0434, \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b @types\/node, \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u043b package.json, \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u043b vite.config.ts. \u0422\u0435\u043f\u0435\u0440\u044c \u0445\u043e\u0440\u043e\u0448\u043e. \u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0443\u0433\u043b\u0443\u0431\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 Vite \u0438\u043b\u0438 React, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u041d\u0415 \u0418\u041c\u0415\u042e\u0422 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u043a \u0434\u0435\u043b\u0443. \u0422\u043e\u043b\u044c\u043a\u043e \u0441\u0443\u0442\u044c.<\/span><\/p>\n<pre><code class=\"bash\">yarn dev # \u0438\u043b\u0438 vite<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b2a\/f62\/0f8\/b2af620f85543fc2673fc50c97a9483f.png\" alt=\"\u0422\u0430\u043a\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\" title=\"\u0422\u0430\u043a\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\" width=\"2000\" height=\"1160\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b2a\/f62\/0f8\/b2af620f85543fc2673fc50c97a9483f.png\"\/><\/p>\n<div><figcaption>\u0422\u0430\u043a\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/figcaption><\/div>\n<\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 &#171;\u043b\u0438\u0448\u043d\u0435\u0433\u043e \u0448\u0443\u043c\u0430&#187; \u044f \u0443\u0434\u0430\u043b\u044e \u0432\u0435\u0441\u044c \u043a\u043e\u0434, \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 Vite \u0438 \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a <code>h1<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0441\u043b\u0443\u0436\u0438\u0442 \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u044f \u0445\u043e\u0447\u0443 \u0438\u043c\u0435\u0442\u044c \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043a\u043e\u043d\u0444\u0438\u0433, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0432\u044b\u0448\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430, \u0442\u0430\u043a \u0447\u0442\u043e \u044f \u0441\u043e\u0437\u0434\u0430\u043c \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 <strong>.env<\/strong> \u0444\u0430\u0439\u043b:<\/p>\n<pre><code class=\"bash\">APP_TITLE=\"My app\" APP_VERSION=1 SHOW_VERSION=true # COMMENTED_REQUIRED_VALUE=<\/code><\/pre>\n<p>Vite \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u0432\u043e\u0435\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0441 <strong>.env<\/strong>. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 <a href=\"https:\/\/vitejs.dev\/guide\/env-and-mode.html\" rel=\"noopener noreferrer nofollow\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>, \u043d\u043e \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u043d\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0441 \u043f\u0440\u0435\u0438\u0444\u043a\u0441\u043e\u043c <code>VITE_<\/code>, \u0430 \u0432\u044b\u0437\u043e\u0432 \u044d\u0442\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 <code>import.meta.env<\/code>.<br \/>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433 \u0442\u0430\u043a\u043e\u0433\u043e \u0432\u0438\u0434\u0430:<\/p>\n<pre><code class=\"bash\">VITE_APP_TITLE=\"My app\" VITE_APP_VERSION=1 VITE_SHOW_VERSION=true # VITE_COMMENTED_REQUIRED_VALUE=<\/code><\/pre>\n<p>\u0418 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>VITE_APP_TITLE<\/code>, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0432 \u0435\u0435 \u0432\u043d\u0443\u0442\u0440\u044c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 <code>h1<\/code>, \u043f\u043e\u043b\u044c\u0437\u0443\u044f\u0441\u044c \u0438\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u0435\u0439 <em>JSX(TSX)<\/em>:<\/p>\n<pre><code class=\"typescript\">export const App = () => {   return &lt;h1>{import.meta.env.VITE_APP_TITLE}&lt;\/h1>; };<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/72c\/8f5\/90d\/72c8f590d68306e2e1a7292d275449b6.png\" alt=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\" title=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\" width=\"2378\" height=\"1584\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/72c\/8f5\/90d\/72c8f590d68306e2e1a7292d275449b6.png\"\/><\/p>\n<div><figcaption>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e! \u042d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041d\u043e \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432 \u043a\u043e\u0434\u0435 \u043d\u0430 \u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 <code>import.meta.env<\/code>, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043e\u043d \u0432\u0440\u043e\u0434\u0435 \u043a\u0430\u043a \u0438 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0443\u0436\u043d\u044b\u0445 \u043d\u0430\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043b\u044e\u0431\u043e\u0435 \u0435\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e, \u043f\u043e\u043c\u0438\u043c\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 <code>BASE_URL<\/code>, <code>MODE<\/code>, <code>DEV<\/code>, <code>PROD<\/code>, <code>SSR<\/code>, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u0438\u043f\u0430 <code>any<\/code>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/402\/e81\/0bf\/402e810bf6a0f7c0c0a6eaa82f031258.png\" width=\"1682\" height=\"722\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/402\/e81\/0bf\/402e810bf6a0f7c0c0a6eaa82f031258.png\"\/><\/figure>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 <a href=\"https:\/\/vitejs.dev\/guide\/env-and-mode.html#intellisense-for-typescript\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/a>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Vite. \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c <em>env.d.ts<\/em>, \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0435\u0433\u043e \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e <em>src<\/em> \u0438\u043b\u0438 \u043a\u0443\u0434\u0430 \u0432\u0430\u043c \u0443\u0433\u043e\u0434\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 <em>src\/types<\/em>:<\/p>\n<pre><code class=\"typescript\">\/\/\/ &lt;reference types=\"vite\/client\" \/>  interface ImportMetaEnv {   readonly VITE_APP_TITLE: string;   readonly VITE_APP_VERSION: number;   readonly VITE_SHOW_VERSION: boolean;   readonly VITE_COMMENTED_REQUIRED_VALUE: any; }  interface ImportMeta {   readonly env: ImportMetaEnv }<\/code><\/pre>\n<p>\u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0435\u043f\u043b\u043e\u0445\u043e, \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 \u0438 \u043e\u043f\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0438\u0445 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ac3\/406\/640\/ac34066401a09bcf72c679104c978b5c.png\" width=\"1686\" height=\"720\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ac3\/406\/640\/ac34066401a09bcf72c679104c978b5c.png\"\/><\/figure>\n<p>\u041d\u043e \u0432\u043e\u043f\u0440\u043e\u0441 \u0441 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0435\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c. IDE \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <code>VITE_APP_VERSION<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u0438\u043f\u0430 <code>number<\/code>. \u041d\u043e \u043f\u043e \u0444\u0430\u043a\u0442\u0443, \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 <code>typeof<\/code>, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c <code>string<\/code>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f51\/10d\/0bb\/f5110d0bbfb78e963438d7a3a7584a1d.png\" width=\"1408\" height=\"278\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f51\/10d\/0bb\/f5110d0bbfb78e963438d7a3a7584a1d.png\"\/><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/394\/cbf\/f4e\/394cbff4ebc65f5dbbb7c9d391fad784.png\" width=\"892\" height=\"280\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/394\/cbf\/f4e\/394cbff4ebc65f5dbbb7c9d391fad784.png\"\/><\/figure>\n<p>\u0422\u0430\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442, \u0441\u043a\u043e\u0440\u0435\u0435, \u0441\u0431\u0438\u0442\u044c \u0441\u0442\u043e\u043b\u043a\u0443. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0444\u0430\u0439\u043b\u043e\u0432: \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 src \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e config, \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0434\u0432\u0430 <code>.ts<\/code> \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430:<\/p>\n<ul>\n<li>\n<p>index.ts<\/p>\n<\/li>\n<li>\n<p>buildEnvProxy.ts<\/p>\n<\/li>\n<\/ul>\n<p>buildEnvProxy.ts \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u0441\u0435\u0431\u0435 \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b: <em>source<\/em> \u2014 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0435\u0440\u0443\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f (\u043a\u0430\u043a \u0432\u044b \u043f\u043e\u043c\u043d\u0438\u0442\u0435, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e <code>import.meta.env<\/code>) \u0438 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 <em>transformKey<\/em> \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447\u0438 (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445) \u043a\u043e\u043d\u0444\u0438\u0433\u0430, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. <\/p>\n<p>\u0421 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043d\u043e \u0437\u0430\u0447\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447\u0438? \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u043d\u0435 \u0431\u044b \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0444\u0438\u043a\u0441 <code>VITE_<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0435\u0440\u0435\u0437 <code>Proxy<\/code> \u044f \u0431\u0443\u0434\u0443 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0435\u0433\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 <code>Proxy<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d handler \u2014 <code>get<\/code>. \u0415\u0433\u043e \u0438 \u043e\u043f\u0438\u0448\u0435\u043c.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043a\u043b\u044e\u0447 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u2014 \u044d\u0442\u043e <code>string | symbol<\/code>, \u0430 \u043d\u0430\u0448 \u043a\u043e\u043d\u0444\u0438\u0433, \u043f\u043e \u0438\u0434\u0435\u0435 \u2014 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u0442\u0438\u043f\u0430 <code>Record&lt;string | unknown><\/code>, \u0433\u0434\u0435 \u043a\u043b\u044e\u0447 \u2014 \u044d\u0442\u043e <code>string<\/code>, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u044d\u0442\u043e\u0442 \u043a\u043b\u044e\u0447 \u043a \u0441\u0442\u0440\u043e\u043a\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>String<\/code>.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043a\u043b\u044e\u0447 \u0432 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <em>transformKey<\/em> \u0438, \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u2014 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435. \u0412 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435 get \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 <em>source<\/em> \u043f\u043e \u043a\u043b\u044e\u0447\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043a \u0441\u0442\u0440\u043e\u043a\u0435 \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <em>transformKey<\/em>:<\/p>\n<pre><code class=\"typescript\">\/\/ buildEnvProxy.ts  export const buildEnvProxy = &lt;T extends Record&lt;string, unknown>>(   source: T,   transformKey: (key: string) => string, ) =>   new Proxy({} as T, {     get(_, key) {       const keyStr = String(key);       const envKey = transformKey ? transformKey(keyStr) : keyStr;        return source[envKey];     },   });<\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 <em>index.ts<\/em> \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 ENV \u0438 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u0435\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u0432\u044b\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0443\u043a\u0430\u0437\u0430\u0432 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <em>generic<\/em> <code>Record&lt;string, unknown><\/code>, \u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432: \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u2014 <code>import.meta.env<\/code> \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043a \u043a\u043b\u044e\u0447\u0443 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u043f\u0440\u0435\u0444\u0438\u043a\u0441:<\/p>\n<pre><code class=\"typescript\">\/\/ index.ts  import { buildEnvProxy } from '.\/buildEnvProxy.ts';  const ENV = buildEnvProxy&lt;Record&lt;string, unknown>>(   import.meta.env,   (key) => `VITE_${key}`, );<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c:<\/p>\n<pre><code class=\"typescript\">console.log('Without prefix:', ENV.APP_TITLE); console.log('With prefix', ENV.VITE_APP_TITLE);<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ff0\/f72\/54c\/ff0f7254c9c1a20d8f0f7acb43cce13a.png\" width=\"890\" height=\"282\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ff0\/f72\/54c\/ff0f7254c9c1a20d8f0f7acb43cce13a.png\"\/><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0430. \u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u0432 \u044d\u0442\u043e\u0439 \u0436\u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 <em>config.types.ts<\/em>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c <code>type Config<\/code> \u0441 \u0442\u0438\u043f\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439:<\/p>\n<pre><code class=\"typescript\">\/\/ config.types.ts  export type Config = {   APP_TITLE: string;   APP_VERSION: number;   SHOW_VERSION: boolean;   COMMENTED_REQUIRED_VALUE: any; };<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u043d\u0430 \u044d\u0442\u043e\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u043d\u0430 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 Vite, \u0442.\u043a. \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e\u0434 \u043a\u043e\u043d\u0444\u0438\u0433 \u0438\u043c\u0435\u0435\u0442\u0441\u044f, \u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442\u0441\u044f \u0438 \u043f\u043e \u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0442\u0438\u043f\u0430 <code>string<\/code>. <\/p>\n<p>\u0414\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u0432\u043d\u0443\u0442\u0440\u0438 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <em>config<\/em> \u0437\u0430\u0432\u043e\u0434\u0438\u043c \u043d\u043e\u0432\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e <em>configGetters<\/em>, \u0430 \u0432 \u043d\u0435\u0439 \u0442\u0440\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430, \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430:<\/p>\n<ul>\n<li>\n<p><em>getBoolean.ts<\/em><\/p>\n<\/li>\n<li>\n<p><em>getNumber.ts<\/em><\/p>\n<\/li>\n<li>\n<p><em>getString.ts<\/em><\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u0430\u043a \u0432\u044b \u0443\u0436\u0435 \u0434\u043e\u0433\u0430\u0434\u0430\u043b\u0438\u0441\u044c, \u044d\u0442\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0442\u0438\u043f\u0430\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445. \u0418\u043c\u0435\u043d\u043d\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435. <\/p>\n<pre><code class=\"typescript\">\/\/ getBoolean.ts  export const getBoolean = (   target: Record&lt;string, unknown>,   key: string, ): boolean => {   const value = target[key];    try {     if (value === 'true' || value === true) return true;     if (value === 'false' || value === false) return false;      throw new Error();   } catch {     throw new Error(`Config value for \"${key}\" is not a boolean: \"${value}\"`);   } };<\/code><\/pre>\n<pre><code class=\"typescript\">\/\/ getNumber.ts  export const getNumber = (   target: Record&lt;string, unknown>,   key: string, ): number => {   const value = target[key];    try {     const numValue = Number(value);      if (isFinite(numValue) &amp;&amp; !isNaN(numValue)) return numValue;      throw new Error();   } catch {     throw new Error(`Config value for \"${key}\" is not a number: \"${value}\"`);   } };<\/code><\/pre>\n<pre><code class=\"typescript\">\/\/ getString.ts  export const getString = (   target: Record&lt;string, unknown>,   key: string, ): string => {   const strValue = target[key];    try {     if (typeof strValue === 'string') return strValue;      throw new Error();   } catch {     throw new Error(`Config value for \"${key}\" is not a string: \"${strValue}\"`);   } };<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u043a\u043e\u043d\u0444\u0438\u0433\u0430 \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f\u043c \u2014 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0431\u0440\u043e\u0448\u0435\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0430.<\/p>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0442\u0430\u043a\u0436\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a\u0430\u044f \u0438\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u043d\u0438\u043c\u0435\u043c\u0441\u044f \u043d\u0430 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432\u044b\u0448\u0435, \u0442.\u0435. \u0432\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e <em>config<\/em> \u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u2014 <em>config.gettersMap.ts<\/em>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u0438\u0432\u044f\u0436\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c:<\/p>\n<pre><code class=\"typescript\">\/\/ config.gettersMap.ts  import type { Config } from '.\/config.types.ts';  import { getString } from '.\/configGetters\/getString.ts'; import { getNumber } from '.\/configGetters\/getNumber.ts'; import { getBoolean } from '.\/configGetters\/getBoolean.ts';  export const CONFIG_GETTERS_MAP: {   [K in keyof Config]: (target: Record&lt;string, unknown>, key: K) => Config[K]; } = {   APP_TITLE: getString,   APP_VERSION: getNumber,   SHOW_VERSION: getBoolean,   COMMENTED_REQUIRED_VALUE: getString };<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442, \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u043b\u044e\u0447\u0430\u043c\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043a\u043b\u044e\u0447\u0438 \u0442\u0438\u043f\u0430 <code>Config<\/code>, \u0442.\u0435. \u043d\u0430\u0448\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u0418 \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u043a\u043b\u044e\u0447\u0443 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f.<\/p>\n<p>\u0412\u044b \u043c\u043e\u0433\u043b\u0438 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0435\u043a\u0446\u0438\u0438 \u043d\u0438 \u0440\u0430\u0437\u0443 \u043d\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u0430\u0441\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <code>COMMENTED_REQUIRED_VALUE<\/code>. \u041f\u043e\u0437\u0436\u0435 \u044f \u0440\u0430\u0441\u043a\u0440\u043e\u044e \u0432\u0441\u0435 \u043a\u0430\u0440\u0442\u044b, \u0430 \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u043c \u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>getString<\/code>.<\/p>\n<p>\u0417\u0430\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0435\u043a\u0446\u0438\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0431\u043e\u0440 \u0432\u0441\u0435\u0433\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0432\u043c\u0435\u0441\u0442\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430 \u0442\u043e\u043c \u0436\u0435 \u0443\u0440\u043e\u0432\u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u2014 <em>buildConfigProxy.ts<\/em>. \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442: <\/p>\n<ol>\n<li>\n<p><em>generic<\/em> \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u0442\u044c \u0442\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f;<\/p>\n<\/li>\n<li>\n<p> \u0434\u0432\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430:<\/p>\n<ul>\n<li>\n<p><em>env<\/em> \u2014 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0440\u0430\u043d\u0435\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>buildEnvProxy<\/code><\/p>\n<\/li>\n<li>\n<p><em>envGettersMap<\/em> \u2014 \u043d\u0430\u0448 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u043d\u044b\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u2014 <code>CONFIG_GETTERS_MAP<\/code><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0444\u0438\u0433, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0448\u0435\u043b \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0438 \u0438\u0445 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u0442\u0438\u043f\u0430\u043c.<\/p>\n<pre><code class=\"typescript\">\/\/ buildConfigProxy.ts  export const buildConfigProxy = &lt;T extends Record&lt;string, unknown>>({   env,   envGettersMap, }: {   env: Record&lt;string, unknown>;   envGettersMap: {     [K in keyof T]: (target: Record&lt;string, unknown>, key: K) => T[K];   }; }) =>   new Proxy({} as T, {     get(_, key) {       const keyStr = String(key);       const getter = envGettersMap[keyStr];        if (!getter || typeof getter !== 'function') {         throw new Error(`Config: Proxy getter for \"${keyStr}\" is not defined`);       }        return getter(env, keyStr);     },   });<\/code><\/pre>\n<p>\u041e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u044c <em>index.ts<\/em> \u0432\u044b\u0437\u043e\u0432\u043e\u043c \u0434\u0430\u043d\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"typescript\">\/\/ index.ts  import { buildEnvProxy } from '.\/buildEnvProxy.ts'; import { buildConfigProxy } from '.\/buildConfigProxy.ts'; import { CONFIG_GETTERS_MAP } from '.\/config.gettersMap.ts';  import type { Config } from '.\/config.types.ts';  const ENV = buildEnvProxy&lt;Record&lt;string, unknown>>(   import.meta.env,   (key) => `VITE_${key}`, );  export const CONFIG = buildConfigProxy&lt;Config>({   env: ENV,   envGettersMap: CONFIG_GETTERS_MAP, });<\/code><\/pre>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <em>generic<\/em> \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u0442\u0438\u043f <code>Config<\/code>, \u043e \u0447\u0435\u043c \u0443\u0436\u0435 \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 IDE:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d24\/7fc\/c25\/d247fcc254ea00f50eccf5b174c69e68.png\" width=\"1294\" height=\"230\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d24\/7fc\/c25\/d247fcc254ea00f50eccf5b174c69e68.png\"\/><\/figure>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c:<\/p>\n<pre><code class=\"bash\"># .env  VITE_APP_TITLE=\"My app\" VITE_APP_VERSION=1 VITE_SHOW_VERSION=true # VITE_COMMENTED_REQUIRED_VALUE=<\/code><\/pre>\n<pre><code class=\"typescript\">\/\/ App.tsx  import { CONFIG } from '.\/config';  export const App = () =>    return (     &lt;h1>       {CONFIG.SHOW_VERSION &amp;&amp; (          &lt;>           {CONFIG.APP_TITLE} v{CONFIG.APP_VERSION.toFixed(1)}         &lt;\/>       )}     &lt;\/h1>   ); };<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/47f\/e80\/a87\/47fe80a877f2b7ac347ca8cc92025455.png\" width=\"2376\" height=\"1584\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/47f\/e80\/a87\/47fe80a877f2b7ac347ca8cc92025455.png\"\/><\/figure>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0431\u044b\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b \u0438 \u043a\u043e\u0434 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e. \u041e\u0431 \u044d\u0442\u043e\u043c \u0441\u0432\u0438\u0434\u0435\u0442\u0435\u043b\u044c\u0441\u0442\u0432\u0443\u0435\u0442, \u043a\u0430\u043a \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 <code>h1<\/code>, \u0442\u0430\u043a \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u044b\u0439 \u043d\u0430\u0434 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>CONFIG.APP_VERSION<\/code> \u043c\u0435\u0442\u043e\u0434 <code>.toFixed(1)<\/code>, \u043f\u0440\u0438\u0441\u0443\u0449\u0438\u0439 \u0442\u0438\u043f\u0443 <code>number<\/code>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432 <strong>.env<\/strong> \u0437\u0430\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u043b\u044e\u0431\u0443\u044e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>VITE_APP_TITLE<\/code>: <\/p>\n<pre><code class=\"bash\"># VITE_APP_TITLE=\"My app\" VITE_APP_VERSION=1 VITE_SHOW_VERSION=true # VITE_COMMENTED_REQUIRED_VALUE=<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043e\u0448\u0438\u0431\u043a\u0443 <code>Config value for \"APP_TITLE\" is not a string: \"undefined\"<\/code> \u0438 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u0447\u0442\u043e \u0441\u0442\u043e\u0438\u0442 \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/838\/696\/9f3\/8386969f3441e31a80c64a7150fb23ea.png\" width=\"2424\" height=\"1584\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/838\/696\/9f3\/8386969f3441e31a80c64a7150fb23ea.png\"\/><\/figure>\n<p>\u0418 \u0434\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0440\u0430\u0441\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>VITE_APP_TITLE<\/code> \u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043c \u0442\u0435\u043f\u0435\u0440\u044c \u0443\u0436\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>VITE_APP_VERSION<\/code>:<\/p>\n<pre><code class=\"bash\">VITE_APP_TITLE=\"My app\" VITE_APP_VERSION=1,0 VITE_SHOW_VERSION=true # VITE_COMMENTED_REQUIRED_VALUE=<\/code><\/pre>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u2014 \u043e\u0448\u0438\u0431\u043a\u0430 <code>Config value for \"APP_VERSION\" is not a number: \"1,0\"<\/code>:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/25c\/c45\/581\/25cc45581669c5a0de4b0b079cbaf617.png\" width=\"2422\" height=\"1584\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/25c\/c45\/581\/25cc45581669c5a0de4b0b079cbaf617.png\"\/><\/figure>\n<p>\u041a\u0440\u0443\u0442\u043e! \u041c\u044b \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043b\u0438 \u0445\u043e\u0440\u043e\u0448\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443: \u043a\u043e\u043d\u0444\u0438\u0433 \u0442\u0435\u043f\u0435\u0440\u044c \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u0441\u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u043d. \u041f\u043e\u043c\u0438\u043c\u043e, \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0445 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a <code>getNumber<\/code>, <code>getString<\/code> \u0438 <code>getBoolean<\/code>, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u0434\u0440\u0443\u0433\u0438\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, enum:<\/p>\n<pre><code class=\"typescript\">export const getEnum =   &lt;T>(     getter: (target: Record&lt;string, unknown>, key: string) => unknown,     allowedValues: T[],   ): ((target: Record&lt;string, unknown>, key: string) => T) =>   (target, key) => {     const value = getter(target, key) as T;      try {       if (allowedValues.includes(value)) return value;        throw new Error();     } catch {       throw new Error(         `Config value for \"${key}\" is not one of allowed values [${allowedValues}]: \"${value}\"`,       );     }   };<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0434\u0440\u0443\u0433\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0433\u0435\u0442\u0442\u0435\u0440 \u0438 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u0435\u0442 <em>generic<\/em> \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435\u043c \u044d\u0442\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f:<\/p>\n<pre><code class=\"typescript\">... MODE: getSpecific&lt;'production' | 'development' | 'test'>(getString, [   'production',   'development',   'test', ]), ...<\/code><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0441\u0435\u043a\u0446\u0438\u044f \u043f\u0440\u043e ? \u0445\u043e\u0440\u043e\u0448\u0435\u0435 ? \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u043e\u0448\u043b\u0430 \u043a \u043a\u043e\u043d\u0446\u0443. \u0412\u043e\u0442 \u0442\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u0432 \u0438\u0442\u043e\u0433\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d04\/da1\/e3e\/d04da1e3e01b32fcbf1393e30f602ee6.png\" width=\"532\" height=\"540\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d04\/da1\/e3e\/d04da1e3e01b32fcbf1393e30f602ee6.png\"\/><\/figure>\n<p>\u041d\u043e \u0447\u0442\u043e \u0436\u0435 \u0441 <code>VITE_COMMENTED_REQUIRED_VALUE<\/code>? \u042d\u0442\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u043a\u0430\u043a \u0440\u0430\u0437 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0441\u0432\u044f\u0437\u0430\u043d\u0430 \u0441\u043e \u0432\u0442\u043e\u0440\u044b\u043c, \u2728 <strong>\u043e\u0442\u043b\u0438\u0447\u043d\u044b\u043c<\/strong> \u2728 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b.<\/p>\n<h3>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 v1<\/h3>\n<p>\u0418\u0442\u0430\u043a, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442? <\/p>\n<p><code>VITE_COMMENTED_REQUIRED_VALUE<\/code> \u043a\u0430\u043a \u0440\u0430\u0437 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u043b\u0430\u0441\u044c, \u043a\u0430\u043a \u0442\u0430\u043a\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f.<\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0449\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 <code>getNumber<\/code>, <code>getBoolean<\/code> \u0438 \u0442.\u0434., \u043d\u043e \u0435\u0441\u043b\u0438 \u0442\u0430\u043a\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0438 \u043e\u043d\u0438 \u0432\u0441\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440, \u0442\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0445\u043e\u0440\u043e\u0448\u0435\u0439 \u0438\u0434\u0435\u0435\u0439.<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043d\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 <a href=\"https:\/\/zod.dev\" rel=\"noopener noreferrer nofollow\"><strong>Zod<\/strong><\/a>.<\/p>\n<p>\u041d\u0430 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u0430\u0439\u0442\u0435 \u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<blockquote>\n<p><em>Zod \u2014 \u044d\u0442\u043e TypeScript-first \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u0445\u0435\u043c. \u042f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0442\u0435\u0440\u043c\u0438\u043d \u00ab\u0441\u0445\u0435\u043c\u0430\u00bb \u0434\u043b\u044f \u0448\u0438\u0440\u043e\u043a\u043e\u0433\u043e \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e\u00a0<\/em><code>string<\/code><em>\u00a0\u043a \u0441\u043b\u043e\u0436\u043d\u043e\u043c\u0443 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u043c\u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0443.<\/em><\/p>\n<\/blockquote>\n<p>\u041f\u0440\u043e\u0449\u0435 \u0433\u043e\u0432\u043e\u0440\u044f, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u043b\u0438\u0431\u043e \u0441\u0445\u0435\u043c\u0443, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u043e \u044d\u0442\u043e\u0439 \u0441\u0445\u0435\u043c\u0435 \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u041f\u0440\u0438\u043c\u0435\u0440 (\u0442\u043e\u0436\u0435 \u0441 \u043e\u0444. \u0441\u0430\u0439\u0442\u0430):<\/p>\n<pre><code class=\"typescript\">import { z } from \"zod\";  \/\/ \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0445\u0435\u043c\u044b \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u043a (string) const mySchema = z.string();  \/\/ \u043f\u0430\u0440\u0441\u0438\u043d\u0433 mySchema.parse(\"tuna\"); \/\/ => \"tuna\" mySchema.parse(12); \/\/ => throws ZodError  \/\/ \"\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0439\" \u043f\u0430\u0440\u0441\u0438\u043d\u0433 (\u043d\u0435 throw error \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u043b\u0430\u0441\u044c) mySchema.safeParse(\"tuna\"); \/\/ => { success: true; data: \"tuna\" } mySchema.safeParse(12); \/\/ => { success: false; error: ZodError }<\/code><\/pre>\n<p>\u0418 \u0435\u0449\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0438\u043c\u044b\u0445 \u043f\u043b\u044e\u0441\u043e\u0432 (\u043e\u043f\u044f\u0442\u044c \u0436\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u043e\u0444. \u0441\u0430\u0439\u0442\u0435):<\/p>\n<ul>\n<li>\n<p>0 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439;<\/p>\n<\/li>\n<li>\n<p>\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 Node.js \u0438 \u0432\u0441\u0435\u0445 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u0445;<\/p>\n<\/li>\n<li>\n<p>\u043a\u0440\u043e\u0448\u0435\u0447\u043d\u044b\u0439: 8kb minified + zipped;<\/p>\n<\/li>\n<li>\n<p>\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 JS (TS \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u0435\u043d) \u2014 \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e, \u043d\u043e \u043a\u0440\u0443\u0442\u043e!<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044e <strong>Zod<\/strong>. \u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u044f \u0441\u0434\u0435\u043b\u0430\u044e \u044d\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <em>yarn<\/em>:<\/p>\n<pre><code class=\"bash\">yarn add zod<\/code><\/pre>\n<p>\u0410 \u0437\u0430\u0442\u0435\u043c \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0438\u0437 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <em>config<\/em> \u0412\u0421\u0415, \u0447\u0442\u043e \u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0432 \u0441\u0435\u043a\u0446\u0438\u0438 &#171;\u0420\u0435\u0448\u0435\u043d\u0438\u0435 v0&#187;, \u043a\u0440\u043e\u043c\u0435 <em>index.ts<\/em> \u0438 <em>buildEnvProxy.ts<\/em>. \u0414\u0430, \u043d\u0430\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f, <code>buildConfigProxy<\/code><em>, <\/em><code>CONFIG_GETTERS_MAP<\/code> \u2014 <strong>Zod<\/strong> \u0432\u0441\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u0437\u0430 \u043d\u0430\u0441! <sub>(\u043f\u043e\u0447\u0442\u0438)<\/sub> <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043d\u043e\u0432\u044b\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 \u2014 <em>config.schema.ts<\/em>. \u0412 \u044d\u0442\u043e\u043c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0435 \u043e\u043f\u0438\u0448\u0435\u043c \u0441\u0445\u0435\u043c\u0443 \u043a\u043e\u043d\u0444\u0438\u0433\u0430 \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043d\u0430 \u0432\u0445\u043e\u0434 \u043d\u0430\u0448 ENV, \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0435\u0433\u043e \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0430. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0438\u0437-\u0437\u0430 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e (\u0438\u043b\u0438 \u0432\u043e\u0432\u0441\u0435 \u043d\u0435\u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e) \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0443.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043a\u043e\u043d\u0444\u0438\u0433 \u2014 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442, \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u043c \u0441\u0445\u0435\u043c\u0443, \u043a\u0430\u043a <code>z.object({})<\/code>, \u0430 \u0432\u043d\u0443\u0442\u0440\u0438, \u0432 \u0444\u0438\u0433\u0443\u0440\u043d\u044b\u0445 \u0441\u043a\u043e\u0431\u043a\u0430\u0445 \u043e\u043f\u0438\u0448\u0435\u043c \u044d\u0442\u043e\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 Zod&#8217;\u0430:<\/p>\n<pre><code class=\"typescript\">\/\/ config.schema.ts  import { z } from 'zod';  const configSchema = z.object({   APP_TITLE: z.string(),   APP_VERSION: z.number(),   SHOW_VERSION: z.boolean(), });<\/code><\/pre>\n<p>\u041d\u0438\u0436\u0435 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0442\u0443 \u0441\u0430\u043c\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u043a\u043e\u043d\u0444\u0438\u0433:<\/p>\n<pre><code class=\"typescript\">export const parseConfig = (configObj: Record&lt;string, unknown>) => {   const parseResult = configSchema.safeParse(configObj);    if (!parseResult.success) throw parseResult.error;    return parseResult.data; }<\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0443 \u0441\u0445\u0435\u043c\u044b \u043c\u0435\u0442\u043e\u0434 <a href=\"https:\/\/zod.dev\/?id=safeparse\" rel=\"noopener noreferrer nofollow\">safeParse<\/a>, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0430. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043a\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>success<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 <code>data<\/code> \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u0441\u043f\u0435\u0445\u0430 \u0438 <code>error<\/code> \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0443\u0434\u0430\u0447\u0438. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u0441\u0435 \u044d\u0442\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 <code>success<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c <code>data<\/code>, \u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0443\u0434\u0430\u0447\u0438 \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c <code>error<\/code>.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0438\u0434\u0435\u043c \u0432 <code>index.ts<\/code> \u0438 \u0443\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0441\u0435 \u043b\u0438\u0448\u043d\u0435\u0435, \u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u044b (\u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0440\u0430\u043d\u0435\u0435 \u043c\u044b \u0443\u0434\u0430\u043b\u0438\u043b\u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u044b) \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b <code>CONFIG<\/code>, \u043c\u044b \u0435\u0433\u043e \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c:<\/p>\n<pre><code class=\"typescript\">import { buildEnvProxy } from '.\/buildEnvProxy.ts'; import { parseConfig } from '.\/config.schema.ts';  const ENV = buildEnvProxy&lt;Record&lt;string, unknown>>(   import.meta.env,   (key) => `VITE_${key}`, );  export const CONFIG = parseConfig(ENV);  export type Config = typeof CONFIG;<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 <code>CONFIG<\/code> \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u043d \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u043c\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u0430 \u0435\u0441\u043b\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0430, Zod \u0441\u043a\u0430\u0436\u0435\u0442 \u043e\u0431 \u044d\u0442\u043e\u043c \u0435\u0449\u0435 \u0434\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f97\/4e5\/c13\/f974e5c132e1417fd32a8861da27fa53.png\" width=\"2880\" height=\"1800\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f97\/4e5\/c13\/f974e5c132e1417fd32a8861da27fa53.png\"\/><\/figure>\n<p>\u0418 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443. \u0410 \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0431\u0435\u043b\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u043e\u043d\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u0430\u0436\u0435 \u043d\u0435 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u0430\u043b\u0430\u0441\u044c! \u0412 \u043e\u0448\u0438\u0431\u043a\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 <code>APP_VERSION<\/code> \u0438 <code>SHOW_VERSION<\/code> \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c <code>number<\/code> \u0438 <code>boolean<\/code> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043d\u043e \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 <code>string<\/code>. \u0422\u0430\u043a \u0438 \u0435\u0441\u0442\u044c, \u043a\u0430\u043a \u043f\u043e\u043c\u043d\u0438\u0442\u0435 \u0432\u0441\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 <em>.env<\/em> \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u0441\u0442\u0440\u043e\u043a, \u0438 Zod \u0438\u043c\u0435\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e. \u042f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0441\u044c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c &#171;\u043f\u0440\u0438\u043d\u0443\u0436\u0434\u0435\u043d\u0438\u0435&#187; \u2014 <code>.coerce<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0434\u0435\u043b\u043e \u0441 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u0430\u043c\u0438 (\u0441\u0435\u0439\u0447\u0430\u0441 \u043e\u0431\u044a\u044f\u0441\u043d\u044e):<\/p>\n<pre><code class=\"typescript\">const configSchema = z.object({   APP_TITLE: z.string(),   APP_VERSION: z.coerce.number(),   SHOW_VERSION: z.coerce.boolean(), });<\/code><\/pre>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0445\u0435\u043c\u0435 \u043a\u0430\u043a \u0431\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u0441\u044f &#171;\u0432\u043e\u0437\u044c\u043c\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>APP_VERSION<\/code> \u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0438 \u0435\u0435 \u043a \u0442\u0438\u043f\u0443 <code>number<\/code>&#171;. \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0438 \u0441 <code>SHOW_VERSION<\/code>. \u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043a \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c\u0443 \u0442\u0438\u043f\u0443 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043d\u0435\u0443\u0434\u0430\u0447\u043d\u043e \u2014 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/679\/207\/003\/679207003f69b9a9d2e0cdbafa45d8ab.png\" width=\"2328\" height=\"1584\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/679\/207\/003\/679207003f69b9a9d2e0cdbafa45d8ab.png\"\/><\/figure>\n<p>\u0412\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043e\u0442\u043b\u0438\u0447\u043d\u043e. \u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c <code>APP_VERSION<\/code> \u043d\u0430 <strong>1,0<\/strong> \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 <code>number<\/code>, \u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f <code>NaN<\/code> (\u0434\u0430, \u044f \u0437\u043d\u0430\u044e, \u043d\u043e \u0432\u043e\u0442 \u0442\u0430\u043a \u2014 \u0445\u043e\u0440\u043e\u0448\u043e \u0436\u0435!). \u0415\u0441\u043b\u0438 \u0437\u0430\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 \u043a\u0430\u043a\u0443\u044e-\u043b\u0438\u0431\u043e \u0438\u0437 \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u0432 \u0441\u0445\u0435\u043c\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u2014 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443, \u043d\u043e \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u0448\u043b\u043e <code>undefined<\/code>.<\/p>\n<p>\u0412\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043a\u0430\u043a \u043d\u0430\u0434\u043e \u0438 <strong>Zod<\/strong> \u0443\u0436\u0435 \u0437\u0430\u043a\u0440\u044b\u043b \u0432\u0441\u0435 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u0438. \u041d\u0430\u043a\u043e\u043d\u0435\u0446 \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>COMMENTED_REQUIRED_VALUE<\/code>. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435:<\/p>\n<pre><code class=\"typescript\">Array&lt;{   solution: string;   rate: 'A' | 'B'; }><\/code><\/pre>\n<p>\u0421\u0440\u0430\u0437\u0443 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 JSON, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043f\u0438\u0448\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"bash\">VITE_APP_TITLE=\"My app\" VITE_APP_VERSION=1 VITE_SHOW_VERSION=true VITE_COMMENTED_REQUIRED_VALUE='[{\"solution\":\"v1\",\"rate\":\"A\"},{\"solution\":\"v0\",\"rate\":\"B\"}]'<\/code><\/pre>\n<p>\u0418 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u0441\u0445\u0435\u043c\u0435. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c, \u043a\u0430\u043a \u0446\u0435\u043f\u043e\u0447\u043a\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439.<\/p>\n<p>\u0410\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0442\u043e\u0447\u043d\u043e, \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>.string()<\/code>. \u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0432\u0430\u043b\u0438\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u043e\u043d\u0430 \u0442\u0430\u043a\u0436\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c JSON-\u0444\u043e\u0440\u043c\u0430\u0442\u043e\u043c. \u0423 Zod \u043d\u0435\u0442 \u0440\u0435\u0448\u0435\u043d\u0438\u044f &#171;\u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438&#187; \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0434\u043b\u044f JSON, \u043d\u043e \u0437\u0430\u0442\u043e \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>.transform()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0438\u043c\u0435\u0435\u0442 \u043d\u0430\u0448\u0435 \u0434\u043e\u0448\u0435\u0434\u0448\u0435\u0435 \u043a \u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0430\u043b\u0438\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443. \u042d\u0442\u0443 \u0441\u0442\u0440\u043e\u043a\u0443 \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c, \u043a\u0430\u043a JSON \u2014 \u044d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f <code>.transform((value) => JSON.parse(value))<\/code>. \u0410 \u0434\u0430\u043b\u044c\u0448\u0435 \u0432\u0441\u0435, \u043a\u0430\u043a \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u043e \u0441\u0445\u0435\u043c\u043e\u0439 \u0441\u0430\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0430: <code>.object(...)<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <code>solution<\/code> \u0438 <code>rate<\/code>. \u041d\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430\u0434 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>.transform()<\/code> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044c \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u043e\u043c <code>.pipe()<\/code>, \u0442\u043e \u0435\u0441\u0442\u044c \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u0442\u044c &#171;\u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d&#187; \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438.<\/p>\n<p>\u0418 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432\u0441\u0435 \u0442\u0430\u043a\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u0441\u043b\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 <code>.object()<\/code> \u043c\u0435\u0442\u043e\u0434 <code>.array()<\/code>: <code>.object(...).array()<\/code>. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c:<\/p>\n<pre><code class=\"typescript\">... COMMENTED_REQUIRED_VALUE: z     .string() \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443     .transform((val) => JSON.parse(val)) \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0432 JSON     .pipe( \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \"\u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\"       z         .object({ \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442           solution: z.string(),           rate: z.enum(['A', 'B']),         })         .array(), \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432     ), ...<\/code><\/pre>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u0441\u044f \u0440\u0430\u043d\u0435\u0435 \u2014 <code>.enum()<\/code>. \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0441\u0442\u0440\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043d\u044f\u0442\u044b \u043d\u0430 \u0432\u0445\u043e\u0434. \u041a\u0441\u0442\u0430\u0442\u0438, \u043f\u043e\u043c\u0438\u043c\u043e \u0442\u0430\u043a\u0438\u0445 &#171;enum&#8217;\u043e\u0432&#187;, Zod \u0443\u043c\u0435\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c\u0438 <code>enum<\/code>.<\/p>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 \u0441\u043b\u0435\u0433\u043a\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c:<\/p>\n<pre><code class=\"typescript\">import { CONFIG } from '.\/config';  export const App = () => {   return (     &lt;>       &lt;h1>         {CONFIG.SHOW_VERSION &amp;&amp; (           &lt;>             {CONFIG.APP_TITLE} v{CONFIG.APP_VERSION.toFixed(1)}           &lt;\/>         )}       &lt;\/h1>       {CONFIG.COMMENTED_REQUIRED_VALUE.map(({ solution, rate }) => (         &lt;div>           Solution {solution} \u2014 {rate}         &lt;\/div>       ))}     &lt;\/>   ); };<\/code><\/pre>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/847\/d73\/55b\/847d7355bd886de1f7845c10ef24c1b4.png\" width=\"2328\" height=\"1584\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/847\/d73\/55b\/847d7355bd886de1f7845c10ef24c1b4.png\"\/><\/figure>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b, \u043f\u043e\u0441\u0432\u044f\u0449\u0435\u043d\u043d\u044b\u0439 \u2728 <strong>\u043e\u0442\u043b\u0438\u0447\u043d\u043e\u043c\u0443<\/strong> \u2728 \u0440\u0435\u0448\u0435\u043d\u0438\u044e \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u0430\u043a \u0438 \u0441\u0442\u0430\u0442\u044c\u044f.<br \/>\u041a\u0430\u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438 \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 \u043a\u043e\u043d\u0444\u0438\u0433, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0441\u0430\u043c\u044b\u0435 \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0443\u0434\u043e\u0431\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0438, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0438 \u043f\u043e\u043d\u044f\u0442\u043d\u0443\u044e \u043e\u0448\u0438\u0431\u043a\u0443.<\/p>\n<p>\u0411\u043e\u043b\u044c\u0448\u0438\u043c \u043f\u043b\u044e\u0441\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0439: \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0435\u043a\u0442 Vite \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>buildEnvProxy<\/code>, \u043a\u0443\u0434\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0438 <code>transformKey<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 <code>_VITE<\/code>; \u0435\u0441\u043b\u0438 \u0432\u0434\u0440\u0443\u0433 \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 Webpack, \u0442\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043d\u043e\u0432\u044b\u0439 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0438 \u0443\u0431\u0440\u0430\u0442\u044c <code>transformKey<\/code>. \u0410 \u0432\u043e\u0442 \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e:<\/p>\n<pre><code class=\"typescript\">export const buildEnvProxy = &lt;T extends Record&lt;string, unknown>>(   envSources: {     source: Partial&lt;T>;     transformKey?: (key: string) => string;   }[], ) =>   new Proxy({} as T, {     get(_, key) {       return envSources         .map(({ source, transformKey }) => {           const keyStr = String(key);           const envKey = transformKey ? transformKey(keyStr) : keyStr;            return source[envKey];         })         .find((v) => v !== undefined);     },   });<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u043b\u0438 \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c <code>transformKey<\/code> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445. Handler <code>get<\/code> \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u043e \u0432\u0441\u0435\u0445 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u0445, \u0430 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u0438 \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442.<\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0441\u043e \u043c\u043d\u043e\u0439 \u0441\u043e\u043b\u0438\u0434\u0430\u0440\u043d\u043e, \u043d\u043e \u0431\u0443\u0434\u0443 \u0440\u0430\u0434 \u043e\u0431\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u044e \u0442\u0435\u0445 \u0438\u043b\u0438 \u0438\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c \u043f\u043e \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044e \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u0447\u0442\u043e, \u0437\u0430\u0434\u0430\u0447\u0430 \u043d\u0430 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433 \u043d\u0435 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442 \u0441\u0435\u0431\u044f \u0436\u0434\u0430\u0442\u044c \ud83d\ude42<\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0433\u0438\u0442\u0445\u0430\u0431 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u0441 \u043a\u0430\u0436\u0434\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c (\u0434\u0432\u0443\u043c\u044f) \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0442\u043a\u0435: <a href=\"https:\/\/github.com\/bodasooqa\/vite-react-config-validation\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/bodasooqa\/vite-react-config-validation<\/a><\/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\/743798\/\"> https:\/\/habr.com\/ru\/articles\/743798\/<\/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>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041d\u0435\u0440\u0435\u0434\u043a\u043e \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u0432\u043e\u0434\u0438\u0442\u044c <strong>\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f (environment variables)<\/strong>. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043d\u043e\u0433\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e &#171;inline&#187;, \u043a\u0430\u043a <code>MY_VAR=\"my value\" node index.js<\/code> \u0438\u043b\u0438 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u0442\u044c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439 <code>source<\/code>. \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u0438\u043c\u0435\u044e\u0442 \u0434\u0430\u0436\u0435 \u0446\u0435\u043b\u044b\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043f\u0430\u043a\u0435\u0442\u044b \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f (\u043f\u0440\u0438\u043c. <a href=\"https:\/\/docs.nestjs.com\/techniques\/configuration\" rel=\"noopener noreferrer nofollow\">nest.js<\/a>). \u041d\u043e \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0437\u0430 \u0433\u043e\u0434\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0432 \u0441\u0444\u0435\u0440\u0435 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043c\u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 <strong>.env<\/strong> \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u0422\u0430\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u0438\u043c\u0435\u044e\u0442 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0438\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0432\u0438\u0434\u0430 <code>KEY=VALUE<\/code>:<\/p>\n<pre><code class=\"bash\"># .env  APP_TITLE=\"My application\" PORT=3000<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0447\u0435\u0433\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0443\u0436\u043d\u044b \u044d\u0442\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 \u043a\u0430\u043a\u043e\u0433\u043e \u0440\u043e\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043d\u0438\u0445 \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c? \u041e\u0442\u0432\u0435\u0442:<\/p>\n<ul>\n<li>\n<p>\u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u0441\u0435\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438. <br \/>\u041f\u0440\u0438\u043c\u0435\u0440: <code>KEY_SECRET<\/code> \u043e\u0442 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e API \u0438\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0411\u0414;<\/p>\n<\/li>\n<li>\n<p>\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0440\u0435\u0436\u0438\u043c\u043e\u0432 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041f\u0440\u0438\u043c\u0435\u0440: <code>BASE_URL<\/code> \u0434\u043b\u044f:<\/p>\n<ul>\n<li>\n<p>dev-\u0441\u0442\u0435\u043d\u0434\u0430 \u2014 <em>https:\/\/<\/em><strong><em>dev<\/em><\/strong><em>.my-amazing-resource.com<\/em> <\/p>\n<\/li>\n<li>\n<p>test-\u0441\u0442\u0435\u043d\u0434\u0430 \u2014 <em>https:\/\/<\/em><strong><em>stage<\/em><\/strong><em>.my-amazing-resource.com<\/em> <\/p>\n<\/li>\n<li>\n<p>production \u2014 <em>https:\/\/my-amazing-resource.com<\/em><\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p>\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0438\u043b\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b. \u041f\u0440\u0438\u043c\u0435\u0440: <code>PORT<\/code>, <code>PROXY_URL<\/code>, <code>FEATURE_TOGGLE<\/code> \u0438 \u0442.\u0434.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043a\u0440\u044b\u0442\u044b \u043e\u0442 \u0447\u0443\u0436\u0438\u0445 \u0433\u043b\u0430\u0437 \u0438 \u043c\u043e\u0433\u0443\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 (\u0438 \u0432\u043d\u0435) \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0435\u0436\u0438\u043c\u0430 \u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b. \u0423\u0434\u043e\u0431\u043d\u043e!<\/p>\n<h2>\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/h2>\n<p>\u0410 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 env-\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043d\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u043d\u0430\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u043d\u0435 \u0434\u0430\u0435\u0442 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043e \u0435\u0433\u043e \u0442\u0438\u043f\u0435 \u0434\u0430\u043d\u043d\u044b\u0445. \u0412\u0437\u0433\u043b\u044f\u043d\u0438\u0442\u0435 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u043d\u0444\u0438\u0433:<\/p>\n<pre><code class=\"bash\"># .env  APP_TITLE=\"My app\" APP_VERSION=1 SHOW_VERSION=true # COMMENTED_REQUIRED_VALUE=<\/code><\/pre>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e <code>APP_TITLE<\/code>, <code>APP_VERSION<\/code> \u0438 <code>SHOW_VERSION<\/code> \u2014 \u044d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430, \u0447\u0438\u0441\u043b\u043e \u0438 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0436\u0435 \u0434\u0435\u043b\u0435 \u0412\u0421\u0415 \u044d\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438.<\/p>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u0437\u0430\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <code>COMMENTED_REQUIRED_VALUE<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435\u0441\u043f\u0440\u043e\u0441\u0442\u0430 \u043d\u0430\u0437\u0432\u0430\u043d\u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a. \u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0431\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>\u0427\u0442\u043e \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043f\u043e \u0438\u0442\u043e\u0433\u0443:<\/p>\n<ol>\n<li>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0437\u0430\u0434\u0443\u043c\u0430\u043d\u043d\u044b\u043c \u0438\u043c \u0442\u0438\u043f\u0430\u043c \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0438\u0445 \u043a \u044d\u0442\u0438\u043c \u0442\u0438\u043f\u0430\u043c:<\/p>\n<ul>\n<li>\n<p><code>const title = process.env.APP_TITLE; \/\/ all is ok<\/code><\/p>\n<\/li>\n<li>\n<p><code>const version = Number(process.env.APP_VERSION);<\/code><\/p>\n<\/li>\n<li>\n<p><code>const showVersion = JSON.parse(process.env.SHOW_VERSION);<\/code><\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043b\u043e\u043c\u0430\u0442\u044c \u0441\u0430\u043c\u0430\u044f \u043c\u0430\u043b\u0430\u044f \u043e\u043f\u0435\u0447\u0430\u0442\u043a\u0430 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>False<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>false<\/code> \u0438\u043b\u0438 <code>1,0<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>1<\/code>. \u0421\u0442\u043e\u0438\u0442 \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c \u043d\u0430 \u0441\u0447\u0435\u0442 \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0438 \u043f\u0440\u043e\u0447\u0435\u043c.<\/p>\n<\/li>\n<li>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a <em>.env<\/em> \u043d\u0435 \u0434\u0430\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043c\u044b, \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>COMMENTED_REQUIRED_VALUE<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u0430, \u041d\u041e \u043f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u0430\u0441\u044c \u0437\u0430\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443. \u041e\u043a\u0435\u0439, \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0449\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u043d\u0430\u043b\u0438\u0447\u0438\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u043e\u0432, \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0442\u0438\u043f\u043e\u0432.<\/p>\n<\/li>\n<\/ol>\n<p><s>\u0414\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u043e\u0432, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438, \u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u0434&#8230;<\/s><\/p>\n<p>\u041d\u0435\u0442.<\/p>\n<h2>\u0420\u0435\u0448\u0435\u043d\u0438\u0435 v0<\/h2>\n<p>\u041d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430, \u0432\u044b \u0443\u0436\u0435 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u0434\u0443\u043c\u0430\u043b\u0438, \u0447\u0442\u043e \u0431\u044b\u043b\u043e \u0434\u0430\u043b\u044c\u0448\u0435. \u0422\u0430\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c-\u0442\u043e \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u0438 \u0443\u0434\u043e\u0431\u043d\u043e. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u044c\u0448\u0435\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0430\u0441\u043f\u0435\u043a\u0442\u044b. \u0412 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u044f \u0445\u043e\u0447\u0443 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c ? \u0445\u043e\u0440\u043e\u0448\u0435\u0435 ? \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0438 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u0441\u0430\u043c \u043f\u043e\u0434\u0445\u043e\u0434, \u0430 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0435\u0433\u043e &#171;\u0434\u043e\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0439 \u0434\u043e \u0443\u043c\u0430&#187; \u0432\u0435\u0440\u0441\u0438\u0438 \u2014 \u2728 <strong>\u043e\u0442\u043b\u0438\u0447\u043d\u043e\u043c <\/strong>\u2728 \u0440\u0435\u0448\u0435\u043d\u0438\u0438.<\/p>\n<p>\u0417\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u0431\u0443\u0434\u0435\u0442 \u0432\u0437\u044f\u0442 \u043f\u0440\u043e\u0435\u043a\u0442, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 <a href=\"https:\/\/vitejs.dev\" rel=\"noopener noreferrer nofollow\">Vite<\/a> \u043f\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0443 <code>react-swc-ts<\/code>, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 <a href=\"https:\/\/react.dev\" rel=\"noopener noreferrer nofollow\">React<\/a> + <a href=\"https:\/\/swc.rs\" rel=\"noopener noreferrer nofollow\">SWC<\/a> + <a href=\"https:\/\/www.typescriptlang.org\" rel=\"noopener noreferrer nofollow\">TypeScript<\/a>. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u044d\u0442\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043a \u043b\u044e\u0431\u043e\u043c\u0443 \u0441\u0442\u0435\u043a\u0443. <\/p>\n<p><span class=\"habrahidden\">\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b prettier, \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b\u00a0\u043b\u0438\u043d\u0442\u0438\u043d\u0433, \u043e\u0442\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043b \u043a\u043e\u0434, \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b @types\/node, \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u043b package.json, \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u043b vite.config.ts. \u0422\u0435\u043f\u0435\u0440\u044c \u0445\u043e\u0440\u043e\u0448\u043e. \u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0443\u0433\u043b\u0443\u0431\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438 Vite \u0438\u043b\u0438 React, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u041d\u0415 \u0418\u041c\u0415\u042e\u0422 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u043a \u0434\u0435\u043b\u0443. \u0422\u043e\u043b\u044c\u043a\u043e \u0441\u0443\u0442\u044c.<\/span><\/p>\n<pre><code class=\"bash\">yarn dev # \u0438\u043b\u0438 vite<\/code><\/pre>\n<figure class=\"full-width\">\n<div><figcaption>\u0422\u0430\u043a\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/figcaption><\/div>\n<\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 &#171;\u043b\u0438\u0448\u043d\u0435\u0433\u043e \u0448\u0443\u043c\u0430&#187; \u044f \u0443\u0434\u0430\u043b\u044e \u0432\u0435\u0441\u044c \u043a\u043e\u0434, \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 Vite \u0438 \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a <code>h1<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0441\u043b\u0443\u0436\u0438\u0442 \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u044f \u0445\u043e\u0447\u0443 \u0438\u043c\u0435\u0442\u044c \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043a\u043e\u043d\u0444\u0438\u0433, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u0432\u044b\u0448\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0430, \u0442\u0430\u043a \u0447\u0442\u043e \u044f \u0441\u043e\u0437\u0434\u0430\u043c \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 <strong>.env<\/strong> \u0444\u0430\u0439\u043b:<\/p>\n<pre><code class=\"bash\">APP_TITLE=\"My app\" APP_VERSION=1 SHOW_VERSION=true # COMMENTED_REQUIRED_VALUE=<\/code><\/pre>\n<p>Vite \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u0432\u043e\u0435\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0441 <strong>.env<\/strong>. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 <a href=\"https:\/\/vitejs.dev\/guide\/env-and-mode.html\" rel=\"noopener noreferrer nofollow\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>, \u043d\u043e \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u043d\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0441 \u043f\u0440\u0435\u0438\u0444\u043a\u0441\u043e\u043c <code>VITE_<\/code>, \u0430 \u0432\u044b\u0437\u043e\u0432 \u044d\u0442\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0447\u0435\u0440\u0435\u0437 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 <code>import.meta.env<\/code>.<br \/>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u043e\u043d\u0444\u0438\u0433 \u0442\u0430\u043a\u043e\u0433\u043e \u0432\u0438\u0434\u0430:<\/p>\n<pre><code class=\"bash\">VITE_APP_TITLE=\"My app\" VITE_APP_VERSION=1 VITE_SHOW_VERSION=true # VITE_COMMENTED_REQUIRED_VALUE=<\/code><\/pre>\n<p>\u0418 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <code>VITE_APP_TITLE<\/code>, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0432 \u0435\u0435 \u0432\u043d\u0443\u0442\u0440\u044c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 <code>h1<\/code>, \u043f\u043e\u043b\u044c\u0437\u0443\u044f\u0441\u044c \u0438\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u044f\u0446\u0438\u0435\u0439 <em>JSX(TSX)<\/em>:<\/p>\n<pre><code class=\"typescript\">export const App = () => {   return &lt;h1>{import.meta.env.VITE_APP_TITLE}&lt;\/h1>; };<\/code><\/pre>\n<figure class=\"full-width\">\n<div><figcaption>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e! \u042d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041d\u043e \u0435\u0441\u043b\u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432 \u043a\u043e\u0434\u0435 \u043d\u0430 \u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 <code>import.meta.env<\/code>, \u0442\u043e \u0443\u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043e\u043d \u0432\u0440\u043e\u0434\u0435 \u043a\u0430\u043a \u0438 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0443\u0436\u043d\u044b\u0445 \u043d\u0430\u043c \u0441\u0432\u043e\u0439\u0441\u0442\u0432. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043b\u044e\u0431\u043e\u0435 \u0435\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e, \u043f\u043e\u043c\u0438\u043c\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 <code>BASE_URL<\/code>, <code>MODE<\/code>, <code>DEV<\/code>, <code>PROD<\/code>, <code>SSR<\/code>, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u0438\u043f\u0430 <code>any<\/code>.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 <a href=\"https:\/\/vitejs.dev\/guide\/env-and-mode.html#intellisense-for-typescript\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/a>, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 Vite. \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c <em>env.d.ts<\/em>, \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0435\u0433\u043e \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e <em>src<\/em> \u0438\u043b\u0438 \u043a\u0443\u0434\u0430 \u0432\u0430\u043c \u0443\u0433\u043e\u0434\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 <em>src\/types<\/em>:<\/p>\n<pre><code class=\"typescript\">\/\/\/ &lt;reference types=\"vite\/client\" \/>  interface ImportMetaEnv {   readonly VITE_APP_TITLE: string;   readonly VITE_APP_VERSION: number;   readonly VITE_SHOW_VERSION: boolean;   readonly VITE_COMMENTED_REQUIRED_VALUE: any; }  interface ImportMeta {   readonly env: ImportMetaEnv }<\/code><\/pre>\n<p>\u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0435\u043f\u043b\u043e\u0445\u043e, \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u0432 \u043c\u043e\u0434\u0443\u043b\u0435 \u0438 \u043e\u043f\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0438\u0445 \u0442\u0438\u043f\u044b \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041d\u043e \u0432\u043e\u043f\u0440\u043e\u0441 \u0441 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0435\u0439 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u043c. IDE \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f <code>VITE_APP_VERSION<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0442\u0438\u043f\u0430 <code>number<\/code>. \u041d\u043e \u043f\u043e \u0444\u0430\u043a\u0442\u0443, \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 <code>typeof<\/code>, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c <code>string<\/code>:<\/p>\n<figure class=\"full-width\"><\/figure>\n<figure class=\"full-width\"><\/figure>\n<p>\u0422\u0430\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442, \u0441\u043a\u043e\u0440\u0435\u0435, \u0441\u0431\u0438\u0442\u044c \u0441\u0442\u043e\u043b\u043a\u0443. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0444\u0430\u0439\u043b\u043e\u0432: \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 src \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e config, \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0434\u0432\u0430 <code>.ts<\/code> \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430:<\/p>\n<ul>\n<li>\n<p>index.ts<\/p>\n<\/li>\n<li>\n<p>buildEnvProxy.ts<\/p>\n<\/li>\n<\/ul>\n<p>buildEnvProxy.ts \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0432 \u0441\u0435\u0431\u0435 \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b: <em>source<\/em> \u2014 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0435\u0440\u0443\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f (\u043a\u0430\u043a \u0432\u044b \u043f\u043e\u043c\u043d\u0438\u0442\u0435, \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e <code>import.meta.env<\/code>) \u0438 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 <em>transformKey<\/em> \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447\u0438 (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445) \u043a\u043e\u043d\u0444\u0438\u0433\u0430, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. <\/p>\n<p>\u0421 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043d\u043e \u0437\u0430\u0447\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447\u0438? \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043c\u043d\u0435 \u0431\u044b \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0444\u0438\u043a\u0441 <code>VITE_<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0435\u0440\u0435\u0437 <code>Proxy<\/code> \u044f \u0431\u0443\u0434\u0443 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0435\u0433\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 <code>Proxy<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d handler \u2014 <code>get<\/code>. \u0415\u0433\u043e \u0438 \u043e\u043f\u0438\u0448\u0435\u043c.<\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043a\u043b\u044e\u0447 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0435 \u2014 \u044d\u0442\u043e <code>string | symbol<\/code>, \u0430 \u043d\u0430\u0448 \u043a\u043e\u043d\u0444\u0438\u0433, \u043f\u043e \u0438\u0434\u0435\u0435 \u2014 \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u0442\u0438\u043f\u0430 <code>Record&lt;string | unknown><\/code>, \u0433\u0434\u0435 \u043a\u043b\u044e\u0447 \u2014 \u044d\u0442\u043e <code>string<\/code>, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u044d\u0442\u043e\u0442 \u043a\u043b\u044e\u0447 \u043a \u0441\u0442\u0440\u043e\u043a\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>String<\/code>.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043a\u043b\u044e\u0447 \u0432 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u0438\u043c\u0435\u0435\u0442\u0441\u044f, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <em>transformKey<\/em> \u0438, \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u2014 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435. \u0412 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435 get \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 <em>source<\/em> \u043f\u043e \u043a\u043b\u044e\u0447\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u043a \u0441\u0442\u0440\u043e\u043a\u0435 \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <em>transformKey<\/em>:<\/p>\n<pre><code class=\"typescript\">\/\/ buildEnvProxy.ts  export const buildEnvProxy = &lt;T extends Record&lt;string, unknown>>(   source: T,   transformKey: (key: string) => string, ) =>   new Proxy({} as T, {     get(_, key) {       const keyStr = String(key);       const envKey = transformKey ? transformKey(keyStr) : keyStr;        return source[envKey];     },   });<\/code><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 <em>index.ts<\/em> \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 ENV \u0438 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u0435\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u0432\u044b\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0443\u043a\u0430\u0437\u0430\u0432 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 <em>generic<\/em> <code>Record&lt;string, unknown><\/code>, \u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432: \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u2014 <code>import.meta.env<\/code> \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043a \u043a\u043b\u044e\u0447\u0443 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u043f\u0440\u0435\u0444\u0438\u043a\u0441:<\/p>\n<pre><code class=\"typescript\">\/\/ index.ts  import { buildEnvProxy } from '.\/buildEnvProxy.ts';  const ENV = buildEnvProxy&lt;Record&lt;string, unknown>>(   import.meta.env,   (key) => `VITE_${key}`, );<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c:<\/p>\n<pre><code class=\"typescript\">console.log('Without prefix:', ENV.APP_TITLE); console.log('With prefix', ENV.VITE_APP_TITLE);<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0430. \u041f\u0435\u0440\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u0432 \u044d\u0442\u043e\u0439 \u0436\u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 <em>config.types.ts<\/em>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c <code>type Config<\/code> \u0441 \u0442\u0438\u043f\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439:<\/p>\n<pre><code class=\"typescript\">\/\/ config.types.ts  export type Config = {   APP_TITLE: string;   APP_VERSION: number;   SHOW_VERSION: boolean;   COMMENTED_REQUIRED_VALUE: any; };<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u043d\u0430 \u044d\u0442\u043e\u043c \u043c\u043e\u043c\u0435\u043d\u0442\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u043d\u0430 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 Vite, \u0442.\u043a. \u0442\u0438\u043f\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e\u0434 \u043a\u043e\u043d\u0444\u0438\u0433 \u0438\u043c\u0435\u0435\u0442\u0441\u044f, \u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442\u0441\u044f \u0438 \u043f\u043e \u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u0442\u0438\u043f\u0430 <code>string<\/code>. <\/p>\n<p>\u0414\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u0432\u043d\u0443\u0442\u0440\u0438 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 <em>config<\/em> \u0437\u0430\u0432\u043e\u0434\u0438\u043c \u043d\u043e\u0432\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e <em>configGetters<\/em>, \u0430 \u0432 \u043d\u0435\u0439 \u0442\u0440\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430, \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430:<\/p>\n<ul>\n<li>\n<p><em>getBoolean.ts<\/em><\/p>\n<\/li>\n<li>\n<p><em>getNumber.ts<\/em><\/p>\n<\/li>\n<li>\n<p><em>getString.ts<\/em><\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u0430\u043a \u0432\u044b \u0443\u0436\u0435 \u0434\u043e\u0433\u0430\u0434\u0430\u043b\u0438\u0441\u044c, \u044d\u0442\u0438 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0434\u043d\u043e\u0438\u043c\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0442\u0438\u043f\u0430\u043c \u0434\u0430\u043d\u043d\u044b\u0445 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445. \u0418\u043c\u0435\u043d\u043d\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435. <\/p>\n<pre><code class=\"typescript\">\/\/ getBoolean.ts  export const getBoolean = (   target: Record&lt;string, unknown>,   key: string, ): boolean => {   const value = target[key];    try {     if (value === 'true' || value === true) return true;     if (value === 'false' || value === false) return false;      throw new Error();   } catch {     throw new Error(`Config value for \"${key}\" is not a boolean: \"${value}\"`);   } };<\/code><\/pre>\n<pre><code class=\"typescript\">\/\/ getNumber.ts  export const getNumber = (   target: Record&lt;string, unknown>,   key: string, ): number => {   const value = target[key];    try {     const numValue = Number(value);      if (isFinite(numValue) &amp;&amp; !isNaN(numValue)) return numValue;      throw new Error();   } catch {     throw new Error(`Config value for \"${key}\" is not a number: \"${value}\"`);   } };<\/code><\/pre>\n<pre><code class=\"typescript\">\/\/ getString.ts  export const getString = (   target: Record&lt;string, unknown>,   key: string, ): string => {   const strValue = target[key];    try {<\/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-349637","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/349637","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=349637"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/349637\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=349637"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=349637"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=349637"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}