<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>내 세상</title>
    <link>https://sga8.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Wed, 1 Jul 2026 07:58:51 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>sga8</managingEditor>
    <image>
      <title>내 세상</title>
      <url>https://tistory1.daumcdn.net/tistory/2986570/attach/04926ee89da84a5e90ecb2e8d34ff792</url>
      <link>https://sga8.tistory.com</link>
    </image>
    <item>
      <title>[React] CSS Button 테두리 효과 넣기</title>
      <link>https://sga8.tistory.com/251</link>
      <description>&lt;pre id=&quot;code_1759228374984&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.GaniButton.on {
  background: linear-gradient(to right, #38bdf8, #7dd3fc, #60a5fa);
  color: #fff;
}
.GaniButton.on::before {
  content:&quot;&quot;; // 입력필수
  position: absolute;
  top:-4px;left:-4px;right:-4px;bottom:-4px;
  background: red;
  background-size: 600% 600%;
  animation: ganiBorder 6s linear infinite;
}
.GaniButton.on::after {
  content:&quot;&quot;;
  position: absolute;
  top:2px;left:2px;right:2px;bottom:2px;
  z-index:-1;
  border-radius: 6px;
  background: blue;
}
@keyframes ganiBorder {
  0% {background-position: 0% 50%;}
  50% {background-position: 100% 50%;}
  100% {background-position: 0% 50%;}
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Technical/React</category>
      <author>sga8</author>
      <guid isPermaLink="true">https://sga8.tistory.com/251</guid>
      <comments>https://sga8.tistory.com/251#entry251comment</comments>
      <pubDate>Tue, 30 Sep 2025 19:33:15 +0900</pubDate>
    </item>
    <item>
      <title>[WebStorm] 중괄호 bracket 자동 완성 해제 하기</title>
      <link>https://sga8.tistory.com/248</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;# 방안 1&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;File &amp;rarr; Settings&amp;nbsp; &amp;rarr; Editor &amp;rarr; Code Style &amp;rarr; HTML&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Add for JSX attributes 를 None으로 변경&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;# 방안 2&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;b&gt;File &amp;rarr; Settings&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr; Editor&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr; General &lt;b&gt;&lt;b&gt;&amp;rarr; Smart Keys&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;insert paired brackets (), [], [}, &amp;lt;&amp;gt; 체크옵션 해제&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>Technical/etc</category>
      <category>bracket</category>
      <category>WebStorm</category>
      <category>중괄호</category>
      <category>해제</category>
      <author>sga8</author>
      <guid isPermaLink="true">https://sga8.tistory.com/248</guid>
      <comments>https://sga8.tistory.com/248#entry248comment</comments>
      <pubDate>Thu, 27 Feb 2025 10:57:26 +0900</pubDate>
    </item>
    <item>
      <title>[Spring Webflux][R2DBC] The server timezone is &amp;lt;????&amp;gt; that's unknown, trying to use system default timezone 조지기</title>
      <link>https://sga8.tistory.com/247</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Version 정보&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;org.springframework.boot 3.4.2&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;org.jetbrains.kotlin.jvm 1.9.25&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;org.jetbrains.kotlin.plugin.spring 1.9.25&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;implementation(&quot;org.springframework.boot:spring-boot-starter-data-r2dbc&quot;) &lt;br /&gt;implementation(&lt;b&gt;&quot;dev.miku:r2dbc-mysql:0.8.2.RELEASE&quot;&lt;/b&gt;) &lt;br /&gt;implementation(&quot;org.springframework.boot:spring-boot-starter-webflux&quot;) &lt;br /&gt;implementation(&quot;com.fasterxml.jackson.module:jackson-module-kotlin&quot;) &lt;br /&gt;implementation(&quot;io.projectreactor.kotlin:reactor-kotlin-extensions&quot;) &lt;br /&gt;implementation(&quot;org.jetbrains.kotlin:kotlin-reflect&quot;) &lt;br /&gt;implementation(&quot;org.jetbrains.kotlinx:kotlinx-coroutines-reactor&quot;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제점&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;에러 로그&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1740556208542&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;The server timezone is &amp;lt;???ѹ&amp;alpha;? ǥ?ؽ&amp;gt; that's unknown, trying to use system default timezone&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;&lt;i&gt;&lt;b&gt;ChatGPT에게 도움을 구하면 헛소리만 함.&amp;nbsp;&lt;/b&gt;&lt;/i&gt;&lt;/u&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적인&amp;nbsp;생각으로&amp;nbsp;dev.miku:r2dbc-mysql의&amp;nbsp;유지보수가&amp;nbsp;20년도가&amp;nbsp;마지막이라,&amp;nbsp;패키지&amp;nbsp;자체에&amp;nbsp;문제가&amp;nbsp;있을&amp;nbsp;것이라&amp;nbsp;생각함. &lt;br /&gt;대안으로,&amp;nbsp;io.asyncer:r2dbc-mysql을&amp;nbsp;사용하는&amp;nbsp;방법이&amp;nbsp;있음.&amp;nbsp;최근까지&amp;nbsp;유지보수가&amp;nbsp;되고,&amp;nbsp;심적으로&amp;nbsp;안정됨. &lt;br /&gt;링크:&amp;nbsp;&lt;a href=&quot;https://github.com/asyncer-io/r2dbc-mysql&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/asyncer-io/r2dbc-mysql&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래&amp;nbsp;버전을&amp;nbsp;참고해서&amp;nbsp;사용하면&amp;nbsp;됨.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 93.6047%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 47.2093%; text-align: center;&quot;&gt;&lt;b&gt;spring boot&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 46.3954%; text-align: center;&quot;&gt;&lt;b&gt;io.asyncer:r2dbc-mysql&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 47.2093%; text-align: center;&quot;&gt;3.0.* and above&lt;/td&gt;
&lt;td style=&quot;width: 46.3954%; text-align: center;&quot;&gt;io.asyncer:r2dbc-mysql:1.4.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 47.2093%; text-align: center;&quot;&gt;2.7.*&lt;/td&gt;
&lt;td style=&quot;width: 46.3954%; text-align: center;&quot;&gt;io.asyncer:r2dbc-mysql:0.9.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 47.2093%; text-align: center;&quot;&gt;2.6.* and below&lt;/td&gt;
&lt;td style=&quot;width: 46.3954%; text-align: center;&quot;&gt;io.asyncer:r2dbc-mysql:0.8.2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만,&amp;nbsp;사내&amp;nbsp;방화벽으로&amp;nbsp;인해&amp;nbsp;io.asyncer:r2dbc-mysql의&amp;nbsp;사용이&amp;nbsp;어려웠고 &lt;br /&gt;dev.miku:r2dbc-mysql에서&amp;nbsp;발생하는&amp;nbsp;문제를&amp;nbsp;해결함.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;해결책&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;serverZoneId를&amp;nbsp;입력하여&amp;nbsp;해당&amp;nbsp;문제를&amp;nbsp;해결할&amp;nbsp;수&amp;nbsp;있음.&lt;/p&gt;
&lt;pre id=&quot;code_1740556613053&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring:
  main:
    web-application-type: reactive
  application:
    name: test_app
  r2dbc:
    url: r2dbc:mysql://12.23.34.56:1000/?serverZoneId=UTC
    username: sga8
    password: sga8!&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Technical/Spring</category>
      <category>dev.miku:r2dbc-mysql</category>
      <category>io.asyncer:r2dbc-mysql</category>
      <category>r2dbc</category>
      <category>r2dbc-mysql</category>
      <category>the server timezone</category>
      <author>sga8</author>
      <guid isPermaLink="true">https://sga8.tistory.com/247</guid>
      <comments>https://sga8.tistory.com/247#entry247comment</comments>
      <pubDate>Wed, 26 Feb 2025 16:59:09 +0900</pubDate>
    </item>
    <item>
      <title>[React] React-leaflet rectangle gradient 적용 방법</title>
      <link>https://sga8.tistory.com/246</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;React-Leafet&amp;nbsp;사용&amp;nbsp;시,&amp;nbsp;동적인&amp;nbsp;정보를&amp;nbsp;보여주기&amp;nbsp;위해&amp;nbsp;Rectangle을&amp;nbsp;Customize해서&amp;nbsp;사용하고&amp;nbsp;있음. &lt;br /&gt;다만,&amp;nbsp;Rectangle은&amp;nbsp;SVG&amp;nbsp;요소이기&amp;nbsp;때문에,&amp;nbsp;fillColor를&amp;nbsp;Gradient로&amp;nbsp;사용이&amp;nbsp;불가하고&amp;nbsp;단색으로만&amp;nbsp;가능함. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;하지만,&amp;nbsp;svg&amp;nbsp;defs&amp;nbsp;선언을&amp;nbsp;통해서&amp;nbsp;SVG&amp;nbsp;요소에도&amp;nbsp;Gradient를&amp;nbsp;적용할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;방안을&amp;nbsp;발견&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MapContainer&amp;nbsp;내부에&amp;nbsp;svg-defs를&amp;nbsp;통해&amp;nbsp;먼저&amp;nbsp;linearGradient를&amp;nbsp;먼저&amp;nbsp;설정한다. &lt;br /&gt;그리고&amp;nbsp;Rectangle이나&amp;nbsp;SVG&amp;nbsp;요소에서&amp;nbsp;fillColor를&amp;nbsp;'url(#grad-RED)'&amp;nbsp;와&amp;nbsp;같은&amp;nbsp;형식으로&amp;nbsp;사용하면&amp;nbsp;됨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1736389892309&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const MyContainer = memo(
  ({ onMove, mapCenter, mapZoom, showDialogWithData, mapMarkers }) =&amp;gt; {
    ....

    const addGradient = () =&amp;gt; {
      const colorToGradient = [&quot;RED&quot;, &quot;BLUE&quot;, &quot;GREY&quot;];
      return colorToGradient.map((item) =&amp;gt; {
        const { start, end } = getGradientColors(item)
        return (
          &amp;lt;linearGradient
            id={`grad-${item}`}
            x1=&quot;0%&quot;
            y1=&quot;0%&quot;
            x2=&quot;100%&quot;
            y2=&quot;100%&quot;
            key={item}
          &amp;gt;
            &amp;lt;stop offset=&quot;0%&quot; stopColor={start} /&amp;gt;
            &amp;lt;stop offset=&quot;100%&quot; stopColor={end} /&amp;gt;
          &amp;lt;/linearGradient&amp;gt;
        )
      })
    }


    _.forEach(mapMarkers, (elem) =&amp;gt; {
      ...
    })

    L.CRS.MyCRS = L.extend({}, L.CRS.Simple, {
      transformation: new L.Transformation(1, 0, 1, 0), // ax+b, cy+d
    })
    return (
      &amp;lt;MapContainer
        center={mapCenter}
        zoom={mapZoom}
        zoomControl={false}
        attributionControl={false}
        maxBounds={boundsMap}
        style={{ height: '100%', fontFamily: 'IBM Plex Sans', fontWeight: 500 }}
        crs={L.CRS.MyCRS}
        maxZoom={10}
        id=&quot;map&quot;
        ref={mapRef}
      &amp;gt;
        &amp;lt;svg&amp;gt;
          &amp;lt;defs&amp;gt;{addGradient()}&amp;lt;/defs&amp;gt;
        &amp;lt;/svg&amp;gt;
        &amp;lt;Marker icon={icon} position={{ lat: 0, lng: 0 }}&amp;gt;&amp;lt;/Marker&amp;gt;
        &amp;lt;Marker icon={icon} position={{ lat: 0, lng: 1980 }}&amp;gt;&amp;lt;/Marker&amp;gt;
        &amp;lt;Marker icon={icon} position={{ lat: 360, lng: 0 }}&amp;gt;&amp;lt;/Marker&amp;gt;
        &amp;lt;Rectangle
          bounds ={[[100,0],[10,100]]}
          pathOptions ={{fillColor: 'url(#grad-RED)'}} /&amp;gt;
      &amp;lt;/MapContainer&amp;gt;
    )
  }
)&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Technical/React</category>
      <category>defs</category>
      <category>gradient</category>
      <category>gradient color</category>
      <category>leaflet</category>
      <category>REACT</category>
      <category>react-leaflet</category>
      <category>SVG</category>
      <author>sga8</author>
      <guid isPermaLink="true">https://sga8.tistory.com/246</guid>
      <comments>https://sga8.tistory.com/246#entry246comment</comments>
      <pubDate>Thu, 9 Jan 2025 11:33:23 +0900</pubDate>
    </item>
    <item>
      <title>[React] React-Select 메뉴 클릭 시, 드롭다운 메뉴 뒤 클릭 이슈</title>
      <link>https://sga8.tistory.com/245</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;react-select를&amp;nbsp;사용해서&amp;nbsp;Select를&amp;nbsp;구현할&amp;nbsp;때,&amp;nbsp;드롭다운&amp;nbsp;메뉴&amp;nbsp;클릭&amp;nbsp;시&amp;nbsp;뒤에&amp;nbsp;있는&amp;nbsp;다른&amp;nbsp;부분이&amp;nbsp;선택되는&amp;nbsp;이슈 &lt;br /&gt;아래&amp;nbsp;예시는&amp;nbsp;Select&amp;nbsp;드롭다운&amp;nbsp;메뉴&amp;nbsp;뒤에&amp;nbsp;CheckBox가&amp;nbsp;있어서&amp;nbsp;드롭다운&amp;nbsp;메뉴&amp;nbsp;중&amp;nbsp;하나&amp;nbsp;선택&amp;nbsp;시,&amp;nbsp;뒤쪽&amp;nbsp;CheckBox가&amp;nbsp;선택되는&amp;nbsp;이슈임. &lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. &lt;b&gt;menuPortalTarget 설정 (react-select 전용)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;react-select에서는 드롭다운 메뉴가 별도의 포탈로 렌더링되기 때문에 menuPortalTarget 속성을 document.body로 설정하면 문제를 해결할 수 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1736210501043&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Select
  value={this.state.temp1}
  options={this.state.temp1List}
  onChange={e =&amp;gt; this.setState({ temp1: e })}
  menuPortalTarget={document.body} // 포탈을 body에 렌더링
  styles={{
    menuPortal: base =&amp;gt; ({ ...base, zIndex: 9999 }), // z-index 설정
  }}
/&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 드롭다운 메뉴가 항상 최상단에 렌더링되어 뒤에 있는 CheckBox와의 충돌을 방지할 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;AS-IS&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1736210340130&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;div&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;Select
      value={this.state.temp1}
      options={this.state.temp1List}
      onChange={e =&amp;gt;
        this.setState({ temp1: e })
      }  
    /&amp;gt;
  &amp;lt;/div&amp;gt;

  &amp;lt;div&amp;gt;
    &amp;lt;FormLabel&amp;gt;Status&amp;lt;/FormLabel&amp;gt;
    &amp;lt;FormGroup row&amp;gt;
      &amp;lt;FormControlLabel
        control={
          &amp;lt;CheckBox
            checked={this.state.test1}
            onChange={this.handleChkBox(&quot;Test1&quot;)}
            color=&quot;primary&quot;
          /&amp;gt;
        }
        label={consts.BABO}
      /&amp;gt;
    &amp;lt;/FormGroup&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;TO-BE&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1736210364594&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;div&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;Select
      value={this.state.temp1}
      options={this.state.temp1List}
      onChange={e =&amp;gt;
        this.setState({ temp1: e })
      }  
      menuPortalTarget={document.body} // 포탈을 body에 렌더링
      styles={{
        menuPortal: base =&amp;gt; ({ ...base, zIndex: 9999 }), // z-index 설정
      }}
    /&amp;gt;
  &amp;lt;/div&amp;gt;

  &amp;lt;div&amp;gt;
    &amp;lt;FormLabel&amp;gt;Status&amp;lt;/FormLabel&amp;gt;
    &amp;lt;FormGroup row&amp;gt;
      &amp;lt;FormControlLabel
        control={
          &amp;lt;CheckBox
            checked={this.state.test1}
            onChange={this.handleChkBox(&quot;Test1&quot;)}
            color=&quot;primary&quot;
          /&amp;gt;
        }
        label={consts.BABO}
      /&amp;gt;
    &amp;lt;/FormGroup&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Technical/React</category>
      <category>menuitem</category>
      <category>REACT</category>
      <category>react-select</category>
      <author>sga8</author>
      <guid isPermaLink="true">https://sga8.tistory.com/245</guid>
      <comments>https://sga8.tistory.com/245#entry245comment</comments>
      <pubDate>Tue, 7 Jan 2025 09:41:57 +0900</pubDate>
    </item>
    <item>
      <title>[webpack] webpack-dev-server config 설정 (esbuild-loader, babel-loader)</title>
      <link>https://sga8.tistory.com/244</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack dev server 매우 느린 이슈로 인해 해결방안&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. babel-loader &amp;rarr; esbuild-loader 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. webpack config 수정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1733451504874&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;module.exports = {
  mode: 'development',
  entry: ['@babel/polyfill', './src/index.js'],
  devtool: false,
  optimization: {
    providedExports: process.env.NODE_ENV === 'prod',
  },
  output: {
    pathinfo: false,
    filename: 'bundle.js',
    path: path.resolve(__dirname + '/dist'),
    publicPath: '/',
    clean: true,
  },
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'),
    },
    historyApiFallback: true,
    // compress: true,
    host: process.env.TEST_IP,
    port: process.env.TEST_PORT,
    https: {
      cert: process.env.TEST_CERT,
      key: process.env.TEST_KEY,
    },
    proxy: {
      '/test': {
        target: `${imsiurl}`,
        changeOrigin: true,
        secure: false,
      }
    },
  },
  cache: { type: process.env.NODE_ENV !== 'prod' ? 'memory' : 'filesystem' },
  module: {
    rules: [
      {
        test: /\.(js|jsx|ts|tsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'esbuild-loader',
          options: {
            loader: 'jsx',
            target: 'es2015',
          },
        },
      },
      {
        test: /\.html$/,
        use: [
          {
            loader: 'html-loader',
            options: { minimize: true },
          },
        ],
      },
      {
        test: /\.(css|scss)$/,
        use: [
          'style-loader',
          'css-loader',
          {
            loader: require.resolve('sass-loader'),
            options: {
              sourceMap: true,
            },
          },
        ],
      },
      {
        test: /\.(png|jpe?g|gif|svg|webp)$/i,
        use: {
          loader: 'file-loader',
          options: {
            name: '[name].[contenthash].[ext]',
          },
        },
      },
    ],
  },
  resolve: {
    extensions: ['.js'],
    alias: {
      '@src': path.resolve(__dirname, 'src/'),
      '@resource': path.resolve(__dirname, 'public/'),
    },
  },
  plugins: [
    (() =&amp;gt; {
      return new Dotenv({
        path: `./.env.${process.env.NODE_ENV}`,
      })
    })(),

    new HtmlWebPackPlugin({
      template: './public/index.html',
      filename: 'index.html',
    }),
  ],
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;cache 옵션&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;true/false (default: true)&lt;/li&gt;
&lt;li&gt;cache.type: memory(default) / filesystem&lt;/li&gt;
&lt;li&gt;cache.compression: 압축 여부&amp;nbsp;&lt;/li&gt;
&lt;li&gt;cache.maxAge: 생명 주기&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;devtool 옵션&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://webpack.kr/configuration/devtool/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://webpack.kr/configuration/devtool/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1733451949695&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Devtool | 웹팩&quot; data-og-description=&quot;웹팩은 모듈 번들러입니다. 주요 목적은 브라우저에서 사용할 수 있도록 JavaScript 파일을 번들로 묶는 것이지만, 리소스나 애셋을 변환하고 번들링 또는 패키징할 수도 있습니다.&quot; data-og-host=&quot;webpack.kr&quot; data-og-source-url=&quot;https://webpack.kr/configuration/devtool/&quot; data-og-url=&quot;https://webpack.kr/configuration/devtool/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/oisIh/hyXGB2ZEdJ/5ypDk74zXY2mEtfAnYEcE0/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://webpack.kr/configuration/devtool/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://webpack.kr/configuration/devtool/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/oisIh/hyXGB2ZEdJ/5ypDk74zXY2mEtfAnYEcE0/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Devtool | 웹팩&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;웹팩은 모듈 번들러입니다. 주요 목적은 브라우저에서 사용할 수 있도록 JavaScript 파일을 번들로 묶는 것이지만, 리소스나 애셋을 변환하고 번들링 또는 패키징할 수도 있습니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;webpack.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;eval-sourc-map
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;fast build / high debug quality&lt;/li&gt;
&lt;li&gt;개발 환경 용도 / 빌드 속도가 중요하면서도 디버깅 품질을 유지하고 싶을 때 적합&lt;/li&gt;
&lt;li&gt;&lt;b&gt;빌드 시간&lt;/b&gt;: 빠름&lt;/li&gt;
&lt;li&gt;&lt;b&gt;디버깅 품질&lt;/b&gt;: 높음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;source-map
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;highest debug quality&lt;/li&gt;
&lt;li&gt;프로덕션 환경 / 디버깅 품질이 중요할 때 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;빌드 시간&lt;/b&gt;: 느림&lt;/li&gt;
&lt;li&gt;&lt;b&gt;디버깅 품질&lt;/b&gt;: 매우 높음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;false
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;fastest build / No Debug&lt;/li&gt;
&lt;li&gt;프로덕션 환경 / 보안상 장점&lt;/li&gt;
&lt;li&gt;&lt;b&gt;빌드 시간&lt;/b&gt;: 매우 빠름&lt;/li&gt;
&lt;li&gt;&lt;b&gt;디버깅 품질&lt;/b&gt;: 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;providedExports 옵션&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;true/false (Default: true)&lt;/li&gt;
&lt;li&gt;Tree&amp;nbsp;Shaking:&amp;nbsp;사용되지&amp;nbsp;않는&amp;nbsp;코드를&amp;nbsp;제거하는&amp;nbsp;기법.&amp;nbsp;최종&amp;nbsp;번들&amp;nbsp;크기를&amp;nbsp;줄여줌.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;트리 쉐이킹 최적화&lt;/b&gt;: providedExports 옵션을 사용하면, Webpack은 해당 모듈이 제공하는 특정 내보내기(export) 항목들을 이미 알고 있기 때문에, 어떤 부분이 실제로 사용되지 않는지 추적하여 제거할 수 있습니다. 이를 통해 번들 크기를 더욱 최적화할 수 있습니다.&lt;/li&gt;
&lt;li&gt;providedExports 옵션의 작동 방식:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;내보내기(export) 확인&lt;/b&gt;: Webpack은 모듈이 제공하는 내보내기(export) 항목을 알아냅니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;트리 쉐이킹&lt;/b&gt;: 이후 트리 쉐이킹을 통해 사용되지 않는 내보내기 항목을 제거합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예를 들어, 특정 함수나 객체가 실제 코드에서 사용되지 않으면, 이를 최종 번들에서 제거합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;최적화&lt;/b&gt;: 트리 쉐이킹은 번들 크기를 줄이고, 불필요한 코드를 배제하여 로딩 성능을 향상시킵니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;예시와 더 나아가:providedExports와 트리 쉐이킹:참고:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;providedExports 옵션은 &lt;b&gt;트리 쉐이킹&lt;/b&gt;을 더 효율적으로 작동하게 만들어, 번들 크기를 최소화하는 데 기여합니다.&lt;/li&gt;
&lt;li&gt;이 옵션은 &lt;b&gt;ES 모듈&lt;/b&gt; 기반으로 최적화되므로, ES 모듈 시스템을 사용해야 효과적으로 작동합니다.&lt;/li&gt;
&lt;/ul&gt;
정리하면, providedExports는 모듈의 내보내기(export) 정보가 제공될 때, Webpack이 이를 활용해 불필요한 코드를 제거하는 데 도움을 주는 설정입니다.&lt;/li&gt;
&lt;li&gt;이 옵션은 기본적으로 Webpack 4 이상에서 &lt;b&gt;트리 쉐이킹&lt;/b&gt;을 지원하기 위해 활성화됩니다. providedExports가 true로 설정되면, Webpack은 해당 모듈에서 제공하는 export 항목을 알고 있게 되고, 실제로 사용되지 않은 코드들은 트리 쉐이킹을 통해 번들에서 제거할 수 있습니다.&lt;/li&gt;
&lt;li&gt;만약 lodash와 같은 라이브러리를 사용하는 경우, providedExports를 설정하면 lodash에서 실제로 사용된 메소드만 번들에 포함시키고, 사용되지 않은 메소드는 제거할 수 있습니다. 이로 인해 최종 번들의 크기가 줄어들게 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Trouble Shooting&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ReferenceError: React is not defined
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;esbuild가 암시적인 React 사용을 감지못해 발생하는 에러&lt;/li&gt;
&lt;li&gt;index.js / app.js 파일처럼 최상단 위치의 파일에서 아래처럼 global 선언해서 해결&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1733459656293&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';

