{"id":4364,"date":"2026-02-17T08:27:27","date_gmt":"2026-02-16T23:27:27","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=4364"},"modified":"2026-02-17T09:37:24","modified_gmt":"2026-02-17T00:37:24","slug":"vitereactexpress-server-client","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/02\/17\/vitereactexpress-server-client\/","title":{"rendered":"[Vite+React]Express \uc11c\ubc84 \uc5f0\ub3d9 \/ Integrating with an Express server(MacOS)"},"content":{"rendered":"\n<p>\u2b50\ufe0f  MacOS\uc5d0\uc11c \ud14c\uc2a4\ud2b8\ud588\uc9c0\ub9cc \ub2e4\ub978 \uc6b4\uc601\uccb4\uc81c\uc5d0\uc11c\ub3c4 \uc2e4\ud589\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<br>Tested on macOS, but should run on other operating systems as well.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udc49\ud83c\udffb 1. \ud504\ub85c\uc81d\ud2b8 \uad6c\uc870 \uc124\uc815 \/ Set up project structure<\/h3>\n\n\n\n<p>\u2714\ufe0f \uba3c\uc800 \uc804\uccb4\ub97c \uad00\ub9ac\ud560 \ub8e8\ud2b8 \ud3f4\ub354 \uc548\uc5d0 \ud074\ub77c\uc774\uc5b8\ud2b8\uc640 \uc11c\ubc84 \ud3f4\ub354\ub97c \ub098\ub215\ub2c8\ub2e4.<br>First, divide the client and server folders into the root folder that will manage the whole thing.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ReactExample5\/\n\u251c\u2500\u2500 client\/ (Vite + React)\n\u2514\u2500\u2500 server\/ (Express)<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udc49\ud83c\udffb 2. Express \uc11c\ubc84 \uc124\uc815 \/ Express Server Setup (Backend)<\/h3>\n\n\n\n<p>\u2714\ufe0f <code>server\/<\/code>\u00a0\ud3f4\ub354\uc5d0\uc11c Express\ub97c \uc124\uce58\ud558\uace0 \uac04\ub2e8\ud55c API\ub97c \ub9cc\ub4ed\ub2c8\ub2e4.<br>Install Express in the server\/ folder and create a simple API.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd server\nnpm init -y\nnpm install express<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f package.json<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"name\": \"server\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" &amp;&amp; exit 1\"\n  },\n  \"keywords\": &#91;],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"type\": \"commonjs\",\n  \"dependencies\": {\n    \"express\": \"^5.2.1\"\n  }\n}<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f server\/index.js<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const express = require('express');\nconst app = express();\nconst PORT = 3000;\n\napp.get('\/api\/data', (req, res) => {\n  res.json({ message: \"Hello from Express Server!\" });\n});\n\napp.listen(PORT, () => {\n  console.log(`Server is running on http:\/\/localhost:${PORT}`);\n});<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udc49\ud83c\udffb3. Vite + React\ud504\ub85c\uc81d\ud2b8 \uc124\uce58 \ubc0f \uc124\uc815  \/ Installing and Setting Up a Vite + React Project<\/h3>\n\n\n\n<p>\u2714\ufe0f \ud504\ub85c\uc81d\ud2b8 \uc124\uce58 \/ Project installation<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> % npm create vite@latest client --template react-ts<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f <code>client\/<\/code>\u00a0\ud3f4\ub354\uc5d0\uc11c Vite \ud504\ub85c\uc81d\ud2b8\ub97c \uc0dd\uc131\ud558\uace0,\u00a0<strong>\ud504\ub85d\uc2dc<\/strong>\u00a0\uc124\uc815\uc744 \ucd94\uac00\ud569\ub2c8\ub2e4. \uc774 \uc124\uc815\uc774 \ud575\uc2ec\uc785\ub2c8\ub2e4.<br>Create a Vite project in the client\/ folder and add proxy settings. These settings are key.<\/p>\n\n\n\n<p><strong><code>\u2714\ufe0f client\/vite.config.js<\/code><\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { defineConfig } from 'vite'\nimport react from '@vitejs\/plugin-react'\n\nexport default defineConfig({\n  plugins: &#91;react()],\n<mark style=\"background-color:rgba(0, 0, 0, 0);color:#6811aa\" class=\"has-inline-color\"><strong>  server: {\n    proxy: {\n      \/\/ '\/api'\ub85c \uc2dc\uc791\ud558\ub294 \uc694\uccad\uc744 \ubc31\uc5d4\ub4dc \uc11c\ubc84\ub85c \ubcf4\ub0c5\ub2c8\ub2e4.<\/strong>\n      <strong>\/\/ Send requests starting with '\/api' to the backend server.\n      '\/api': {\n        target: 'http:\/\/localhost:3000',\n        changeOrigin: true,\n      }\n    }\n  }<\/strong><\/mark>\n})<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udc49\ud83c\udffb 4. React\uc5d0\uc11c API \ud638\ucd9c\ud558\uae30 \/ Calling APIs in React<\/h3>\n\n\n\n<p>\u2714\ufe0f \uc774\uc81c \ud504\ub85d\uc2dc \uc124\uc815\uc744 \ub9c8\ucce4\uc73c\ubbc0\ub85c, React\uc5d0\uc11c\ub294 \uc804\uccb4 URL(<code>http:\/\/localhost:3000\/...<\/code>)\uc744 \uc801\uc744 \ud544\uc694 \uc5c6\uc774 \uc0c1\ub300 \uacbd\ub85c\ub9cc \uc801\uc73c\uba74 \ub429\ub2c8\ub2e4.<br>Now that we&#8217;ve set up our proxy settings, we can just write the relative path in React instead of the full URL (http:\/\/localhost:3000\/\u2026).<\/p>\n\n\n\n<p><strong><code>\u2714\ufe0f client\/src\/App.jsx<\/code><\/strong><\/p>\n\n\n\n<p>&#8212; useEffect() : <br>\ucef4\ud3ec\ub10c\ud2b8\uac00 \ube0c\ub77c\uc6b0\uc800 \ud654\uba74\uc5d0 \ucc98\uc74c \ub098\ud0c0\ub0a0 \ub54c(Mount)\u00a0<strong>\ub531 \ud55c \ubc88\ub9cc<\/strong>\u00a0\uc2e4\ud589\ud569\ub2c8\ub2e4.<br>It runs exactly once when the component first appears on the browser screen (Mount).<\/p>\n\n\n\n<p>&#8212; .then((data) => setMessage(data.message)) : <br>data\ub77c\ub294 \ub369\uc5b4\ub9ac \uc548\uc5d0\uc11c &#8216;message&#8217;\ub77c\ub294 \uc774\ub984\ud45c\uac00 \ubd99\uc740 \uac12\ub9cc \uac00\uc838\uc62c\uac8c&#8221;\ub77c\ub294 \ub73b\uc785\ub2c8\ub2e4.<br>It means I&#8217;ll just take the value labeled &#8216;message&#8217; from the data object.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import { useEffect, useState } from \"react\";\nimport \".\/AppStyle.css\";\n\nfunction App() {\n  const &#91;<strong><mark style=\"background-color:rgba(0, 0, 0, 0);color:#7818a1\" class=\"has-inline-color\">message<\/mark><\/strong>, <strong><mark style=\"background-color:rgba(0, 0, 0, 0);color:#841ea2\" class=\"has-inline-color\">setMessage<\/mark><\/strong>] = useState(\"\");\n\n  useEffect(() => {\n    \/\/ \ud504\ub85d\uc2dc \uc124\uc815 \ub355\ubd84\uc5d0 \/api\/... \ub85c \ubc14\ub85c \ud638\ucd9c \uac00\ub2a5\n    \/\/ Direct call to \/api\/... is possible due to proxy settings\n    fetch(\"\/api\/data\")\n      .then((res) => res.json())\n      .then((data) => <mark style=\"background-color:rgba(0, 0, 0, 0);color:#841ea2\" class=\"has-inline-color\"><strong>setMessage<\/strong><\/mark>(data.message))\n      .catch((err) => console.error(err));\n  }, &#91;]);\n\n  return (\n    &lt;div className=\"container\">\n      &lt;h3>Vite + Express \uc5f0\ub3d9 \ud14c\uc2a4\ud2b8 \/ Link test&lt;\/h3>\n      &lt;p>\uc11c\ubc84\uba54\uc138\uc9c0\/Server Message: {<mark style=\"background-color:rgba(0, 0, 0, 0);color:#7818a1\" class=\"has-inline-color\"><strong>message<\/strong><\/mark>}&lt;\/p>\n    &lt;\/div>\n  );\n}\n\nexport default App;<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f <strong><code>client\/src\/App<\/code>Style.css<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udc49\ud83c\udffb5. \uc2e4\ud589 \ubc29\ubc95 \/ How to run<\/h3>\n\n\n\n<p>\ub450 \uc11c\ubc84\ub97c \ub3d9\uc2dc\uc5d0 \ub744\uc6cc\uc57c \ud569\ub2c8\ub2e4. \uac01\uac01\uc758 \ud130\ubbf8\ub110\uc5d0\uc11c \ub2e4\uc74c \uba85\ub839\uc5b4\ub97c \uc785\ub825\ud558\uc138\uc694.<br>You need to launch both servers simultaneously. Enter the following commands in each terminal:<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li><strong>Backend:<\/strong>\u00a0<code>cd server &amp;&amp; node index.js<\/code><\/li>\n\n\n\n<li><strong>Frontend:<\/strong>\u00a0<code>cd client &amp;&amp; npm run dev<\/code><\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udc49\ud83c\udffb 6. \uc2a4\ud06c\ub9b0 \uc0f7 \/ ScreenShot<\/h3>\n\n\n\n<p>\u2714\ufe0f \ube0c\ub77c\uc6b0\uc800\uc5d0\uc11c http:\/\/localhost:5173\uc744 \uc2e4\ud589\ud569\ub2c8\ub2e4.<br>Go to http:\/\/localhost:5173 in your browser.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"978\" height=\"934\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/02\/ReactExample5.png\" alt=\"\" class=\"wp-image-4386\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/02\/ReactExample5.png 978w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/02\/ReactExample5-300x287.png 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/02\/ReactExample5-768x733.png 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/02\/ReactExample5-400x382.png 400w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/02\/ReactExample5-800x764.png 800w\" sizes=\"auto, (max-width: 978px) 100vw, 978px\" \/><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u2b50\ufe0f MacOS\uc5d0\uc11c \ud14c\uc2a4\ud2b8\ud588\uc9c0\ub9cc \ub2e4\ub978 \uc6b4\uc601\uccb4\uc81c\uc5d0\uc11c\ub3c4 \uc2e4\ud589\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.Tested on macOS, but should run on other operating systems as well. \ud83d\udc49\ud83c\udffb 1. \ud504\ub85c\uc81d\ud2b8 \uad6c\uc870 \uc124\uc815 \/ Set up project structure \u2714\ufe0f \uba3c\uc800 \uc804\uccb4\ub97c \uad00\ub9ac\ud560 \ub8e8\ud2b8 \ud3f4\ub354 \uc548\uc5d0 \ud074\ub77c\uc774\uc5b8\ud2b8\uc640 \uc11c\ubc84 \ud3f4\ub354\ub97c \ub098\ub215\ub2c8\ub2e4.First, divide the client and server folders into the root folder that will manage the whole [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21,1,7],"tags":[],"class_list":["post-4364","post","type-post","status-publish","format-standard","hentry","category-react","category-uncategorized","category-website","missing-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/4364","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=4364"}],"version-history":[{"count":43,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/4364\/revisions"}],"predecessor-version":[{"id":4409,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/4364\/revisions\/4409"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=4364"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=4364"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=4364"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}