global.React = React;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Technical/React</category>
      <category>babel-loader</category>
      <category>Cache</category>
      <category>devtool</category>
      <category>esbuild</category>
      <category>esbuild-loader</category>
      <category>providedexports</category>
      <category>react is not defined</category>
      <category>tree shaking</category>
      <category>Webpack</category>
      <author>sga8</author>
      <guid isPermaLink="true">https://sga8.tistory.com/244</guid>
      <comments>https://sga8.tistory.com/244#entry244comment</comments>
      <pubDate>Fri, 6 Dec 2024 13:39:08 +0900</pubDate>
    </item>
    <item>
      <title>[NodeJS] MySQL2 Error: Can't add new command when connection is in closed state. 해결</title>
      <link>https://sga8.tistory.com/243</link>
      <description>&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;br /&gt;공식 답변&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sidorares/node-mysql2/issues/1302&quot;&gt;https://github.com/sidorares/node-mysql2/issues/1302&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #1f2328; text-align: start;&quot;&gt;we should probably make it default option. Currently when remote side closes the socket the client might not see it, see&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; href=&quot;https://nodejs.org/api/net.html#net_socket_setkeepalive_enable_initialdelay&quot;&gt;net.setKeepAlive&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;b&gt;AS-IS&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;b&gt;TO-BE&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;host&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;aa.bb.cc.dd&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;port&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;test_user&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;test_password&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;database&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;connectionLimit&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;queueLimit&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;waitForConnections&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;dateStrings&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;multipleStatements&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;charset&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;utf8_general_ci&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;{&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;host&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;aa.bb.cc.dd&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;port&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &quot;enableKeepAlive&quot;:true&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;test_user&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;password&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;test_passvword!&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;database&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;100&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,v&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;connectionLimit&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;queueLimit&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #b5cea8;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;waitForConnections&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;dateStrings&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;date&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;multipleStatements&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;charset&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;utf8_general_ci&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;}&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Technical/NodeJS</category>
      <category>F</category>
      <author>sga8</author>
      <guid isPermaLink="true">https://sga8.tistory.com/243</guid>
      <comments>https://sga8.tistory.com/243#entry243comment</comments>
      <pubDate>Mon, 19 Aug 2024 18:34:05 +0900</pubDate>
    </item>
    <item>
      <title>[NestJS] mysql connection pool Cannot read properties of undefined 이슈 조치</title>
      <link>https://sga8.tistory.com/242</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NestJS + mysql2 사용시, mysql 객체가 TypeError: Cannot read properties of undefined (reading 'createPool') 에러가 발생하는 경우가 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1720044113276&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import mysql from &quot;mysql2/promise&quot;;

const _dbConn = mysql.createPool({});

export { _dbConn };&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 구현한 경우에 해당 에러가 발생함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조치 방법은 아래와 같이 as로 import 구문을 변경해주면 됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1720044284737&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import * as mysql from &quot;mysql2/promise&quot;;

const _dbConn = mysql.createPool({});

export { _dbConn };&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Technical/NodeJS</category>
      <category>createpool</category>
      <category>MySQL</category>
      <category>NestJS</category>
      <author>sga8</author>
      <guid isPermaLink="true">https://sga8.tistory.com/242</guid>
      <comments>https://sga8.tistory.com/242#entry242comment</comments>
      <pubDate>Thu, 4 Jul 2024 07:08:18 +0900</pubDate>
    </item>
    <item>
      <title>[Javascript] Regex/Regular Expression/정규표현식</title>
      <link>https://sga8.tistory.com/241</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100.116%; height: 110px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 67px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 67px;&quot;&gt;
&lt;h4 style=&quot;color: #000000; text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;RegExp.prototype.exec&lt;/b&gt;&lt;/h4&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 67px;&quot;&gt;
&lt;h4 style=&quot;color: #000000; text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;String.prototype.match&lt;/b&gt;&lt;/h4&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 117px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 117px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문자열에&amp;nbsp;대해&amp;nbsp;정규식과&amp;nbsp;일치하는지&amp;nbsp;탐색&amp;nbsp;후&amp;nbsp;결과를&amp;nbsp;배열로&amp;nbsp;반환함.&amp;nbsp;(일치하지&amp;nbsp;않을&amp;nbsp;경우,&amp;nbsp;null&amp;nbsp;반환)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;example)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;정규식.exec(문자열)&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 117px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정규식으로&amp;nbsp;문자열에서&amp;nbsp;일치하는지&amp;nbsp;탐색&amp;nbsp;후&amp;nbsp;결과를&amp;nbsp;배열로&amp;nbsp;반환함.&amp;nbsp;(일치하지&amp;nbsp;않을&amp;nbsp;경우,&amp;nbsp;&amp;nbsp;null&amp;nbsp;반환)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;example)&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;문자열.match(정규식)&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;차이점1. g 플래그 사용&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Case1) 단순 정규 표현식&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1714020886059&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const execTest = /(?&amp;lt;year&amp;gt;\d{4})-(?&amp;lt;month&amp;gt;\d{2})-(?&amp;lt;day&amp;gt;\d{2})/.exec(&quot;2024-04-15&quot;);
console.log(execTest)

// print log
// [
//   '2024-04-15',
//   '2024',
//   '04',
//   '15',
//   index: 0,
//   input: '2024-04-15',
//   groups: [Object: null prototype] { year: '2024', month: '04', day: '15' }
// ]

console.log(execTest.groups)
// print log
// { year: '2024', month: '04', day: '15' }

console.log(execTest.groups.year)
// print log
// 2024&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1714021361944&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const matchTest = &quot;2024-04-15&quot;.match(/(?&amp;lt;year&amp;gt;\d{4})-(?&amp;lt;month&amp;gt;\d{2})-(?&amp;lt;day&amp;gt;\d{2})/);
console.log(matchTest)

// [
//   '2024-04-15',
//   '2024',
//   '04',
//   '15',
//   index: 0,
//   input: '2024-04-15',
//   groups: [Object: null prototype] { year: '2024', month: '04', day: '15' }
// ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Case2)&amp;nbsp;g플래그&amp;nbsp;사용&amp;nbsp;정규식&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- exec의 경우, 동일한 결과&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1714021956300&quot; class=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const execTest = /(?&amp;lt;year&amp;gt;\d{4})-(?&amp;lt;month&amp;gt;\d{2})-(?&amp;lt;day&amp;gt;\d{2})/g.exec(&quot;2024-04-15&quot;);
console.log(execTest)

// print log
// [
//   '2024-04-15',
//   '2024',
//   '04',
//   '15',
//   index: 0,
//   input: '2024-04-15',
//   groups: [Object: null prototype] { year: '2024', month: '04', day: '15' }
// ]

console.log(execTest.groups)
// print log
// { year: '2024', month: '04', day: '15' }

console.log(execTest.groups.year)
// print log
// 2024&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- match의 경우, 결과 배열만 반환&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1714022003837&quot; class=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const matchTest = &quot;2024-04-15&quot;.match(/(?&amp;lt;year&amp;gt;\d{4})-(?&amp;lt;month&amp;gt;\d{2})-(?&amp;lt;day&amp;gt;\d{2})/g);
console.log(matchTest)

// [ '2024-04-15' ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;차이점2.&amp;nbsp; 캡처 그룹(Capture group) 사용 시, 반복 검색 여부&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- exec의 경우, 첫 매칭 정보만 반환함 &amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1714022347044&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const execTest = /(?&amp;lt;babo&amp;gt;\d{4})/g.exec(&quot;2024-2025-2026&quot;);
console.log(execTest);

// print log
// [
//   '2024',
//   '2024',
//   index: 0,
//   input: '2024-2025-2026',
//   groups: [Object: null prototype] { babo: '2024' }
// ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;match의&amp;nbsp;경우,&amp;nbsp;모든&amp;nbsp;매칭&amp;nbsp;정보를&amp;nbsp;반환함.&lt;/p&gt;
&lt;pre id=&quot;code_1714022392457&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const matchTest = &quot;2024-2025-2026&quot;.match(/(?&amp;lt;babo&amp;gt;\d{4})/g);
console.log(matchTest);

// print log
// [ '2024', '2025', '2026' ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;차이점3. 반복문을 통한 exec 사용&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;exec의&amp;nbsp;경우,&amp;nbsp;반복문을&amp;nbsp;통해&amp;nbsp;사용했을&amp;nbsp;경우&amp;nbsp;반환&amp;nbsp;값과&amp;nbsp;lastIndex를&amp;nbsp;계속해서&amp;nbsp;갱신함.&amp;nbsp; &lt;br /&gt;-&amp;nbsp;더&amp;nbsp;이상&amp;nbsp;찾을&amp;nbsp;수&amp;nbsp;없을&amp;nbsp;경우,&amp;nbsp;null&amp;nbsp;반환&amp;nbsp;및&amp;nbsp;lastIndex&amp;nbsp;값을&amp;nbsp;0으로&amp;nbsp;초기화함.&lt;/p&gt;
&lt;pre id=&quot;code_1714022651525&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const execRegex = /(?&amp;lt;babo&amp;gt;\d{4})/g;
while((result = execRegex.exec(&quot;2024-2025-2026&quot;)) !== null) {
    console.log(result)
    console.log(`Found ${result[0]}. Next starts at ${execRegex.lastIndex}`)
}


// print log
// [
//   '2024',
//   '2024',
//   index: 0,
//   input: '2024-2025-2026',
//   groups: [Object: null prototype] { babo: '2024' }
// ]
// Found 2024. Next starts at 4


// [
//   '2025',
//   '2025',
//   index: 5,
//   input: '2024-2025-2026',
//   groups: [Object: null prototype] { babo: '2025' }
// ]
// Found 2025. Next starts at 9


// [
//   '2026',
//   '2026',
//   index: 10,
//   input: '2024-2025-2026',
//   groups: [Object: null prototype] { babo: '2026' }
// ]
// Found 2026. Next starts at 14&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;장점:&lt;/b&gt; index, lastIndex, input 같은 데이터 활용 가능.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단점:&lt;/b&gt; 반복문을 통한 exec 사용해야 여러 반환값 탐색 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;exec와 match의 장/단점을 골고루 합친 String.prototype.matchAll 기능도 있음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고) &lt;a href=&quot;https://bsscl.tistory.com/84&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://bsscl.tistory.com/84&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Language/Javascript</category>
      <category>JavaScript</category>
      <category>regex</category>
      <category>Regular expression</category>
      <category>정규표현식</category>
      <author>sga8</author>
      <guid isPermaLink="true">https://sga8.tistory.com/241</guid>
      <comments>https://sga8.tistory.com/241#entry241comment</comments>
      <pubDate>Thu, 25 Apr 2024 14:26:06 +0900</pubDate>
    </item>
    <item>
      <title>useRef Array로 사용하기</title>
      <link>https://sga8.tistory.com/240</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@cmk0905/React-useRef&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://velog.io/@cmk0905/React-useRef&lt;/a&gt;&lt;/p&gt;</description>
      <author>sga8</author>
      <guid isPermaLink="true">https://sga8.tistory.com/240</guid>
      <comments>https://sga8.tistory.com/240#entry240comment</comments>
      <pubDate>Thu, 4 Apr 2024 17:16:46 +0900</pubDate>
    </item>
  </channel>
</rss>