<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>타닥타닥 민타쿠</title>
    <link>https://mintaku.tistory.com/</link>
    <description>개발 관련 기록, 정리 위주의 포스팅 예정입니다.
도움이 되면 좋겠습니다.</description>
    <language>ko</language>
    <pubDate>Wed, 29 Jul 2026 12:35:38 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>민타쿠</managingEditor>
    <image>
      <title>타닥타닥 민타쿠</title>
      <url>https://tistory1.daumcdn.net/tistory/3111884/attach/82c39fbca11f4377926255d8cbc087f0</url>
      <link>https://mintaku.tistory.com</link>
    </image>
    <item>
      <title>AI 가 바라본 윤석열 대통령의 계엄령 선포 목적과 이로 인한 탄핵 가능성</title>
      <link>https://mintaku.tistory.com/35</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkvF2P/btsK5FwGh65/sfORb8qaHVHJ9n3scloj6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkvF2P/btsK5FwGh65/sfORb8qaHVHJ9n3scloj6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkvF2P/btsK5FwGh65/sfORb8qaHVHJ9n3scloj6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkvF2P%2FbtsK5FwGh65%2FsfORb8qaHVHJ9n3scloj6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;954&quot; height=&quot;348&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;348&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2024년 12월 3일. 초유의 사태가 발생했다. 윤석열 대통령의 계엄령 선포. &lt;br /&gt;윤석열 대통령은 무슨 목적으로 이를 진행했을까. 이번 일을 벌여서 탄핵 가능성이 높아지진 않았을까. &lt;br /&gt;편파적인 관점을 배제하기 위해 AI 에게 물어보자.&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;1. 윤석열 대통령의 계엄령 선포 목적&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZJU6B/btsK5cV4cQC/SkFKAtsdaH648zmiAkB4ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZJU6B/btsK5cV4cQC/SkFKAtsdaH648zmiAkB4ck/img.png&quot; data-alt=&quot;윤석열 대통령의 계엄령 선포 목적&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZJU6B/btsK5cV4cQC/SkFKAtsdaH648zmiAkB4ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZJU6B%2FbtsK5cV4cQC%2FSkFKAtsdaH648zmiAkB4ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;851&quot; height=&quot;440&quot; data-origin-width=&quot;851&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;윤석열 대통령의 계엄령 선포 목적&lt;/figcaption&gt;
&lt;/figure&gt;
&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;849&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWQRYw/btsK69pK8e5/u3rdR1K5UnAadRPPoucXK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWQRYw/btsK69pK8e5/u3rdR1K5UnAadRPPoucXK0/img.png&quot; data-alt=&quot;윤석열 대통령이 계엄령을 선포한 진짜 목적&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWQRYw/btsK69pK8e5/u3rdR1K5UnAadRPPoucXK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWQRYw%2FbtsK69pK8e5%2Fu3rdR1K5UnAadRPPoucXK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;849&quot; height=&quot;676&quot; data-origin-width=&quot;849&quot; data-origin-height=&quot;676&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;윤석열 대통령이 계엄령을 선포한 진짜 목적&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI 에 따르면,&lt;br /&gt;윤석열 대통령이 계엄령을 선포한 진짜 목적은 아래 네 가지일 가능성이 높다.&lt;/p&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;li&gt;권력 강화&lt;/li&gt;
&lt;li&gt;국민적 위기감 조성&lt;/li&gt;
&lt;li&gt;경제적, 사회적 문제 전환&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로, &lt;b&gt;정치적 생존과 권력 유지를 위한 의도&lt;/b&gt;라는 종합적 판단을 내리는 것을 볼 수 있다.&lt;br /&gt;물론 이는 명백히 입증된 것은 아니라는 말도 당연히 덧붙였지만 말이다.&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;2. 계엄령 선포 사태로 인한 탄핵 가능성&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LRuUZ/btsK51lZvtF/jbAkI2TVzyvz6zfghbdzDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LRuUZ/btsK51lZvtF/jbAkI2TVzyvz6zfghbdzDK/img.png&quot; data-alt=&quot;계엄령 선포 사태로 인한 탄핵 가능성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LRuUZ/btsK51lZvtF/jbAkI2TVzyvz6zfghbdzDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLRuUZ%2FbtsK51lZvtF%2FjbAkI2TVzyvz6zfghbdzDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;845&quot; height=&quot;453&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;계엄령 선포 사태로 인한 탄핵 가능성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마찬가지로 간략한 설명만 해준다. &lt;br /&gt;계엄령 선포에 대한 절차적 정당성에 대해선 의견이 분분할테니, 정당하지 않을 경우의 탄핵 가능성만 물어보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;669&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmkths/btsK40uxmTy/n0CVEUFkaDGwq0RERLHcu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmkths/btsK40uxmTy/n0CVEUFkaDGwq0RERLHcu0/img.png&quot; data-alt=&quot;정당하지 않은 계엄령 선포의 법률 위반점과 이에 따른 탄핵 가능성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmkths/btsK40uxmTy/n0CVEUFkaDGwq0RERLHcu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbmkths%2FbtsK40uxmTy%2Fn0CVEUFkaDGwq0RERLHcu0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;837&quot; height=&quot;669&quot; data-origin-width=&quot;837&quot; data-origin-height=&quot;669&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정당하지 않은 계엄령 선포의 법률 위반점과 이에 따른 탄핵 가능성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;헌법재판소는 탄핵 사유를 판단할 때, 대통령이 헌법과 법률을 얼마나 준수했는지 확인하는데,&lt;br /&gt;&lt;b&gt;타당한 이유 없이 계엄령을 선포했다면&lt;/b&gt; 명백한 권한 남용으로 간주되며 헌법 제77조, 형법 제123조, 내란죄 등의 중대한 법적 문제에 해당 되어 &lt;b&gt;탄핵 사유가 되기 충분하다&lt;/b&gt;는 말을 한다. &lt;br /&gt;역시나 그만큼 이번 사태는 굉장히 심각하며 &lt;b&gt;계엄령 선포의 정당성 판단이 가장 중요&lt;/b&gt;할 것으로 보인다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>사회</category>
      <category>AI</category>
      <category>ChatGPT</category>
      <category>가능성</category>
      <category>계엄령</category>
      <category>대통령</category>
      <category>목적</category>
      <category>윤석열</category>
      <category>탄핵</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/35</guid>
      <comments>https://mintaku.tistory.com/35#entry35comment</comments>
      <pubDate>Wed, 4 Dec 2024 11:20:32 +0900</pubDate>
    </item>
    <item>
      <title>C# 윈폼(Winform) 자식(하위) 노드까지 한번에 체크하기</title>
      <link>https://mintaku.tistory.com/34</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;트리뷰의 자식 노드까지 전체 체크, 전체 체크해제 기능은 AfterCheck 이벤트를 통해 간단히 만들 수 있는데, &lt;br /&gt;친절하게도 공식 문서의 TreeView.AfterCheck Event 페이지에 자식 노드의 체크 기능까지 같이 나와있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드는 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1658454869199&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// Updates all child tree nodes recursively.
private void CheckAllChildNodes(TreeNode treeNode, bool nodeChecked)
{
   foreach(TreeNode node in treeNode.Nodes)
   {
      node.Checked = nodeChecked;
      if(node.Nodes.Count &amp;gt; 0)
      {
         // If the current node has child nodes, call the CheckAllChildsNodes method recursively.
         this.CheckAllChildNodes(node, nodeChecked);
      }
   }
}

// NOTE   This code can be added to the BeforeCheck event handler instead of the AfterCheck event.
// After a tree node's Checked property is changed, all its child nodes are updated to the same value.
private void node_AfterCheck(object sender, TreeViewEventArgs e)
{
   // The code only executes if the user caused the checked state to change.
   if(e.Action != TreeViewAction.Unknown)
   {
      if(e.Node.Nodes.Count &amp;gt; 0)
      {
         /* Calls the CheckAllChildNodes method, passing in the current 
         Checked value of the TreeNode whose checked state changed. */
         this.CheckAllChildNodes(e.Node, e.Node.Checked);
      }
   }
}&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;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.treeview.aftercheck?redirectedfrom=MSDN&amp;amp;view=windowsdesktop-6.0&quot;&gt;https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.treeview.aftercheck?redirectedfrom=MSDN&amp;amp;view=windowsdesktop-6.0&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1658454957710&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;TreeView.AfterCheck Event (System.Windows.Forms)&quot; data-og-description=&quot;Occurs after the tree node check box is checked.&quot; data-og-host=&quot;docs.microsoft.com&quot; data-og-source-url=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.treeview.aftercheck?redirectedfrom=MSDN&amp;amp;view=windowsdesktop-6.0&quot; data-og-url=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.treeview.aftercheck&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ceKKRv/hyPaojGgq5/KqDEOpeRm5MUzUnGeZtka0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.treeview.aftercheck?redirectedfrom=MSDN&amp;amp;view=windowsdesktop-6.0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.treeview.aftercheck?redirectedfrom=MSDN&amp;amp;view=windowsdesktop-6.0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ceKKRv/hyPaojGgq5/KqDEOpeRm5MUzUnGeZtka0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&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;TreeView.AfterCheck Event (System.Windows.Forms)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Occurs after the tree node check box is checked.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Winform</category>
      <category>AfterCheck</category>
      <category>CheckAllChildNodes</category>
      <category>checkbox</category>
      <category>treeview</category>
      <category>WinForm</category>
      <category>윈폼</category>
      <category>자식노드</category>
      <category>하위노드</category>
      <category>한번에 체크</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/34</guid>
      <comments>https://mintaku.tistory.com/34#entry34comment</comments>
      <pubDate>Sat, 23 Jul 2022 10:01:28 +0900</pubDate>
    </item>
    <item>
      <title>C# Winform(윈폼) 트리뷰 체크박스 더블클릭 버그 방지 해결책</title>
      <link>https://mintaku.tistory.com/33</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;윈폼에서 제공해주는 트리뷰(TreeView) 의 체크박스를 더블클릭해보면 정상적으로 동작하지 않는 모습을 볼 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1658453897632&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class NewTreeView : TreeView {
protected override void WndProc(ref Message m) {
 if (m.Msg == 0x203) { m.Result = IntPtr.Zero; }
 else base.WndProc(ref m);
 }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때, Designer.cs 파일에 위와 같이 트리뷰를 상속받는 NewTreeView 클래스를 만들고&lt;/p&gt;
&lt;pre id=&quot;code_1658454217586&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// this.treeView1 = new System.Windows.Forms.TreeView();
this.treeView1 = new SCL_Editor.Dialogs.AddFCDAForm.NewTreeView();

//private System.Windows.Forms.TreeView treeView1;
private NewTreeView treeView1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 같이 기존 TreeView 를 NewTreeView 로 바꿔주면 해결 가능하다.&lt;/p&gt;</description>
      <category>개발/Winform</category>
      <category>bug</category>
      <category>checkbox</category>
      <category>double click</category>
      <category>treeview</category>
      <category>TreeView CheckBox</category>
      <category>WinForm</category>
      <category>더블클릭</category>
      <category>버그</category>
      <category>체크박스</category>
      <category>트리뷰</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/33</guid>
      <comments>https://mintaku.tistory.com/33#entry33comment</comments>
      <pubDate>Fri, 22 Jul 2022 10:48:50 +0900</pubDate>
    </item>
    <item>
      <title>C# 객체 복사 (Deep Copy) 클래스</title>
      <link>https://mintaku.tistory.com/32</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;결론부터 말하자면, &lt;u&gt;아래 클래스 저장&lt;/u&gt; 후 &lt;b&gt;ObjectExtensions.Copy(객체)&lt;/b&gt; 의 형태로 쓰자.&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;깊은 복사가 된 객체를 반환&lt;/span&gt;&lt;/b&gt; 받을 수 있다.&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;다만 조금 느릴 수 있다&lt;/span&gt;.&lt;/p&gt;
&lt;pre id=&quot;code_1658124254558&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static class ObjectExtensions // Deep Copy Class. Use 'ObjectExtensions.Copy(object)'.
    {
        private static readonly MethodInfo CloneMethod = typeof(Object).GetMethod(&quot;MemberwiseClone&quot;, BindingFlags.NonPublic | BindingFlags.Instance);

        public static bool IsPrimitive(this Type type)
        {
            if (type == typeof(String)) return true;
            return (type.IsValueType &amp;amp; type.IsPrimitive);
        }

        public static Object Copy(this Object originalObject)
        {
            return InternalCopy(originalObject, new Dictionary&amp;lt;Object, Object&amp;gt;(new ReferenceEqualityComparer()));
        }
        private static Object InternalCopy(Object originalObject, IDictionary&amp;lt;Object, Object&amp;gt; visited)
        {
            if (originalObject == null) return null;
            var typeToReflect = originalObject.GetType();
            if (IsPrimitive(typeToReflect)) return originalObject;
            if (visited.ContainsKey(originalObject)) return visited[originalObject];
            if (typeof(Delegate).IsAssignableFrom(typeToReflect)) return null;
            var cloneObject = CloneMethod.Invoke(originalObject, null);
            if (typeToReflect.IsArray)
            {
                var arrayType = typeToReflect.GetElementType();
                if (IsPrimitive(arrayType) == false)
                {
                    Array clonedArray = (Array)cloneObject;
                    clonedArray.ForEach((array, indices) =&amp;gt; array.SetValue(InternalCopy(clonedArray.GetValue(indices), visited), indices));
                }

            }
            visited.Add(originalObject, cloneObject);
            CopyFields(originalObject, visited, cloneObject, typeToReflect);
            RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect);
            return cloneObject;
        }

        private static void RecursiveCopyBaseTypePrivateFields(object originalObject, IDictionary&amp;lt;object, object&amp;gt; visited, object cloneObject, Type typeToReflect)
        {
            if (typeToReflect.BaseType != null)
            {
                RecursiveCopyBaseTypePrivateFields(originalObject, visited, cloneObject, typeToReflect.BaseType);
                CopyFields(originalObject, visited, cloneObject, typeToReflect.BaseType, BindingFlags.Instance | BindingFlags.NonPublic, info =&amp;gt; info.IsPrivate);
            }
        }

        private static void CopyFields(object originalObject, IDictionary&amp;lt;object, object&amp;gt; visited, object cloneObject, Type typeToReflect, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.FlattenHierarchy, Func&amp;lt;FieldInfo, bool&amp;gt; filter = null)
        {
            foreach (FieldInfo fieldInfo in typeToReflect.GetFields(bindingFlags))
            {
                if (filter != null &amp;amp;&amp;amp; filter(fieldInfo) == false) continue;
                if (IsPrimitive(fieldInfo.FieldType)) continue;
                var originalFieldValue = fieldInfo.GetValue(originalObject);
                var clonedFieldValue = InternalCopy(originalFieldValue, visited);
                fieldInfo.SetValue(cloneObject, clonedFieldValue);
            }
        }
        public static T Copy&amp;lt;T&amp;gt;(this T original)
        {
            return (T)Copy((Object)original);
        }
    }

    public class ReferenceEqualityComparer : EqualityComparer&amp;lt;Object&amp;gt;
    {
        public override bool Equals(object x, object y)
        {
            return ReferenceEquals(x, y);
        }
        public override int GetHashCode(object obj)
        {
            if (obj == null) return 0;
            return obj.GetHashCode();
        }
    }

    namespace ArrayExtensions
    {
        public static class ArrayExtensions
        {
            public static void ForEach(this Array array, Action&amp;lt;Array, int[]&amp;gt; action)
            {
                if (array.LongLength == 0) return;
                ArrayTraverse walker = new ArrayTraverse(array);
                do action(array, walker.Position);
                while (walker.Step());
            }
        }

        internal class ArrayTraverse
        {
            public int[] Position;
            private int[] maxLengths;

            public ArrayTraverse(Array array)
            {
                maxLengths = new int[array.Rank];
                for (int i = 0; i &amp;lt; array.Rank; ++i)
                {
                    maxLengths[i] = array.GetLength(i) - 1;
                }
                Position = new int[array.Rank];
            }

            public bool Step()
            {
                for (int i = 0; i &amp;lt; Position.Length; ++i)
                {
                    if (Position[i] &amp;lt; maxLengths[i])
                    {
                        Position[i]++;
                        for (int j = 0; j &amp;lt; i; j++)
                        {
                            Position[j] = 0;
                        }
                        return true;
                    }
                }
                return false;
            }
        }
    }&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;size18&quot;&gt;얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)에 대한 짧은 설명&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 짜다보면 참조를 공유하지 않고 완전히 똑같지만 새로운 객체가 필요한 경우가 생긴다. 내가 그랬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통&lt;/p&gt;
&lt;pre id=&quot;code_1658123559842&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Object something = new Something();
something = originObject;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 방식으로 새로운 객체를 만들어 냈다고 생각하는 경우가 있는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 새로운 객체가 기존의 객체를 바라보는 형태이므로 originObject 가 수정되면 something 도 같이 변한다.&lt;br /&gt;(정확히는 변하는 것이 아닌 같은 주소를 참조하기 때문에 같은 것이라 할 수 있다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 얕은 복사(Shallow Copy)라 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 얕은 복사가 필요한 경우가 있겠지만, 지금은 값은 같지만 새로운 주소를 가지게 하는 깊은 복사(Deep Copy)가 필요했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일일이 객체 속을 낱낱히 뒤져가며 해야 하나 싶었지만 다행히 그리고 고맙게도 Stack Overflow 에서 해결책을 찾았다.&lt;br /&gt;&lt;a title=&quot;How do you do a deep copy of an object in .NET? [duplicate]&quot; href=&quot;https://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-of-an-object-in-net&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-of-an-object-in-net&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1658124905436&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;How do you do a deep copy of an object in .NET?&quot; data-og-description=&quot;I want a true deep copy. In Java, this was easy, but how do you do it in C#?&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-of-an-object-in-net&quot; data-og-url=&quot;https://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-of-an-object-in-net&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/n0PYZ/hyO8XrptVu/xfACmoDnd3LPwYC9y0Yts0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-of-an-object-in-net&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/questions/129389/how-do-you-do-a-deep-copy-of-an-object-in-net&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/n0PYZ/hyO8XrptVu/xfACmoDnd3LPwYC9y0Yts0/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316');&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;How do you do a deep copy of an object in .NET?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I want a true deep copy. In Java, this was easy, but how do you do it in C#?&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Winform</category>
      <category>C#</category>
      <category>C# Deep Copy</category>
      <category>deep copy</category>
      <category>Object Copy</category>
      <category>shallow copy</category>
      <category>객체 복사</category>
      <category>깊은 복사</category>
      <category>얕은 복사</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/32</guid>
      <comments>https://mintaku.tistory.com/32#entry32comment</comments>
      <pubDate>Tue, 19 Jul 2022 01:15:42 +0900</pubDate>
    </item>
    <item>
      <title>Git LFS 무료 사용량 제한, 사용량 확인 방법</title>
      <link>https://mintaku.tistory.com/31</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;깃허브에는 100MB 단일 파일 업로드 제한이 있다. (50메가가 넘어가면 warning, 100메가가 넘어가면 error)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 단일 파일이 100 메가 바이트가 넘어가는 파일을 업로드 하는 것을 지양하는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 어쩔 수 없거나 편의성의 문제로 업로드 해야할 경우, Git LFS 라는 것을 이용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a title=&quot;Git LFS 깃허브 대용량(100MB) 파일 올리기&quot; href=&quot;https://mintaku.tistory.com/14&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://mintaku.tistory.com/14&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1658072990258&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Git LFS 깃허브 대용량(100MB) 파일 올리기&quot; data-og-description=&quot;깃허브 저장소에는 용량 제한이 없지만, 파일 하나당 100메가의 제한이 있다. 따라서, 파일이 50메가만 넘어가도 warning 메시지가 뜨고, 100메가가 넘어가는 파일을 push 하려는 경우에 다음과 같은 &quot; data-og-host=&quot;mintaku.tistory.com&quot; data-og-source-url=&quot;https://mintaku.tistory.com/14&quot; data-og-url=&quot;https://mintaku.tistory.com/14&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/OA8Lw/hyO7uDTeEO/TUFV4vkAKdRYCYk0Ha7Oq1/img.png?width=503&amp;amp;height=440&amp;amp;face=0_0_503_440,https://scrap.kakaocdn.net/dn/cpzN39/hyO7Fk3sZf/ChRFpB4XPhKfkJ4Ms99FXk/img.png?width=503&amp;amp;height=440&amp;amp;face=0_0_503_440,https://scrap.kakaocdn.net/dn/oiZIt/hyO7HQKvBZ/yiZs6vt9VqQuWQm2kCUCoK/img.png?width=990&amp;amp;height=357&amp;amp;face=0_0_990_357&quot;&gt;&lt;a href=&quot;https://mintaku.tistory.com/14&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mintaku.tistory.com/14&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/OA8Lw/hyO7uDTeEO/TUFV4vkAKdRYCYk0Ha7Oq1/img.png?width=503&amp;amp;height=440&amp;amp;face=0_0_503_440,https://scrap.kakaocdn.net/dn/cpzN39/hyO7Fk3sZf/ChRFpB4XPhKfkJ4Ms99FXk/img.png?width=503&amp;amp;height=440&amp;amp;face=0_0_503_440,https://scrap.kakaocdn.net/dn/oiZIt/hyO7HQKvBZ/yiZs6vt9VqQuWQm2kCUCoK/img.png?width=990&amp;amp;height=357&amp;amp;face=0_0_990_357');&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;Git LFS 깃허브 대용량(100MB) 파일 올리기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;깃허브 저장소에는 용량 제한이 없지만, 파일 하나당 100메가의 제한이 있다. 따라서, 파일이 50메가만 넘어가도 warning 메시지가 뜨고, 100메가가 넘어가는 파일을 push 하려는 경우에 다음과 같은&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mintaku.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 링크의 방법을 따라하면 무리 없이 업로드할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 한 가지 의문이 든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 Git LFS 의 무료 허용량은 얼마나 될까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론은 현재 2022년 기준 1GB 의 용량과 1GB 의 전송량이 한 개의 무료 계정에 허용되는 양이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 전송량은 업로드할 때는 계산되지 않고 다운로드할 때에만 계산된다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 내 Git LFS 사용량 수치를 보려면, 그 과정은 아래와 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;GitHub 홈페이지에 로그인 후 우측 상단 내 계정 아이콘을 누르고&lt;/li&gt;
&lt;li&gt;Settings 클릭&lt;/li&gt;
&lt;li&gt;좌측 Access 탭에서 Billing and plans 클릭&lt;/li&gt;
&lt;li&gt;아래로 스크롤하여 Usage this month 의 Git LFS Data 항목을 확인&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;209&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVH8ic/btrHxV3FAO0/GXOoMFJQQEHaQl4Bx22N11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVH8ic/btrHxV3FAO0/GXOoMFJQQEHaQl4Bx22N11/img.png&quot; data-alt=&quot;Git LFS Data 사용량&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVH8ic/btrHxV3FAO0/GXOoMFJQQEHaQl4Bx22N11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVH8ic%2FbtrHxV3FAO0%2FGXOoMFJQQEHaQl4Bx22N11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;420&quot; height=&quot;209&quot; data-origin-width=&quot;420&quot; data-origin-height=&quot;209&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Git LFS Data 사용량&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Git</category>
      <category>Git</category>
      <category>git lfs</category>
      <category>Git LFS 무료</category>
      <category>Git LFS 사용량</category>
      <category>Git LFS 사용량 제한</category>
      <category>Git LFS 사용량 확인</category>
      <category>Git LFS 사용법</category>
      <category>Git LFS 허용량</category>
      <category>github</category>
      <category>lfs</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/31</guid>
      <comments>https://mintaku.tistory.com/31#entry31comment</comments>
      <pubDate>Mon, 18 Jul 2022 01:03:55 +0900</pubDate>
    </item>
    <item>
      <title>윈폼 테이블 변경이 느릴 때(C# Winform TableLayoutPanel  Suspend)</title>
      <link>https://mintaku.tistory.com/30</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;윈폼에서 보여지는 테이블에 행을 추가하는 등의 변경이 일어날 때, 굉장히 느리다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;표가 깜빡이면서 열심히 하나하나 그리는 것처럼 보이는데, 성능이 이렇게 안좋나 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블의 Visible 속성을 false 로 하고 작업 후 True 로 되돌려도 약간의 속도가 빨라진 기분만 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다행히 이것은 테이블을 중단시키고 변경 후 재개시키면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1631250685789&quot; class=&quot;cs&quot; data-ke-language=&quot;cs&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;table1.SuspendLayout();

// 테이블 행 추가 등의 변경 작업

table1.ResumeLayout();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깜빡이던 것이 없어지고 속도가 훨씬 향상됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;20행 추가할 때 10초정도 걸리던 것이 2초정도로 줄었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 정도면 쓸만한데.. 더 빨라졌으면 좋겠다.&lt;/p&gt;</description>
      <category>개발/Winform</category>
      <category>C#</category>
      <category>ResumeLayout</category>
      <category>slow</category>
      <category>SuspendLayout</category>
      <category>TableLayoutPanel</category>
      <category>WinForm</category>
      <category>깜빡임</category>
      <category>느림</category>
      <category>윈폼</category>
      <category>테이블</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/30</guid>
      <comments>https://mintaku.tistory.com/30#entry30comment</comments>
      <pubDate>Fri, 10 Sep 2021 14:17:16 +0900</pubDate>
    </item>
    <item>
      <title>Nodejs 파일명, 라인 나오게 로깅하기 (tracer 모듈)</title>
      <link>https://mintaku.tistory.com/29</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Nodejs 에서 로깅 모듈로 유명한 winston 모듈은 성능 등의 이슈로 추적(tracing) 기능을 지원하지 않는다고 한다.&lt;br /&gt;일부 유저들이 winston 을 쓰면서 파일명, 라인(몇째 줄인지)까지 나오게 하는 시도들이 있는 것 같지만,&lt;br /&gt;불안정하고 성능이 좋지 못하다는 공식 입장을 보고도 그러한 방법을 써볼 필요는 없는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, tracer 라는 편리한 모듈을 써서 쉽고 간편하게 파일명과 라인 출력을 해보았다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;npm install tracer&lt;/span&gt;&lt;br /&gt;프로젝트 경로에서 명령어를 통해 모듈 설치&lt;/li&gt;
&lt;li&gt;tracer.js&lt;br /&gt;
&lt;pre id=&quot;code_1629802847338&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var fs = require('fs');

var logger = require('tracer').colorConsole({
  transport: function(data) {
    console.log(data.output);
    // logs 폴더에 로그 파일을 생성할 것이므로 폴더를 미리 만들어 놓아야 한다!
    fs.appendFile('logs/'+getTodayFormat()+'.log', data.rawoutput + '\n', err =&amp;gt; {
      if (err) throw err
    });
  }
});

function getTodayFormat() {
  let today = new Date();

  let year = today.getFullYear(); // 년도
  let month = today.getMonth() + 1;  // 월
  let date = today.getDate();  // 날짜
  // let day = today.getDay();  // 요일

  let format = year + '-' + (((month+'').length === 1)?'0':'')+month + '-' + (((date+'').length === 1)?'0':'')+date; // ex) 2021-08-24

  return format;
}

module.exports = logger;​&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;app.js&lt;br /&gt;
&lt;pre id=&quot;code_1629803004477&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const express = require('express');
const app = express();

const logger = require('./pages/assets/js/tracer'); // tracer.js

// 로컬 변수로 사용
app.use(function(req, res, next) {
  res.locals.logger = logger;
  next();
});​&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;cognito.js (router)&lt;br /&gt;
&lt;pre id=&quot;code_1629803205799&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const express = require('express');
const router = express.Router();

router.get('/login', function(req,res){
  res.locals.logger.error('GET /login !?!?!');
  res.render('login');
});​&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;로그 출력 확인&lt;br /&gt;- 콘솔&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;42&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sm0WI/btrc3o9NRL8/7jS4d5mQ2mxFAoukt0B4t1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sm0WI/btrc3o9NRL8/7jS4d5mQ2mxFAoukt0B4t1/img.png&quot; data-alt=&quot;tracer 모듈로 로깅된 콘솔 로그&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sm0WI/btrc3o9NRL8/7jS4d5mQ2mxFAoukt0B4t1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsm0WI%2Fbtrc3o9NRL8%2F7jS4d5mQ2mxFAoukt0B4t1%2Fimg.png&quot; data-origin-width=&quot;619&quot; data-origin-height=&quot;42&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;tracer 모듈로 로깅된 콘솔 로그&lt;/figcaption&gt;
&lt;/figure&gt;
- 파일&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;597&quot; data-origin-height=&quot;26&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MbYpu/btrc2oWxKpo/rG1C2Je3t8eJdtNGx3sPkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MbYpu/btrc2oWxKpo/rG1C2Je3t8eJdtNGx3sPkK/img.png&quot; data-alt=&quot;tracer 모듈로 생성된 로그 파일&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MbYpu/btrc2oWxKpo/rG1C2Je3t8eJdtNGx3sPkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMbYpu%2Fbtrc2oWxKpo%2FrG1C2Je3t8eJdtNGx3sPkK%2Fimg.png&quot; data-origin-width=&quot;597&quot; data-origin-height=&quot;26&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;tracer 모듈로 생성된 로그 파일&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;69&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NybMi/btrdaFWuu2M/lLovvTPuIHGpI4C6fhJcz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NybMi/btrdaFWuu2M/lLovvTPuIHGpI4C6fhJcz0/img.png&quot; data-alt=&quot;tracer 모듈로 로깅된 로그 파일 내용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NybMi/btrdaFWuu2M/lLovvTPuIHGpI4C6fhJcz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNybMi%2FbtrdaFWuu2M%2FlLovvTPuIHGpI4C6fhJcz0%2Fimg.png&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;69&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;tracer 모듈로 로깅된 로그 파일 내용&lt;/figcaption&gt;
&lt;/figure&gt;
파일명은 위 format 에서 직접 설정해주었고&lt;br /&gt;날짜, 시간, 로그 레벨, 파일명, 라인, 로깅 내용까지 잘 출력 및 저장되었다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 로그 레벨은&lt;br /&gt;log, trace, debug, info, warn, error 가 있고, 세부적인 설정방법은 아래 모듈참조페이지 링크를 통해서 알 수 있다.&lt;br /&gt;&lt;a href=&quot;https://github.com/baryon/tracer&quot;&gt;모듈참조페이지&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1629804139691&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - baryon/tracer: A powerful and customizable logging library for node.js&quot; data-og-description=&quot;A powerful and customizable logging library for node.js - GitHub - baryon/tracer: A powerful and customizable logging library for node.js&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/baryon/tracer&quot; data-og-url=&quot;https://github.com/baryon/tracer&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://github.com/baryon/tracer&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/baryon/tracer&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;GitHub - baryon/tracer: A powerful and customizable logging library for node.js&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A powerful and customizable logging library for node.js - GitHub - baryon/tracer: A powerful and customizable logging library for node.js&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Nodejs</category>
      <category>logging</category>
      <category>tracer</category>
      <category>tracer 모듈</category>
      <category>라인</category>
      <category>로깅</category>
      <category>로깅 라인 출력</category>
      <category>로깅 파일 저장</category>
      <category>로깅 파일명 출력</category>
      <category>파일명</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/29</guid>
      <comments>https://mintaku.tistory.com/29#entry29comment</comments>
      <pubDate>Tue, 24 Aug 2021 20:29:17 +0900</pubDate>
    </item>
    <item>
      <title>Ajax 통신시 제한시간 설정 및 로딩 아이콘 표시하기</title>
      <link>https://mintaku.tistory.com/28</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;ajax 통신시 제한시간 설정 및 로딩 아이콘 표시하기&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;로딩 아이콘 CSS 설정(&lt;a href=&quot;https://story.pxd.co.kr/922&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;샘플 참고 사이트&lt;/a&gt;)&lt;br /&gt;
&lt;pre id=&quot;code_1628925142080&quot; class=&quot;css&quot; data-ke-language=&quot;css&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/* &amp;lt;style&amp;gt; (css) */
.loading {
	display: inline-block;
	width: 30px;
	height: 30px;
	border: 3px solid rgba(255,255,255,.3);
	border-radius: 50%;
	border-top-color: #fff;
	animation: spin 1s ease-in-out infinite;
	-webkit-animation: spin 1s ease-in-out infinite;
}
@keyframes spin {
	to { -webkit-transform: rotate(360deg); }
}
@-webkit-keyframes spin {
	to { -webkit-transform: rotate(360deg); }
}&lt;/code&gt;&lt;/pre&gt;
- style 태그 혹은 css 파일에 loading 클래스를 정의한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Javascript ajax 통신 설정&lt;br /&gt;
&lt;pre id=&quot;code_1628925567986&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$.ajax({
	url: '/login',
	type: 'post',
	contentType: 'application/json:chrset=utf-8',
	data: JSON.stringify({data: sendData}),
	success: function(resData) {
		alert('성공!');
	},
	beforeSend: function() {
		$('#btnLogin').html('&amp;lt;div class=&quot;loading&quot;&amp;gt;&amp;lt;/div&amp;gt;');
		$('#btnLogin').attr('disabled',true);
	},
	complete: function() {
		$('#btnLogin').text('Log in');
		$('#btnLogin').attr('disabled',false);
	},
	error: function(request, status, error) { // 오류가 발생했을 때 호출된다.
		if(error === 'timeout'){
			alert('서버 응답 제한시간 초과');
		}else{
			alert('아이디 혹은 비밀번호를 확인해주세요.');
		}
	}
	,timeout: 5000 // 서버 응답 제한시간 5초
});​&lt;/code&gt;&lt;/pre&gt;
- beforeSend : 요청에 대한 응답을 받기 전에 실행된다.&lt;br /&gt;- complete : 요청에 대한 응답이 오면 실행된다.&lt;br /&gt;- timeout : 서버 응답 제한시간을 밀리초로 설정하여 제한시간이 초과하면 timeout 오류를 발생시킨다.&lt;br /&gt;- 따라서 beforeSend 에서 loading 클래스를 가진 div 를 보여주고, complete 에서 다시 안보이게 하면 된다.&lt;br /&gt;- 응답 제한시간은 timeout 으로 설정한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제 코드처럼 작성할 경우, 응답을 5초간 기다리며&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;91&quot; data-origin-height=&quot;53&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dM9g1R/btrb5n5wKIR/gxwgXPHNkkFHStYfQM3vX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dM9g1R/btrb5n5wKIR/gxwgXPHNkkFHStYfQM3vX1/img.png&quot; data-alt=&quot;돌아가는 로딩 아이콘&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dM9g1R/btrb5n5wKIR/gxwgXPHNkkFHStYfQM3vX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdM9g1R%2Fbtrb5n5wKIR%2FgxwgXPHNkkFHStYfQM3vX1%2Fimg.png&quot; data-origin-width=&quot;91&quot; data-origin-height=&quot;53&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;돌아가는 로딩 아이콘&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 나오며 클릭이 제한되고, 응답 제한시간이 초과되거나 응답이 도착하면 기존처럼 돌아간다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;79&quot; data-origin-height=&quot;37&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XOTGf/btrb7ySOyGN/MCKmXbkqSKgsvv0jeBaMvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XOTGf/btrb7ySOyGN/MCKmXbkqSKgsvv0jeBaMvK/img.png&quot; data-alt=&quot;기존, 완료된 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XOTGf/btrb7ySOyGN/MCKmXbkqSKgsvv0jeBaMvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXOTGf%2Fbtrb7ySOyGN%2FMCKmXbkqSKgsvv0jeBaMvK%2Fimg.png&quot; data-origin-width=&quot;79&quot; data-origin-height=&quot;37&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;기존, 완료된 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Nodejs</category>
      <category>ajax</category>
      <category>beforeSend</category>
      <category>complete</category>
      <category>javascript</category>
      <category>Timeout</category>
      <category>로딩</category>
      <category>로딩아이콘</category>
      <category>제한시간</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/28</guid>
      <comments>https://mintaku.tistory.com/28#entry28comment</comments>
      <pubDate>Sat, 14 Aug 2021 17:08:06 +0900</pubDate>
    </item>
    <item>
      <title>HTML CSS 글자(폰트)에 테두리, 그림자 넣기</title>
      <link>https://mintaku.tistory.com/27</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;각종 태그에서 border 속성을 통해 테두리를 넣을 수 있듯이 글자에도 비슷한 속성이 있다.&lt;br /&gt;text-shadow 속성인데, 이를 이용하여 그림자는 물론이고 테두리까지 넣을 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;글자 테두리 넣는 방법&lt;/h3&gt;
&lt;pre id=&quot;code_1628216448878&quot; class=&quot;html xml&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;span style=&quot;text-shadow: -1px 0 #000, 0 1px #000, 1px 0 #000, 0 -1px #000;&quot;&amp;gt;
	테두리 스타일
&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 각각 순서대로 왼쪽, 아래, 오른쪽, 위쪽을 그려준다.&lt;br /&gt;- 'x축 position / y축 position / 색상' 혹은 '가로 위치 / 세로 위치 / 색상' 으로 이해하면 되겠다.&lt;br /&gt;- 추가로, 색상 전에 픽셀 단위를 한번 더 적어서 번짐 정도를 지정할 수 있다. 아래 그림자 넣는 방법에서는 번짐도 이용한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;글자 그림자 넣는 방법&lt;/h3&gt;
&lt;pre id=&quot;code_1628216480280&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;span style=&quot;text-shadow:1px 1px 1px #000;&quot;&amp;gt;
	그림자 스타일
&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 똑같이 'x축 position / y축 position / 색상' 혹은 '가로 위치 / 세로 위치 / 색상' 에서 번짐 정도를 추가한 것이며 오른쪽 아래로 한쪽 방향에만 그린 것이다. 다시 말해, '가로 위치 / 세로 위치 / 번짐 정도 / 색상 순서이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;결과&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배경색과 글자 색상이 비슷하여 가독성에 문제가 생겼다.&amp;nbsp; 흰색 바탕에 노란색의 경우이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;84&quot; data-origin-height=&quot;62&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clZQvX/btrbor7ICRL/9e39XoMHPbmA7o8Mjw3rKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clZQvX/btrbor7ICRL/9e39XoMHPbmA7o8Mjw3rKK/img.png&quot; data-alt=&quot;기존 글자&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clZQvX/btrbor7ICRL/9e39XoMHPbmA7o8Mjw3rKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclZQvX%2Fbtrbor7ICRL%2F9e39XoMHPbmA7o8Mjw3rKK%2Fimg.png&quot; data-origin-width=&quot;84&quot; data-origin-height=&quot;62&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;기존 글자&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 노란색에서 색을 더 어둡게 하였지만 만족스럽지 않았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;87&quot; data-origin-height=&quot;66&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rN1i5/btrbkgFYPnn/iOl91OeYGkwwbcUcLYR6Rk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rN1i5/btrbkgFYPnn/iOl91OeYGkwwbcUcLYR6Rk/img.png&quot; data-alt=&quot;테두리를 추가한 글자&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rN1i5/btrbkgFYPnn/iOl91OeYGkwwbcUcLYR6Rk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrN1i5%2FbtrbkgFYPnn%2FiOl91OeYGkwwbcUcLYR6Rk%2Fimg.png&quot; data-origin-width=&quot;87&quot; data-origin-height=&quot;66&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;테두리를 추가한 글자&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테두리를 넣으니 확실히 가독성이 좋아졌다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;88&quot; data-origin-height=&quot;62&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mz5Eq/btrbtnceY8s/wawTLta8hZ0LwpJM1etWmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mz5Eq/btrbtnceY8s/wawTLta8hZ0LwpJM1etWmk/img.png&quot; data-alt=&quot;그림자를 추가한 글자&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mz5Eq/btrbtnceY8s/wawTLta8hZ0LwpJM1etWmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmz5Eq%2FbtrbtnceY8s%2FwawTLta8hZ0LwpJM1etWmk%2Fimg.png&quot; data-origin-width=&quot;88&quot; data-origin-height=&quot;62&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그림자를 추가한 글자&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테두리 만큼은 아니지만 구분은 되는 것 같다.&lt;/p&gt;</description>
      <category>개발/Nodejs</category>
      <category>CSS</category>
      <category>text-shadow</category>
      <category>그림자 스타일</category>
      <category>글씨 그림자</category>
      <category>글씨 테두리</category>
      <category>글자 그림자</category>
      <category>글자 테두리</category>
      <category>테두리 스타일</category>
      <category>폰트 그림자</category>
      <category>폰트 테두리</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/27</guid>
      <comments>https://mintaku.tistory.com/27#entry27comment</comments>
      <pubDate>Fri, 6 Aug 2021 19:41:19 +0900</pubDate>
    </item>
    <item>
      <title>Nodejs node-schedule 로 간단히 스케줄러 구현하기(기간 반복, 날짜 반복)</title>
      <link>https://mintaku.tistory.com/26</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;node-schedule 사용법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;npm install node-schedule&lt;/span&gt;&lt;br /&gt;- 프로젝트 경로에서 cmd 명령어로 node-schedule 모듈을 설치한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;스케줄러 선언 및 반복 규칙 지정하기&lt;br /&gt;
&lt;pre id=&quot;code_1628039775948&quot; class=&quot;javascript&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var nodeschedule = require('node-schedule');

// nodeschedule rule 지정. 
// '초 분 시 일 월 요일(0 과 7 은 일요일)'
// ex) '0 0 15 1 * *' &amp;lt;- 매월 1일 오후 3시 정각
const rule = '0 0 9 * * 1'; // 매주 월요일 오전 9시 정각​&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;- 초, 분, 시, 일, 월, 요일을 원하는 대로 표현하여 규칙을 지정할 수 있다.&lt;br /&gt;- * 표시는 매번 반복을 나타내고, 요일은 0을 일요일로 본다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;스케줄러 실행하기&lt;br /&gt;
&lt;pre id=&quot;code_1628039783974&quot; class=&quot;javascript&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nodeschedule.scheduleJob(rule, function(){
	// 수행할 작업
});​&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;- 원하는 작업을 구현하면 된다.&lt;br /&gt;- 주기적으로 데이터베이스에 특정 쿼리를 실행하거나, exe 파일을 실행해줄 수도 있고, cmd 명령어로 파이썬 파일을 실행할 수도 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;node-schedule 을 통해 매주 리포트 pdf 파일을 생성하고&lt;br /&gt;리포트 수신인에게 pdf 파일을 메일에 첨부하여 전송한 후&lt;br /&gt;해당 pdf 파일을 삭제하는 리포트 서버를 만든 적이 있는데,&lt;br /&gt;이 모듈 덕분에 과정과 결과가 만족스러웠다.&lt;/p&gt;</description>
      <category>개발/Nodejs</category>
      <category>node-schedule</category>
      <category>기간반복</category>
      <category>날짜반복</category>
      <category>메일발송서버</category>
      <category>반복실행</category>
      <category>스케줄러</category>
      <category>주기적으로 실행</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/26</guid>
      <comments>https://mintaku.tistory.com/26#entry26comment</comments>
      <pubDate>Wed, 4 Aug 2021 19:30:22 +0900</pubDate>
    </item>
    <item>
      <title>Nodejs nodemailer 로 이메일 보내기(파일 첨부)</title>
      <link>https://mintaku.tistory.com/25</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;Nodejs nodemailer 모듈로 이메일 보내는 방법&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;npm install nodemailer (npm install nodemailer fs)&lt;/span&gt;&lt;br /&gt;프로젝트 경로에서 cmd 명령어로 nodemailer 모듈을 설치한다.&lt;br /&gt;(pdf 파일 첨부할 경우 fs 모듈도 함께 설치)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;모듈 선언 및 transporter 생성&lt;br /&gt;
&lt;pre id=&quot;code_1627878651453&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const nodemailer = require('nodemailer');
// const { readFileSync, unlinkSync, stat, readdirSync } = require('fs'); // 파일을 다룰 경우

let transporter = nodemailer.createTransport({
	// 사용하고자 하는 서비스
	// service: 'gmail',
	host: senderSmtp, // 'smtp.gmail.com'
	port: senderPort, // 587
	auth: {
		user: senderEmail, // 'myemail@gmail.com'
		pass: senderPass, // 'password486!'
	}
});​&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;- 파일을 첨부할 경우 fs 모듈까지 추가로 선언한다.&lt;br /&gt;- SMTP 호스트, 포트, 발신자 이메일과 패스워드를 입력한다.&lt;/li&gt;
&lt;li&gt;메일 보내기&lt;br /&gt;
&lt;pre id=&quot;code_1627879965974&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// await 을 사용하려면 async function 안에 있어야 한다.
await transporter.sendMail({
	// 보내는 곳의 이름과, 메일 주소를 입력
	from: `&quot;`+senderName+`&quot; `+senderEmail, // `&quot;ME&quot; myemail@gmail.com`
	// 받는 곳의 메일 주소를 입력
	to: receivers, // ['one@gmail.com', 'two@gmail.com']
	// 보내는 메일의 제목을 입력
	subject: emailSubject, '제목입니다.'
	// 보내는 메일의 내용을 입력
	// text: 일반 text로 작성된 내용
	// text: 'just test text',
	// html: html로 작성된 내용
	html: emailHtml, // `&amp;lt;p&amp;gt;내용입니다.&amp;lt;/p&amp;gt;`
	// 첨부파일 정보 객체를 입력
	attachments: attachList
    // [
    //     {
	// 	       filename: pdfFile1, // 'file1.pdf'
	// 	       content: new Buffer(readFileSync('./pdfPath/' + pdfFile1), 'base64'), // fs 노드 모듈 사용
	// 	       contentType: 'application/pdf'
	//     },
    //     {
	// 	       filename: pdfFile2, // 'file2.pdf'
	// 	       content: new Buffer(readFileSync('./pdfPath/' + pdfFile2), 'base64'), // fs 노드 모듈 사용
	// 	       contentType: 'application/pdf'
	//     }
    // ]
});​&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;- 실제 메일을 전송하는 단계이다.&lt;br /&gt;- 발신자의 이름과 이메일 형식에 주의한다. (`&quot;Name&quot; account@gmail.com`)&lt;br /&gt;- 수신자는 리스트의 형태로 여러명에게 전송 가능하다.&lt;br /&gt;- 내용은 일반 문자로 적는 text 와 html 태그로 작성하는 html 옵션을 골라서 사용할 수 있다.&lt;br /&gt;- 첨부 파일도 여러개를 보낼 수 있지만, 용량 제한이 있다. (gmail smtp 의 경우 한 번에 총 25MB 이하만 첨부 가능)&lt;/li&gt;
&lt;li&gt;전체 예시 코드&lt;br /&gt;
&lt;pre id=&quot;code_1627880549843&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const nodemailer = require('nodemailer');
const { readFileSync, unlinkSync, stat, readdirSync } = require('fs');

const pdfFolderPath = &quot;./pdfPath/&quot;;

const emailSubject = &quot;제목입니다.&quot;;
const emailHtml = 
`&amp;lt;b&amp;gt;내용입니다.&amp;lt;/b&amp;gt;
&amp;lt;br/&amp;gt;
&amp;lt;b&amp;gt;첨부된 PDF 파일들을 다운로드하세요.&amp;lt;/b&amp;gt;`;

// PDF 파일을 메일에 첨부하여 보낸 뒤 삭제.
async function sendPDFMail(senderName,senderEmail,senderPass,senderSmtp,senderPort,receivers,matchedFileList){

	let matchedFileList = ['one.pdf','two.pdf'];
	// 첨부파일 리스트
	let attachList = [];
	for (let j = 0; j &amp;lt; matchedFileList.length; j++) { 
		const matchFile = matchedFileList[j];
		attachList.push({
			filename: matchFile,
			content: new Buffer(readFileSync(pdfFolderPath + matchFile), 'base64'),
			contentType: 'application/pdf'
		});
	}

	// 수신자에게 메일 전송
	let transporter = nodemailer.createTransport({
		// 사용하고자 하는 서비스
		// service: 'gmail',

		host: senderSmtp,
		port: senderPort,
		auth: {
			user: senderEmail,
			pass: senderPass,
		}
	});

	await transporter.sendMail({
		// 보내는 곳의 이름과, 메일 주소를 입력
		from: `&quot;`+senderName+`&quot; `+senderEmail,
		// 받는 곳의 메일 주소를 입력
		to: receivers,
		// 보내는 메일의 제목을 입력
		subject: emailSubject,
		// 보내는 메일의 내용을 입력
		// text: 일반 text로 작성된 내용
		// text: 'just test text',
		// html: html로 작성된 내용
		html: emailHtml,
		// 첨부파일 정보 객체를 입력
		attachments: attachList
	});
			

	// PDF 파일 삭제
	for (let j = 0; j &amp;lt; matchedFileList.length; j++) {
		const matchFile = matchedFileList[j];
		stat(pdfFolderPath + matchFile,(err,stat)=&amp;gt;{
			if(err == null){
				unlinkSync(pdfFolderPath + matchFile);
				console.log('PDF deleted');
			}else if(err.code === 'ENOENT'){
				console.log('---Delete Error! NO PDF FILE---');
			}else {
				console.log('Delete error code : ' + err.code);
			}
		});
	}
}​&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이해를 돕기 위한 주석과 예시 코드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SMTP 메일 설정에 대해서는 되어 있다고 가정하고 따로 기록하지 않는다.&lt;/p&gt;</description>
      <category>개발/Nodejs</category>
      <category>nodemailer</category>
      <category>SMTP</category>
      <category>메일발송</category>
      <category>메일전송</category>
      <category>이메일 보내기</category>
      <category>파일첨부</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/25</guid>
      <comments>https://mintaku.tistory.com/25#entry25comment</comments>
      <pubDate>Mon, 2 Aug 2021 19:26:54 +0900</pubDate>
    </item>
    <item>
      <title>유닉스(에포크) 시간 변환 사이트(epochconverter.com)</title>
      <link>https://mintaku.tistory.com/23</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.epochconverter.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;유닉스 시간 변환 사이트&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1627522883887&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;Epoch Converter&quot; data-og-description=&quot;Convert Unix Timestamps (and many other date formats) to regular dates.&quot; data-og-host=&quot;www.epochconverter.com&quot; data-og-source-url=&quot;https://www.epochconverter.com/&quot; data-og-url=&quot;https://www.epochconverter.com&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/zqa9s/hyK2FbYZlC/evtMpoMwaX6kJ5PKG9qSI1/img.png?width=1186&amp;amp;height=342&amp;amp;face=0_0_1186_342&quot;&gt;&lt;a href=&quot;https://www.epochconverter.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.epochconverter.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/zqa9s/hyK2FbYZlC/evtMpoMwaX6kJ5PKG9qSI1/img.png?width=1186&amp;amp;height=342&amp;amp;face=0_0_1186_342');&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;Epoch Converter&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Convert Unix Timestamps (and many other date formats) to regular dates.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.epochconverter.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;672&quot; data-origin-height=&quot;480&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pflqs/btraGGSZZ1o/7SZHLigg3IZKlbvM0vIWbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pflqs/btraGGSZZ1o/7SZHLigg3IZKlbvM0vIWbk/img.png&quot; data-alt=&quot;www.epochconverter.com&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pflqs/btraGGSZZ1o/7SZHLigg3IZKlbvM0vIWbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpflqs%2FbtraGGSZZ1o%2F7SZHLigg3IZKlbvM0vIWbk%2Fimg.png&quot; data-origin-width=&quot;672&quot; data-origin-height=&quot;480&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;www.epochconverter.com&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이지에 들어가면 바로 현재 시간이 유닉스 시간으로 변환되어 나타나고 바로 그 아래에 유닉스 시간을 변환하는 입력창과 버튼이 있다. 물론 그 아래에는 반대의 경우를 할 수 있는 창과 변환 버튼이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 그 아래엔 순서대로 특정 날짜 기준 년, 월, 일의 시작과 끝의 유닉스 시간을 볼 수 있는 메뉴와&lt;br /&gt;초 단위를 일, 시간, 분 단위로 계산해주는 메뉴가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 다음 아래로는 유닉스 시간이란 1970년 1월 1일 자정부터 경과한 초를 의미한다는 등의 간단한 소개 글이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 아래에 각 프로그램 언어 환경별 현재 유닉스 시간 얻는 법, 유닉스 시간으로 변환 방법, 유닉스 시간을 날짜로 변환하는 법에 대해 안내해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간편하게 이용하기에 정말 유용한 사이트인데다가, 유닉스 시간 또는 에포크 또는 유닉스 타임스탬프 등등 부르는 이름도 많은 이것에 대한 개념을 이해하기에도 좋은 웹 사이트라고 생각한다. (번역이라도 활용해 한번쯤 읽어보자)&lt;/p&gt;</description>
      <category>개발/꿀팁저장소</category>
      <category>epoch</category>
      <category>Epoch Converter</category>
      <category>epochconverter.com</category>
      <category>timestamp</category>
      <category>UNIX</category>
      <category>에포크</category>
      <category>에포크 시간</category>
      <category>유닉스 변환</category>
      <category>유닉스 시간</category>
      <category>유닉스 타임스탬프</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/23</guid>
      <comments>https://mintaku.tistory.com/23#entry23comment</comments>
      <pubDate>Sun, 1 Aug 2021 11:18:34 +0900</pubDate>
    </item>
    <item>
      <title>Nodejs 로그 저장하기(winston 모듈)</title>
      <link>https://mintaku.tistory.com/24</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;로깅을 위해 Nodejs 에서 가장 많이 사용되는 winston 모듈을 적용 및 테스트하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;winston 모듈로 로깅하면 로그 &lt;span style=&quot;color: #409d00;&quot;&gt;레벨별로 색상을 구분하여 출력&lt;/span&gt;할 수 있으며,&lt;br /&gt;레벨별, 날짜별로 &lt;b&gt;저장&lt;/b&gt;하고 &lt;b&gt;보관 기간 등 원하는 설정&lt;/b&gt;을 할 수가 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;winston 모듈 적용 방법&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;npm install winston winston-daily-rotate-file&lt;/span&gt;&lt;br /&gt;프로젝트 경로에서 cmd로 winston 과 winston-daily-rotate-file 모듈 설치 명령어를 입력한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;winston.js 작성&lt;br /&gt;
&lt;pre id=&quot;code_1627621145785&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const winston = require('winston');
const winstonDaily = require('winston-daily-rotate-file');

const logDir = 'logs';  // 로그 파일 저장 경로 설정
const { combine, timestamp, printf } = winston.format;

// Define log format
const logFormat = printf(info =&amp;gt; {
  return `${info.timestamp} ${info.level}: ${info.message}`;
});

/*
 * Log Level
 * error: 0, warn: 1, info: 2, http: 3, verbose: 4, debug: 5, silly: 6
 */
const logger = winston.createLogger({
  format: combine(
    timestamp({
      format: 'YYYY-MM-DD HH:mm:ss',
    }),
    logFormat,
  ),
  transports: [
    // info 레벨 로그를 저장할 파일 설정
    new winstonDaily({
      level: 'info',
      datePattern: 'YYYY-MM-DD',
      dirname: logDir,
      filename: `%DATE%.log`,
      maxFiles: 30,  // 30일치 로그 파일 저장
      zippedArchive: true, 
    }),
    // error 레벨 로그를 저장할 파일 설정
    new winstonDaily({
      level: 'error',
      datePattern: 'YYYY-MM-DD',
      dirname: logDir + '/error',  // error.log 파일은 error 폴더를 만들어 저장 
      filename: `%DATE%.error.log`,
      maxFiles: 30,
      zippedArchive: true,
    }),
  ],
});

// Production 환경이 아닌 경우(dev 등) 
if (process.env.NODE_ENV !== 'production') {
  logger.add(new winston.transports.Console({
    format: winston.format.combine(
      winston.format.colorize(),  // 색깔 넣어서 출력
      winston.format.simple(),  // `${info.level}: ${info.message} JSON.stringify({ ...rest })` 포맷으로 출력
    )
  }));
}

module.exports = logger;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;로거를 사용할 위치에서 import 하기&lt;br /&gt;
&lt;pre id=&quot;code_1627621354533&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const logger = require('./winston.js의 경로/winston');​&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;로깅하기&lt;br /&gt;
&lt;pre id=&quot;code_1627621518275&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;logger.info('GET /index !');

logger.error('Get index error occurred!');​&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;로그 확인&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;144&quot; data-origin-height=&quot;66&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVucfq/btraHZdVvXK/PAYZ70NjaaCCaRsj6HXvg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVucfq/btraHZdVvXK/PAYZ70NjaaCCaRsj6HXvg0/img.png&quot; data-alt=&quot;winston 로그 저장 폴더&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVucfq/btraHZdVvXK/PAYZ70NjaaCCaRsj6HXvg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVucfq%2FbtraHZdVvXK%2FPAYZ70NjaaCCaRsj6HXvg0%2Fimg.png&quot; data-origin-width=&quot;144&quot; data-origin-height=&quot;66&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;winston 로그 저장 폴더&lt;/figcaption&gt;
&lt;/figure&gt;
텍스트 파일 및 폴더가 잘 생성된다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Nodejs</category>
      <category>logger</category>
      <category>nodejs</category>
      <category>winston</category>
      <category>winston-daily-rotate-file</category>
      <category>로거</category>
      <category>로그저장</category>
      <category>로깅</category>
      <category>모듈</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/24</guid>
      <comments>https://mintaku.tistory.com/24#entry24comment</comments>
      <pubDate>Sat, 31 Jul 2021 00:02:00 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL 서버 초기 설정(5.로그 데이터 용량 자동 축소)</title>
      <link>https://mintaku.tistory.com/22</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;DB 로그 데이터 용량 자동 축소 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;SSMS(Microsoft SQL Server Management Studio)에서 DB 서버에 로그인 후 에이전트에서 새 작업을 추가한다.&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;378&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXfACi/btraBdbUJWR/CmBjs2eFVt0IMDGCR0DIB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXfACi/btraBdbUJWR/CmBjs2eFVt0IMDGCR0DIB1/img.png&quot; data-alt=&quot;SSMS 연결 &amp;amp;amp;ndash; [SQL Server 에이전트] &amp;amp;amp;ndash; [작업] 우클릭 &amp;amp;amp;ndash; [새 작업]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXfACi/btraBdbUJWR/CmBjs2eFVt0IMDGCR0DIB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXfACi%2FbtraBdbUJWR%2FCmBjs2eFVt0IMDGCR0DIB1%2Fimg.png&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;378&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSMS 연결 &amp;ndash; [SQL Server 에이전트] &amp;ndash; [작업] 우클릭 &amp;ndash; [새 작업]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;작업 이름 입력 후 범주에서 데이터베이스 유지 관리 선택&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;283&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCtPnO/btrax8hWRMI/t520jdu6qZxkLhK8691uU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCtPnO/btrax8hWRMI/t520jdu6qZxkLhK8691uU0/img.png&quot; data-alt=&quot;이름 입력 &amp;amp;amp;ndash; 범주 [데이터베이스 유지 관리]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCtPnO/btrax8hWRMI/t520jdu6qZxkLhK8691uU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCtPnO%2Fbtrax8hWRMI%2Ft520jdu6qZxkLhK8691uU0%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;283&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이름 입력 &amp;ndash; 범주 [데이터베이스 유지 관리]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;[단계] 탭에서 [새로 만들기]&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;284&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfWITB/btraBS6sdaS/Y48uY5QM9DD8GcoynLxXc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfWITB/btraBS6sdaS/Y48uY5QM9DD8GcoynLxXc1/img.png&quot; data-alt=&quot;[단계] 탭 &amp;amp;amp;ndash; [새로 만들기]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfWITB/btraBS6sdaS/Y48uY5QM9DD8GcoynLxXc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfWITB%2FbtraBS6sdaS%2FY48uY5QM9DD8GcoynLxXc1%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;284&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[단계] 탭 &amp;ndash; [새로 만들기]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;단계 이름 입력 및 [데이터베이스] 선택 후 명령 창에 아래의 쿼리 입력하고 [확인]&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;283&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSxVCB/btraEfmzgFn/m1Rd6G4aM1WIEWb44xdugK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSxVCB/btraEfmzgFn/m1Rd6G4aM1WIEWb44xdugK/img.png&quot; data-alt=&quot;단계 이름 입력 &amp;amp;amp;ndash; [데이터베이스] 선택 &amp;amp;amp;ndash; 명령 창에 shrink 쿼리 입력 후&amp;amp;amp;nbsp;[확인]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSxVCB/btraEfmzgFn/m1Rd6G4aM1WIEWb44xdugK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSxVCB%2FbtraEfmzgFn%2Fm1Rd6G4aM1WIEWb44xdugK%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;283&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;단계 이름 입력 &amp;ndash; [데이터베이스] 선택 &amp;ndash; 명령 창에 shrink 쿼리 입력 후&amp;nbsp;[확인]&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;pre id=&quot;code_1627520896135&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;use DB명
alter database DB명 Set recovery simple
go
dbcc shrinkdatabase ('DB명', 10)
go
dbcc shrinkfile ('DB명_log', 1)
go
alter database DB명 set recovery full
go​&lt;/code&gt;&lt;/pre&gt;
&amp;nbsp;- dbcc shrinkdatabase('DB명', 10) 는 &lt;span style=&quot;color: #171717;&quot;&gt;데이터베이스를 축소한 후 데이터베이스에 남겨둘 여유 공간의 비율을 10%로 설정한다는 의미이다.&lt;br /&gt;&lt;/span&gt;- dbcc shrinkfile('DB명_log', 1) 은 로그 파일을 1MB 크기로 축소한다는 의미이다.&lt;/li&gt;
&lt;li&gt;[일정] 탭에서 [새로 만들기]&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;284&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b32xWk/btraEgMwkkO/NKp0q6YfxCKR6hrkDumQHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b32xWk/btraEgMwkkO/NKp0q6YfxCKR6hrkDumQHK/img.png&quot; data-alt=&quot;[일정] 탭 &amp;amp;amp;ndash; [새로 만들기]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b32xWk/btraEgMwkkO/NKp0q6YfxCKR6hrkDumQHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb32xWk%2FbtraEgMwkkO%2FNKp0q6YfxCKR6hrkDumQHK%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;284&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[일정] 탭 &amp;ndash; [새로 만들기]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;일정 이름 입력 후 되풀이 간격 및 수행할 시간을 설정하고 [확인] - [확인]&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;275&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kDqSJ/btraBehDnuZ/2Kjk0q9d6F7WLkn7aEZwm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kDqSJ/btraBehDnuZ/2Kjk0q9d6F7WLkn7aEZwm1/img.png&quot; data-alt=&quot;이름 입력 - 되풀이 [일별] &amp;amp;amp;ndash; 매 [1] &amp;amp;amp;ndash; 한 번 수행 [오전 9:10:00] &amp;amp;amp;ndash; [확인] &amp;amp;amp;ndash; [확인]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kDqSJ/btraBehDnuZ/2Kjk0q9d6F7WLkn7aEZwm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkDqSJ%2FbtraBehDnuZ%2F2Kjk0q9d6F7WLkn7aEZwm1%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;275&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이름 입력 - 되풀이 [일별] &amp;ndash; 매 [1] &amp;ndash; 한 번 수행 [오전 9:10:00] &amp;ndash; [확인] &amp;ndash; [확인]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/SQL</category>
      <category>dbcc</category>
      <category>db로그</category>
      <category>DB로그정리</category>
      <category>MSSQL</category>
      <category>shrinkdatabase</category>
      <category>SHRINKFILE</category>
      <category>SQL Server</category>
      <category>로그용량축소</category>
      <category>자동정리</category>
      <category>초기설정</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/22</guid>
      <comments>https://mintaku.tistory.com/22#entry22comment</comments>
      <pubDate>Fri, 30 Jul 2021 00:03:28 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL 서버 초기 설정(4.백업 파일 자동 삭제)</title>
      <link>https://mintaku.tistory.com/21</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;백업 파일 자동 삭제 설정&amp;nbsp;&lt;/span&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;SSMS(Microsoft SQL Server Management Studio) 에서 서버에 로그인 후&amp;nbsp; 유지 관리 계획 마법사 실행&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;378&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/94ZXd/btraqrPw8rx/9Y7EUjmSZkC8jpG5bYqrHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/94ZXd/btraqrPw8rx/9Y7EUjmSZkC8jpG5bYqrHK/img.png&quot; data-alt=&quot;SSMS&amp;amp;amp;nbsp;연결&amp;amp;amp;nbsp;&amp;amp;amp;ndash; [관리] &amp;amp;amp;ndash; [유지 관리 계획]&amp;amp;amp;nbsp;우클릭&amp;amp;amp;nbsp;&amp;amp;amp;ndash; [유지 관리 계획 마법사]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/94ZXd/btraqrPw8rx/9Y7EUjmSZkC8jpG5bYqrHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F94ZXd%2FbtraqrPw8rx%2F9Y7EUjmSZkC8jpG5bYqrHK%2Fimg.png&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;378&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSMS&amp;nbsp;연결&amp;nbsp;&amp;ndash; [관리] &amp;ndash; [유지 관리 계획]&amp;nbsp;우클릭&amp;nbsp;&amp;ndash; [유지 관리 계획 마법사]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;[다음]&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;247&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbU7MU/btrazMZW9yw/8kyMW5CO19X7k4xKZttTLK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbU7MU/btrazMZW9yw/8kyMW5CO19X7k4xKZttTLK/img.png&quot; data-alt=&quot;[다음]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbU7MU/btrazMZW9yw/8kyMW5CO19X7k4xKZttTLK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbU7MU%2FbtrazMZW9yw%2F8kyMW5CO19X7k4xKZttTLK%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;247&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[다음]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;이름 입력&amp;nbsp;&amp;ndash;&amp;nbsp;일정&amp;nbsp;[변경]&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;244&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Pkk7D/btraGOV8cYM/BuMk4CGK4So6sTsgmGIWw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Pkk7D/btraGOV8cYM/BuMk4CGK4So6sTsgmGIWw1/img.png&quot; data-alt=&quot;이름 입력&amp;amp;amp;nbsp; &amp;amp;amp;ndash;&amp;amp;amp;nbsp; 일정&amp;amp;amp;nbsp; [변경]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Pkk7D/btraGOV8cYM/BuMk4CGK4So6sTsgmGIWw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPkk7D%2FbtraGOV8cYM%2FBuMk4CGK4So6sTsgmGIWw1%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;244&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이름 입력&amp;nbsp; &amp;ndash;&amp;nbsp; 일정&amp;nbsp; [변경]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;되풀이 간격 및 시간 설정 &amp;ndash; [확인] &amp;ndash; [다음]&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;275&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GIVG5/btraFFZy3Eo/0kqitzJmpFyA7zbzxHZFKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GIVG5/btraFFZy3Eo/0kqitzJmpFyA7zbzxHZFKK/img.png&quot; data-alt=&quot;되풀이 [일별] &amp;amp;amp;ndash; 매 [1] &amp;amp;amp;ndash; 한 번 수행 [오전 9:10:00] &amp;amp;amp;ndash; [확인] &amp;amp;amp;ndash; [다음]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GIVG5/btraFFZy3Eo/0kqitzJmpFyA7zbzxHZFKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGIVG5%2FbtraFFZy3Eo%2F0kqitzJmpFyA7zbzxHZFKK%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;275&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;되풀이 [일별] &amp;ndash; 매 [1] &amp;ndash; 한 번 수행 [오전 9:10:00] &amp;ndash; [확인] &amp;ndash; [다음]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;[유지 관리 정리 태스크]&amp;nbsp;체크&amp;nbsp;&amp;ndash; [다음] &amp;ndash; [다음]&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;244&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C6dCN/btrawCC44KN/4AZfqNgQmxOQk7X4KruVb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C6dCN/btrawCC44KN/4AZfqNgQmxOQk7X4KruVb1/img.png&quot; data-alt=&quot;[유지 관리 정리 태스크] 체크 &amp;amp;amp;ndash; [다음] &amp;amp;amp;ndash; [다음]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C6dCN/btrawCC44KN/4AZfqNgQmxOQk7X4KruVb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC6dCN%2FbtrawCC44KN%2F4AZfqNgQmxOQk7X4KruVb1%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;244&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[유지 관리 정리 태스크] 체크 &amp;ndash; [다음] &amp;ndash; [다음]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;파일 보존 기간&amp;nbsp;설정 &amp;ndash; [다음] &amp;ndash; [다음] &amp;ndash; [마침] &amp;ndash;&amp;nbsp;성공 확인 후&amp;nbsp;[닫기]&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;441&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sfB2k/btrbh2HIDtY/vcRar4TI0Y1tTyGhVRcQQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sfB2k/btrbh2HIDtY/vcRar4TI0Y1tTyGhVRcQQk/img.png&quot; data-alt=&quot;백업폴더경로 지정 &amp;amp;amp;ndash; 확장명 bak 입력 - 파일 보존 기간 [3] [일] &amp;amp;amp;ndash; [다음] &amp;amp;amp;ndash; [다음] &amp;amp;amp;ndash; [마침] &amp;amp;amp;ndash; 성공 확인 후 [닫기]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sfB2k/btrbh2HIDtY/vcRar4TI0Y1tTyGhVRcQQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsfB2k%2Fbtrbh2HIDtY%2FvcRar4TI0Y1tTyGhVRcQQk%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;441&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;백업폴더경로 지정 &amp;ndash; 확장명 bak 입력 - 파일 보존 기간 [3] [일] &amp;ndash; [다음] &amp;ndash; [다음] &amp;ndash; [마침] &amp;ndash; 성공 확인 후 [닫기]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/SQL</category>
      <category>MSSQL</category>
      <category>SQL Server</category>
      <category>SSMS</category>
      <category>백업파일</category>
      <category>백업파일자동삭제</category>
      <category>백업파일정리</category>
      <category>유지관리</category>
      <category>자동삭제</category>
      <category>초기설정</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/21</guid>
      <comments>https://mintaku.tistory.com/21#entry21comment</comments>
      <pubDate>Thu, 29 Jul 2021 19:20:31 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL 서버 초기 설정(3.DB 자동 백업)</title>
      <link>https://mintaku.tistory.com/20</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;자동 백업 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;SSMS(Microsoft SQL Server Management Studio)에서 DB 서버에 로그인 후 &lt;br /&gt;유지 관리 계획 마법사 실행&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;222&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byEsiF/btrasVQihMd/QWDgQucg9u55F534NBUeY0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byEsiF/btrasVQihMd/QWDgQucg9u55F534NBUeY0/img.png&quot; data-alt=&quot;SSMS 연결 &amp;amp;amp;ndash; [관리] &amp;amp;amp;ndash; [유지 관리 계획] 우클릭 &amp;amp;amp;ndash; [유지 관리 계획 마법사]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byEsiF/btrasVQihMd/QWDgQucg9u55F534NBUeY0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyEsiF%2FbtrasVQihMd%2FQWDgQucg9u55F534NBUeY0%2Fimg.png&quot; data-origin-width=&quot;298&quot; data-origin-height=&quot;222&quot; data-filename=&quot;blob&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SSMS 연결 &amp;ndash; [관리] &amp;ndash; [유지 관리 계획] 우클릭 &amp;ndash; [유지 관리 계획 마법사]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;[다음] 클릭&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;247&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Bs3R6/btraHrsXLbf/5UjxOBRWrSPBH7kbvA0iG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Bs3R6/btraHrsXLbf/5UjxOBRWrSPBH7kbvA0iG1/img.png&quot; data-alt=&quot;[다음]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Bs3R6/btraHrsXLbf/5UjxOBRWrSPBH7kbvA0iG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBs3R6%2FbtraHrsXLbf%2F5UjxOBRWrSPBH7kbvA0iG1%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;247&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[다음]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;이름 입력 후 일정 [변경] 클릭&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;246&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgzGfg/btrav7XPeNH/HHHVOmP9zx3P9n9ukZiqi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgzGfg/btrav7XPeNH/HHHVOmP9zx3P9n9ukZiqi1/img.png&quot; data-alt=&quot;이름 입력 &amp;amp;amp;ndash; 일정 [변경]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgzGfg/btrav7XPeNH/HHHVOmP9zx3P9n9ukZiqi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgzGfg%2Fbtrav7XPeNH%2FHHHVOmP9zx3P9n9ukZiqi1%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;246&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이름 입력 &amp;ndash; 일정 [변경]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;1일마다, 2주마다 등 되풀이할 단위 간격을 정하고, 시간을 정한다.&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;274&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dYuFlc/btraFEfgEbA/tvkpCyTbPSklKlWn0oQfOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dYuFlc/btraFEfgEbA/tvkpCyTbPSklKlWn0oQfOk/img.png&quot; data-alt=&quot;되풀이 [일별] &amp;amp;amp;ndash; 매 [1] &amp;amp;amp;ndash; 한 번 수행 [오전 9:10:00] &amp;amp;amp;ndash; [확인] &amp;amp;amp;ndash; [다음]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dYuFlc/btraFEfgEbA/tvkpCyTbPSklKlWn0oQfOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdYuFlc%2FbtraFEfgEbA%2FtvkpCyTbPSklKlWn0oQfOk%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;274&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;되풀이 [일별] &amp;ndash; 매 [1] &amp;ndash; 한 번 수행 [오전 9:10:00] &amp;ndash; [확인] &amp;ndash; [다음]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;데이터베이스 백업(전체)에 체크 후 [다음] 클릭. [다음] 한번 더 클릭.&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;242&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5tDrI/btrazMr7hEN/qK4O9ej6zT7YTBsytd2GYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5tDrI/btrazMr7hEN/qK4O9ej6zT7YTBsytd2GYk/img.png&quot; data-alt=&quot;[데이터베이스 백업(전체)] 체크 &amp;amp;amp;ndash; [다음] &amp;amp;amp;ndash; [다음]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5tDrI/btrazMr7hEN/qK4O9ej6zT7YTBsytd2GYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5tDrI%2FbtrazMr7hEN%2FqK4O9ej6zT7YTBsytd2GYk%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;242&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[데이터베이스 백업(전체)] 체크 &amp;ndash; [다음] &amp;ndash; [다음]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;대상 데이터베이스를 선택해주고 확인 클릭.&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;354&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWUZuI/btraHsSW5Vz/KUa0vJewPM13NVMc7RmQC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWUZuI/btraHsSW5Vz/KUa0vJewPM13NVMc7RmQC1/img.png&quot; data-alt=&quot;[데이터베이스] &amp;amp;amp;ndash; [모든 데이터베이스] &amp;amp;amp;ndash; [확인]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWUZuI/btraHsSW5Vz/KUa0vJewPM13NVMc7RmQC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWUZuI%2FbtraHsSW5Vz%2FKUa0vJewPM13NVMc7RmQC1%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;354&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[데이터베이스] &amp;ndash; [모든 데이터베이스] &amp;ndash; [확인]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;[대상] 탭에서 백업파일을 저장할 경로 선택 후 [다음] 클릭.&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;351&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Br6se/btraGFkGNDq/8HdVNJ8TbvnmJkxgh0vt9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Br6se/btraGFkGNDq/8HdVNJ8TbvnmJkxgh0vt9K/img.png&quot; data-alt=&quot;[대상] 탭 &amp;amp;amp;ndash; [&amp;amp;amp;hellip;] 클릭 및 저장 폴더 선택 - 확장명 bak 입력 &amp;amp;amp;ndash; [다음] &amp;amp;amp;ndash; [다음] &amp;amp;amp;ndash; [마침] &amp;amp;amp;ndash; 성공 확인 후 [닫기]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Br6se/btraGFkGNDq/8HdVNJ8TbvnmJkxgh0vt9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBr6se%2FbtraGFkGNDq%2F8HdVNJ8TbvnmJkxgh0vt9K%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;351&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[대상] 탭 &amp;ndash; [&amp;hellip;] 클릭 및 저장 폴더 선택 - 확장명 bak 입력 &amp;ndash; [다음] &amp;ndash; [다음] &amp;ndash; [마침] &amp;ndash; 성공 확인 후 [닫기]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;[다음]&amp;nbsp;&amp;ndash;&amp;nbsp;[마침]&amp;nbsp;&amp;ndash;&amp;nbsp;성공&amp;nbsp;확인&amp;nbsp;후&amp;nbsp;[닫기]&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>개발/SQL</category>
      <category>DB 자동 백업</category>
      <category>MSSQL</category>
      <category>sql 서버</category>
      <category>데이터베이스 자동 백업</category>
      <category>유지 관리</category>
      <category>유지 관리 계획 마법사</category>
      <category>자동 백업</category>
      <category>초기설정</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/20</guid>
      <comments>https://mintaku.tistory.com/20#entry20comment</comments>
      <pubDate>Wed, 28 Jul 2021 00:58:08 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL 서버 초기 설정(2.에이전트 자동 실행)</title>
      <link>https://mintaku.tistory.com/19</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;SQL&amp;nbsp;Server&amp;nbsp;에이전트&amp;nbsp;자동&amp;nbsp;실행&amp;nbsp;설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;SQL&amp;nbsp;Server&amp;nbsp;Configuration&amp;nbsp;Manager(구성&amp;nbsp;관리자)&amp;nbsp;실행&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;SQL Server 서비스에서 에이전트 시작 및 시작모드 자동 설정&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;257&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GMTWU/btraFFrJscG/i5zSsmzWCj2SwtThXAMmB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GMTWU/btraFFrJscG/i5zSsmzWCj2SwtThXAMmB0/img.png&quot; data-alt=&quot;[SQL Server 서비스] &amp;amp;amp;ndash; SQL Server 에이전트 우클릭 &amp;amp;amp;ndash; [시작] &amp;amp;amp;ndash; SQL Server 에이전트 우클릭 &amp;amp;amp;ndash; [속성] &amp;amp;amp;ndash; 서비스 탭 &amp;amp;amp;ndash; 시작 모드 자동&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GMTWU/btraFFrJscG/i5zSsmzWCj2SwtThXAMmB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGMTWU%2FbtraFFrJscG%2Fi5zSsmzWCj2SwtThXAMmB0%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;257&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[SQL Server 서비스] &amp;ndash; SQL Server 에이전트 우클릭 &amp;ndash; [시작] &amp;ndash; SQL Server 에이전트 우클릭 &amp;ndash; [속성] &amp;ndash; 서비스 탭 &amp;ndash; 시작 모드 자동&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;SSMS(Microsoft SQL Server Management Studio) 에서 DB 서버 로그인&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;[새 쿼리] 클릭 후 입력&lt;br /&gt;
&lt;pre id=&quot;code_1627374381475&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sp_configure 'show advanced options', 1;

GO

RECONFIGURE;

GO

sp_configure 'Agent XPs', 1;

GO

RECONFIGURE;

GO​&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;실행&lt;/li&gt;
&lt;/ol&gt;</description>
      <category>개발/SQL</category>
      <category>MSSQL</category>
      <category>SQL Server 에이전트</category>
      <category>SQL 서버 초기설정</category>
      <category>에이전트</category>
      <category>에이전트 자동실행</category>
      <category>초기설정</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/19</guid>
      <comments>https://mintaku.tistory.com/19#entry19comment</comments>
      <pubDate>Wed, 28 Jul 2021 00:38:55 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL 서버 초기 설정(1.서버 메모리 할당 제한)</title>
      <link>https://mintaku.tistory.com/18</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;DB&amp;nbsp;서버&amp;nbsp;메모리&amp;nbsp;할당&amp;nbsp;제한&amp;nbsp;설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;399&quot; data-origin-height=&quot;452&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GooH2/btraGFSt7Vk/KGlqk3tVIrpaGgmilNK470/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GooH2/btraGFSt7Vk/KGlqk3tVIrpaGgmilNK470/img.png&quot; data-alt=&quot;서버 우클릭 - [속성]&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GooH2/btraGFSt7Vk/KGlqk3tVIrpaGgmilNK470/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGooH2%2FbtraGFSt7Vk%2FKGlqk3tVIrpaGgmilNK470%2Fimg.png&quot; data-origin-width=&quot;399&quot; data-origin-height=&quot;452&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;서버 우클릭 - [속성]&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSMS(Microsoft SQL Server Management Studio) 에서 DB 서버에 로그인 후 속성에 들어간다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;283&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cU5FAs/btraBSyyONa/ZNPwFkbLRqRecP5MzAUXW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cU5FAs/btraBSyyONa/ZNPwFkbLRqRecP5MzAUXW0/img.png&quot; data-alt=&quot;[메모리] 탭 - 최대 서버 메모리 입력&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cU5FAs/btraBSyyONa/ZNPwFkbLRqRecP5MzAUXW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcU5FAs%2FbtraBSyyONa%2FZNPwFkbLRqRecP5MzAUXW0%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;283&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[메모리] 탭 - 최대 서버 메모리 입력&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리 탭에서 MB 단위로 최대 서버 메모리를 입력하여 메모리 제한 설정을 한다.&lt;br /&gt;500~2000MB 정도면 적당하다.&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>개발/SQL</category>
      <category>MSSQL</category>
      <category>MSSQL 서버</category>
      <category>sql 서버</category>
      <category>SSMS</category>
      <category>메모리</category>
      <category>메모리 할당 제한</category>
      <category>메모리제한</category>
      <category>메모리할당</category>
      <category>초기설정</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/18</guid>
      <comments>https://mintaku.tistory.com/18#entry18comment</comments>
      <pubDate>Wed, 28 Jul 2021 00:31:01 +0900</pubDate>
    </item>
    <item>
      <title>MSSQL SQL Server 구성 관리자를 찾을 수 없는 경우</title>
      <link>https://mintaku.tistory.com/17</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;SQL Server Configuration Manager(구성 관리자) 를 실행하려는 경우에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시작 메뉴에서 Microsoft SQL Server 20-- 폴더 안에서 찾거나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우키 누르고 sql 까지만 쳐도 검색으로 나와서 쉽게 실행하지만,&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;&lt;b&gt;C:\Windows\Sys\WOW64&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;SQLServerManager--.msc&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;윈도우 키 + R&lt;/b&gt; (실행) 로 실행창을 열고 &lt;b&gt;SQLServerManager--.msc&lt;/b&gt; 라는 파일 명을 입력 후 확인을 누르면 실행된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;124&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBjoOw/btraGOIxDZo/6x4PS5XI6B7CWDAqQYhwG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBjoOw/btraGOIxDZo/6x4PS5XI6B7CWDAqQYhwG1/img.png&quot; data-alt=&quot;SQL Server 버전별 구성 관리자 파일명&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBjoOw/btraGOIxDZo/6x4PS5XI6B7CWDAqQYhwG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBjoOw%2FbtraGOIxDZo%2F6x4PS5XI6B7CWDAqQYhwG1%2Fimg.png&quot; data-origin-width=&quot;378&quot; data-origin-height=&quot;124&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SQL Server 버전별 구성 관리자 파일명&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버전명은 위를 참고하면 되고 버전을 모른다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSMS(Microsoft SQL Server Management Studio) 에서 DB 서버에 로그인하고 [새 쿼리] 버튼을 누른 후&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;select @@version&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이라고 입력 후 [실행]을 누르면 결과로 볼 수 있다.&lt;/p&gt;</description>
      <category>개발/SQL</category>
      <category>MSSQL</category>
      <category>SQL Server Configuration Manager</category>
      <category>SQL Server 버전</category>
      <category>SQLServerManager</category>
      <category>SQL버전</category>
      <category>구성관리자</category>
      <category>구성관리자 실행</category>
      <category>구성관리자 위치</category>
      <category>실행파일</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/17</guid>
      <comments>https://mintaku.tistory.com/17#entry17comment</comments>
      <pubDate>Tue, 27 Jul 2021 16:59:06 +0900</pubDate>
    </item>
    <item>
      <title>Nodejs 파일 선택하면 저장하기(multer 미들웨어)</title>
      <link>https://mintaku.tistory.com/16</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;823&quot; data-origin-height=&quot;508&quot; width=&quot;608&quot; height=&quot;375&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mEr2T/btraqSr4PIL/MWa9cKNk4cwAD354ySK3n1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mEr2T/btraqSr4PIL/MWa9cKNk4cwAD354ySK3n1/img.png&quot; data-alt=&quot;파일 선택창&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mEr2T/btraqSr4PIL/MWa9cKNk4cwAD354ySK3n1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmEr2T%2FbtraqSr4PIL%2FMWa9cKNk4cwAD354ySK3n1%2Fimg.png&quot; data-origin-width=&quot;823&quot; data-origin-height=&quot;508&quot; width=&quot;608&quot; height=&quot;375&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파일 선택창&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 input 태그를 통해 이미지 파일 선택을 하면, 해당 이미지 파일을 저장하는 업로드 기능을 구현하는 방법이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;파일 선택하면 저장하는 법&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;npm install multer&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;HTML - form 태그로 감싼 input 태그 만들기(name 중요)&lt;br /&gt;
&lt;pre id=&quot;code_1627262903647&quot; class=&quot;javascript&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;form id=&quot;imgForm&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;, action=&quot;/uploadImg&quot;&amp;gt;
  &amp;lt;input type=&quot;file&quot; id=&quot;inputImg&quot; name=&quot;myImg&quot; accept=&quot;.jpg,.png&quot;&amp;gt;
&amp;lt;/form&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;스크립트 - input 태그로 파일 선택을 하면 form 태그 submit 시키기&lt;br /&gt;
&lt;pre id=&quot;code_1627262938625&quot; class=&quot;javascript&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$('#inputImg').on('change',submit);

function submit() {
  $('#imgForm').submit();
}&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;app.js - multer 를 이용해 라우팅 처리하기&lt;br /&gt;
&lt;pre id=&quot;code_1627263069900&quot; class=&quot;javascript&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// app.js

var multer = require('multer');

var imgStorage = multer.diskStorage({
  destination: function(req, file, callback) {
    callback(null, 'public/img'); // 저장할 파일 경로
  },
  filename: function(req, file, callback) {
    fName = file.originalname; // 저장할 파일명 = 원래 파일명
    callback(null, fName);
  }
});

var imgUpload = multer({
  storage: imgStorage,
  fileFilter: function(req, file, callback) {
    var ext = path.extname(file.originalname);
    console.log('ext : '+ ext);
    if (ext !== '.png' &amp;amp;&amp;amp; ext !== '.jpg' &amp;amp;&amp;amp; ext !== '.JPG' &amp;amp;&amp;amp; ext !== '.PNG') {
      console.log('not png, jpg');
      //return callback(null, false);
    } else {
      console.log('correct png, jpg');
      callback(null, true);
    }
  }
});

app.post('/uploadImg', imgUpload.single('myImg'), function(req, res) { 
  res.json({done:1}); // 파일 업로드 후의 작업 작성
});&lt;/code&gt;&lt;/pre&gt;
- 주석으로 적어둔 파일 저장 경로와 파일명 그리고 파일 업로드 후의 작업을 상황에 맞게 작성하면 되겠다.&lt;br /&gt;- single() 함수는 단일 파일을 저장할 때 쓰이며, 파일이 여러개일 경우 array(), fields() 이라는 함수를 쓴다.&lt;br /&gt;- single() 의 파라미터로 input 태그의 name 을 입력해야 한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 포스팅한 이미지 파일 미리보기 기능과 연계하여, 미리보기 확인 후 업로드하는 기능을 만들어도 좋을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mintaku.tistory.com/13&quot;&gt;[개발/Nodejs] - jQuery 이미지 파일 선택시 보여주기&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Nodejs</category>
      <category>image</category>
      <category>input</category>
      <category>multer</category>
      <category>Single</category>
      <category>upload</category>
      <category>선택시 저장</category>
      <category>이미지업로드</category>
      <category>이미지저장</category>
      <category>파일선택</category>
      <category>파일저장</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/16</guid>
      <comments>https://mintaku.tistory.com/16#entry16comment</comments>
      <pubDate>Tue, 27 Jul 2021 00:12:32 +0900</pubDate>
    </item>
    <item>
      <title>자바스크립트 비동기 실행순서 보장 그냥 간단히 따라하기</title>
      <link>https://mintaku.tistory.com/15</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;505&quot; width=&quot;405&quot; height=&quot;377&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKqHFM/btral6QSDzk/ZJ07gNFkVMeRIhKc2CGVI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKqHFM/btral6QSDzk/ZJ07gNFkVMeRIhKc2CGVI1/img.png&quot; data-alt=&quot;순서를 지켜라&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKqHFM/btral6QSDzk/ZJ07gNFkVMeRIhKc2CGVI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKqHFM%2Fbtral6QSDzk%2FZJ07gNFkVMeRIhKc2CGVI1%2Fimg.png&quot; data-origin-width=&quot;542&quot; data-origin-height=&quot;505&quot; width=&quot;405&quot; height=&quot;377&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;순서를 지켜라&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 자바스크립트의 비동기적 특성 때문에 내가 원하는 순서대로 실행되지 않는다는 것을 깨달았을 때,&lt;br /&gt;실행 순서는 보장 받고 싶지만 동기, 비동기, Promise, then, async, await 다 무슨 말인지 모르겠고 무서웠다.&lt;br /&gt;아니면 콜백함수로 다 처리해버리면 된다는데 또 콜백지옥 얘기를 꺼내며 다들 안좋단다.&lt;br /&gt;그래서 그 때의 나에게 해결책을 제시해주듯이 간단히 따라할 수 있도록 정리해보겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;Play() 함수 안에서,&lt;/i&gt;&lt;br /&gt;&lt;i&gt;showFirst() -&amp;gt; showSecond() -&amp;gt; showThird() 의 순서로 실행되기를 원하는데&lt;/i&gt;&lt;br /&gt;&lt;i&gt;showFirst() -&amp;gt; showThird() -&amp;gt; showSecond() 의 순서로 실행되고 있는 상황으로 가정한다.&lt;/i&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;해결책 1. async await 그냥 따라하기&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;async 붙이고 await 붙이기&lt;br /&gt;
&lt;pre id=&quot;code_1627016494228&quot; class=&quot;javascript&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 기존 함수
function Play() {
	showFirst();
    showSecond();
    showThird();
}

// async
async function Play() {
	showFirst();
    await showSecond();
    showThird();
}&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;- Play 함수 선언 전에 async 를 붙이고 문제의 showSecond 함수 사용 전에 await 을 붙인다.&lt;br /&gt;- 이 상태로는 showSecond 가 일반 함수라면 아무런 효과가 없다. showSecond 를 Promise 함수로 바꿔줘야 한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Promise 함수로 바꾸기&lt;br /&gt;
&lt;pre id=&quot;code_1627016546479&quot; class=&quot;javascript&quot; style=&quot;display: block; overflow: auto; padding: 20px; color: #383a42; background: #f8f8f8; font-size: 14px; font-family: 'SF Mono', Menlo, Consolas, Monaco, monospace; border: 1px solid #ebebeb; line-height: 1.71; margin: 20px auto 0px; cursor: default; z-index: 1; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 기존 함수
function showSecond() {
  alert(&quot;Second!&quot;);
}

// Promise
function showSecond() {
  return new Promise(function(resolve,reject){
    alert(&quot;Second!&quot;);
    resolve(); // resolve(&quot;second&quot;) 처럼 값을 return 시킬 수 있다.
  });
}&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;- 기존 함수의 실행 부분을 return new Promise(function(resolve,reject){ }); 이것으로 감싼다.&lt;br /&gt;- 함수를 종료시킬 resolve() 는 필수이며, 이것은 파라미터 값을 return 한다.&lt;/li&gt;
&lt;li&gt;끝&lt;br /&gt;- 생각보다 쉽다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;해결책 2. async.waterfall 노드 모듈 사용하기&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;npm install async&lt;/span&gt;&lt;br /&gt;- 프로젝트 경로에서 cmd 명령어로 async 모듈을 설치한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;waterfall 로 감싸기&lt;br /&gt;
&lt;pre id=&quot;code_1627017254549&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 기존 함수
function Play() {
	showFirst();
    showSecond();
    showThird();
}

// waterfall
function Play() {
  async.waterfall([
      showFirst,
      showSecond,
      showThird,
  ], function (err, result) {
      if(err)
          console.log(err);
      else
          console.log(&quot;작업 완료&quot;);
  });
}&lt;/code&gt;&lt;/pre&gt;
- async.waterfall([ ], function (err, result) { }); 의 대괄호에 순서대로 함수 이름을 적는다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;끝&lt;br /&gt;- 쉽다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발/Nodejs</category>
      <category>async</category>
      <category>await</category>
      <category>node module</category>
      <category>promise</category>
      <category>waterfall</category>
      <category>동기</category>
      <category>비동기</category>
      <category>순서</category>
      <category>실행순서</category>
      <category>자바스크립트</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/15</guid>
      <comments>https://mintaku.tistory.com/15#entry15comment</comments>
      <pubDate>Mon, 26 Jul 2021 00:08:23 +0900</pubDate>
    </item>
    <item>
      <title>Git LFS 깃허브 대용량(100MB) 파일 올리기</title>
      <link>https://mintaku.tistory.com/14</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;깃허브 저장소에는 용량 제한이 없지만, 파일 하나당 100메가의 제한이 있다.&lt;br /&gt;따라서, 파일이 50메가만 넘어가도 warning 메시지가 뜨고,&lt;br /&gt;100메가가 넘어가는 파일을 push 하려는 경우에 다음과 같은 에러 메시지가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;remote:&amp;nbsp;Resolving&amp;nbsp;deltas:&amp;nbsp;100%&amp;nbsp;(3/3),&amp;nbsp;completed&amp;nbsp;with&amp;nbsp;3&amp;nbsp;local&amp;nbsp;objects.&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;remote:&amp;nbsp;error:&amp;nbsp;GH001:&amp;nbsp;Large&amp;nbsp;files&amp;nbsp;detected.&amp;nbsp;You&amp;nbsp;may&amp;nbsp;want&amp;nbsp;to&amp;nbsp;try&amp;nbsp;Git&amp;nbsp;Large&amp;nbsp;File&amp;nbsp;Storage&amp;nbsp;-&amp;nbsp;https://git-lfs.github.com.&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;remote:&amp;nbsp;error:&amp;nbsp;Trace:&amp;nbsp;51efcb860cd7c76aa349c5f931ebc96bedfc30763349d284be7278a271fb56ae&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;remote:&amp;nbsp;error:&amp;nbsp;See&amp;nbsp;http://git.io/iEPt8g&amp;nbsp;for&amp;nbsp;more&amp;nbsp;information.&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;remote: error: File ***/***.exe is 144.19 MB; this exceeds GitHub's file size limit of 100.00 MB&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;To&amp;nbsp;https://github.com/***/***.git&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;&amp;nbsp;!&amp;nbsp;[remote&amp;nbsp;rejected]&amp;nbsp;main&amp;nbsp;-&amp;gt;&amp;nbsp;main&amp;nbsp;(pre-receive&amp;nbsp;hook&amp;nbsp;declined)&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;error:&amp;nbsp;failed&amp;nbsp;to&amp;nbsp;push&amp;nbsp;some&amp;nbsp;refs&amp;nbsp;to&amp;nbsp;'https://github.com/***/***.git'&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;50메가는 넘고 100메가는 넘지 않아 뜨는 warning 메시지는 상관 없지만,&lt;br /&gt;위와 같이 100메가가 넘어서 error 메시지가 발생할 경우 메시지가 안내하는 것과 같이 Git LFS 익스텐션을 이용한 작업이 필요하다. 원리는 대용량 파일을 잘게 쪼개 관리한다는 내용이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;해결방법&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Git LFS 설치(링크 : &lt;a href=&quot;https://git-lfs.github.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Git LFS 다운로드 페이지&lt;/a&gt;)&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;440&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pYbTB/btramgSKhcv/WFSny4pGTGR35SfNvyvWWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pYbTB/btramgSKhcv/WFSny4pGTGR35SfNvyvWWK/img.png&quot; data-alt=&quot;Git LFS download page&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pYbTB/btramgSKhcv/WFSny4pGTGR35SfNvyvWWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpYbTB%2FbtramgSKhcv%2FWFSny4pGTGR35SfNvyvWWK%2Fimg.png&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;440&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Git LFS download page&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;git lfs install&lt;br /&gt;- 로컬 프로젝트 경로에서 cmd 로 설치 명령을 입력한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;git lfs track &quot;***.exe&quot;&lt;br /&gt;- 100MB 이상의 파일을 lfs 로 관리 등록을 한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;git commit -m &quot;메시지&quot;&lt;br /&gt;- 다시 커밋한다.&lt;br /&gt;- 이전에 100MB 이상 파일을 커밋한 적이 없다면 이대로 push 하면 된다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;BFG Repo-Cleaner 다운로드 (링크 : &lt;a href=&quot;https://rtyley.github.io/bfg-repo-cleaner/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;BFG-Repo-Cleaner 다운로드 페이지&lt;/a&gt;)&lt;br /&gt;- LFS 적용 이전에 100MB 이상 파일을 커밋한 적이 있다면 LFS 적용 후에도 여전히 에러 메시지가 발생하기 때문에,&lt;br /&gt;bfq-***.jar 파일의 도움을 받아 없애기 위해 다운로드한다.&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;357&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QtM8t/btraknR74Ov/Eh1MkimfYNuDjzegarqoZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QtM8t/btraknR74Ov/Eh1MkimfYNuDjzegarqoZ0/img.png&quot; data-alt=&quot;BFG Repo-Cleaner download page&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QtM8t/btraknR74Ov/Eh1MkimfYNuDjzegarqoZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQtM8t%2FbtraknR74Ov%2FEh1MkimfYNuDjzegarqoZ0%2Fimg.png&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;357&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;BFG Repo-Cleaner download page&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;java -jar bfg-***.jar --strip-blobs-bigger-than 100M .git&lt;br /&gt;- 다운로드 받은 jar 파일을 로컬 프로젝트 경로로 옮기고 명령어를 실행한다.&lt;br /&gt;- 만약 아래와 같은 메시지가 나온다면,&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;Using repo : C:\***\***\.git &lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;Scanning&amp;nbsp;packfile&amp;nbsp;for&amp;nbsp;large&amp;nbsp;blobs:&amp;nbsp;2555 &lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;Scanning&amp;nbsp;packfile&amp;nbsp;for&amp;nbsp;large&amp;nbsp;blobs&amp;nbsp;completed&amp;nbsp;in&amp;nbsp;65&amp;nbsp;ms. &lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;Warning&amp;nbsp;:&amp;nbsp;no&amp;nbsp;large&amp;nbsp;blobs&amp;nbsp;matching&amp;nbsp;criteria&amp;nbsp;found&amp;nbsp;in&amp;nbsp;packfiles&amp;nbsp;-&amp;nbsp;does&amp;nbsp;the&amp;nbsp;repo&amp;nbsp;need&amp;nbsp;to&amp;nbsp;be&amp;nbsp;packed? &lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;Please&amp;nbsp;specify&amp;nbsp;tasks&amp;nbsp;for&amp;nbsp;The&amp;nbsp;BFG&amp;nbsp;: &lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;bfg 1.***.0 &lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;&lt;i&gt;Usage:&amp;nbsp;bfg&amp;nbsp;[options]&amp;nbsp;[&amp;lt;repo&amp;gt;]&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;git repack &amp;amp;&amp;amp; git gc 라고 명령어 입력 후, 다시 명령을 실행한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;git push&lt;br /&gt;- 이제 100MB 넘는 파일도 깃허브에 업로드 할 수 있다!&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Git</category>
      <category>100MB</category>
      <category>100메가</category>
      <category>BFG-Repo-Cleaner</category>
      <category>git-lfs</category>
      <category>github</category>
      <category>limit</category>
      <category>깃허브</category>
      <category>대용량</category>
      <category>용량제한</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/14</guid>
      <comments>https://mintaku.tistory.com/14#entry14comment</comments>
      <pubDate>Sun, 25 Jul 2021 08:45:21 +0900</pubDate>
    </item>
    <item>
      <title>포토샵 대체 웹 사이트(pixlr.com)</title>
      <link>https://mintaku.tistory.com/11</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pixlr.com/kr/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;온라인 사진 에디터&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1626768916119&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;온라인 사진 에디터 - Pixlr.com&quot; data-og-description=&quot;무료 &amp;amp; 프리미엄 온라인 사진 에디터를 만나보세요. 효과, 필터, 오버레이, 간단한 기능부터 고급형 기능까지 모두 담았어요. 대부분의 파일 형식 (PSD, PXD, JPeg, PNG - 투명, webP, SVG 등)을 지원해요. &quot; data-og-host=&quot;pixlr.com&quot; data-og-source-url=&quot;https://pixlr.com/kr/&quot; data-og-url=&quot;https://pixlr.com/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/kfgNJ/hyKWIfFaP1/5uRbtFBpjv7ZcskVPeIZdk/img.jpg?width=751&amp;amp;height=477&amp;amp;face=0_0_751_477&quot;&gt;&lt;a href=&quot;https://pixlr.com/kr/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pixlr.com/kr/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/kfgNJ/hyKWIfFaP1/5uRbtFBpjv7ZcskVPeIZdk/img.jpg?width=751&amp;amp;height=477&amp;amp;face=0_0_751_477');&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;온라인 사진 에디터 - Pixlr.com&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;무료 &amp;amp; 프리미엄 온라인 사진 에디터를 만나보세요. 효과, 필터, 오버레이, 간단한 기능부터 고급형 기능까지 모두 담았어요. 대부분의 파일 형식 (PSD, PXD, JPeg, PNG - 투명, webP, SVG 등)을 지원해요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pixlr.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;종종 이미지 편집을 간단히 하고 싶을 때, 유용한 웹 사이트이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;816&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/betznp/btq96EG2O8R/1ElrorekqfN7o6rcEaKyw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/betznp/btq96EG2O8R/1ElrorekqfN7o6rcEaKyw1/img.png&quot; data-alt=&quot;pixlr.com 메인 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/betznp/btq96EG2O8R/1ElrorekqfN7o6rcEaKyw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbetznp%2Fbtq96EG2O8R%2F1ElrorekqfN7o6rcEaKyw1%2Fimg.png&quot; data-origin-width=&quot;970&quot; data-origin-height=&quot;816&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;pixlr.com 메인 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인 화면에서 PIXLR E 버튼과 PIXLR X 버튼을 볼 수 있는데, 둘 다 무료이다.&lt;br /&gt;다만 E 는 포토샵처럼 기능이 많은 버전이고 X 는 기능이 적고 빠르고 쉽게 초심자가 작업할 수 있는 버전이라 한다.&lt;br /&gt;두 버전 간의 이동은 자유롭다. E 에서 작업하던 것을 X 에서 작업할 수 있고 그 반대 또한 가능하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;716&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DbcBV/btq91TEQLYH/BshzZ5Qqd9ZiUbeaNtLv5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DbcBV/btq91TEQLYH/BshzZ5Qqd9ZiUbeaNtLv5K/img.png&quot; data-alt=&quot;6일 전에 만들었던 그림&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DbcBV/btq91TEQLYH/BshzZ5Qqd9ZiUbeaNtLv5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDbcBV%2Fbtq91TEQLYH%2FBshzZ5Qqd9ZiUbeaNtLv5K%2Fimg.png&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;716&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;6일 전에 만들었던 그림&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;히스토리, 최근 작업 파일을 볼 수 있어 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무엇보다 그림판으로는 할 수 없는 배경을 투명으로 만드는 일이 가능하다는 것이 가장 큰 장점인 것 같다.&lt;br /&gt;게다가 무료이며, 설치가 필요하지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 바랄 것이 없다!&lt;/p&gt;</description>
      <category>개발/꿀팁저장소</category>
      <category>pixlr</category>
      <category>pixlr.com</category>
      <category>무료 포토샵</category>
      <category>온라인 포토샵</category>
      <category>웹 포토샵</category>
      <category>포토샵</category>
      <category>포토샵 대체</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/11</guid>
      <comments>https://mintaku.tistory.com/11#entry11comment</comments>
      <pubDate>Sat, 24 Jul 2021 15:30:41 +0900</pubDate>
    </item>
    <item>
      <title>jQuery 이미지 파일 선택시 보여주기</title>
      <link>https://mintaku.tistory.com/13</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;마우스 커서를 가져가면 파일 선택 버튼이 보이고, 이미지 파일을 선택하면 해당 이미지를 화면에 보여주는 미리보기 기능을 구현하는 방법에 대해 알아보겠다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HTML 레이아웃&lt;/h3&gt;
&lt;pre id=&quot;code_1626847265735&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;div id=&quot;imgBox&quot; style=&quot;min-height: 400px; min-width: 580px;&quot;&amp;gt;
	&amp;lt;div id=&quot;imgTag&quot; style=&quot;min-height: 400px; min-width: 580px; position: absolute;&quot;&amp;gt;&amp;lt;/div&amp;gt;
	&amp;lt;input type=&quot;file&quot; id=&quot;inputImg&quot; name=&quot;outo&quot; accept=&quot;.jpg,.png&quot; style=&quot;position: absolute; top:181px; left: 63px; font-size: x-large;&quot; onchange=&quot;loadFile(this)&quot;&amp;gt;
&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;id 기준으로,&lt;br /&gt;- imgBox : 마우스 오버를 감지할 곳이다.&lt;br /&gt;- imgTag : 이미지 미리보기를 나타낼 곳이다.&lt;br /&gt;- inputImg : 파일을 입력 받을 input 태그이다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; jpg, png 형식만 accept 로 지정해 해당 확장명의 파일 선택을 유도한다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; onchange 시 파라미터로 this 를 넘겨주며 loadFile 함수를 실행한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;412&quot; width=&quot;441&quot; height=&quot;374&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vL821/btraclAn40x/Sg6cy0A0dzFrdC1AjGMKc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vL821/btraclAn40x/Sg6cy0A0dzFrdC1AjGMKc1/img.png&quot; data-alt=&quot;아무것도 보이지 않는 기본 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vL821/btraclAn40x/Sg6cy0A0dzFrdC1AjGMKc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvL821%2FbtraclAn40x%2FSg6cy0A0dzFrdC1AjGMKc1%2Fimg.png&quot; data-origin-width=&quot;485&quot; data-origin-height=&quot;412&quot; width=&quot;441&quot; height=&quot;374&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;아무것도 보이지 않는 기본 상태&lt;/figcaption&gt;
&lt;/figure&gt;
&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;/h3&gt;
&lt;pre id=&quot;code_1626847882524&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$('#imgBox').on('mouseover', function() {
  $('#inputImg').show();
});
$('#imgBox').on('mouseout', function() {
  $('#inputImg').hide();
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 마우스 커서를 올리면 파일선택 버튼 보여주고, 커서가 벗어나면 숨긴다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;427&quot; data-origin-height=&quot;314&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfCnMg/btracO3mOa8/omDkbsaqISgqAFkjySokE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfCnMg/btracO3mOa8/omDkbsaqISgqAFkjySokE0/img.png&quot; data-alt=&quot;마우스 커서를 올린 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfCnMg/btracO3mOa8/omDkbsaqISgqAFkjySokE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfCnMg%2FbtracO3mOa8%2FomDkbsaqISgqAFkjySokE0%2Fimg.png&quot; data-origin-width=&quot;427&quot; data-origin-height=&quot;314&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;마우스 커서를 올린 상태&lt;/figcaption&gt;
&lt;/figure&gt;
&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;/h3&gt;
&lt;pre id=&quot;code_1626848033191&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function loadFile(input) {
  var file = input.files[0];
  $('#imgTag').html(&quot; &amp;lt;img src='&quot;+URL.createObjectURL(file)+&quot;' style='max-height:432px; max-width:925px;'/&amp;gt; &quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 파일을 선택하면 실행되는 함수이다. 선택된 이미지를 나타낸다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;513&quot; data-origin-height=&quot;460&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IZWJz/btq96EO1RBt/u8kKtUryqRJs2tBZzWjap1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IZWJz/btq96EO1RBt/u8kKtUryqRJs2tBZzWjap1/img.png&quot; data-alt=&quot;파일 선택한 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IZWJz/btq96EO1RBt/u8kKtUryqRJs2tBZzWjap1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIZWJz%2Fbtq96EO1RBt%2Fu8kKtUryqRJs2tBZzWjap1%2Fimg.png&quot; data-origin-width=&quot;513&quot; data-origin-height=&quot;460&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파일 선택한 상태&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Nodejs</category>
      <category>createObjectURL</category>
      <category>img</category>
      <category>input</category>
      <category>jQuery</category>
      <category>mouseover</category>
      <category>마우스 감지</category>
      <category>마우스오버</category>
      <category>미리보기</category>
      <category>보여주기</category>
      <category>파일 선택</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/13</guid>
      <comments>https://mintaku.tistory.com/13#entry13comment</comments>
      <pubDate>Fri, 23 Jul 2021 00:13:29 +0900</pubDate>
    </item>
    <item>
      <title>Git 특정 버전으로 되돌렸다가 돌아오기(혹은 아예 되돌리기)</title>
      <link>https://mintaku.tistory.com/12</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;이전 버전 보고 돌아오기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;이전 커밋의 소스를 확인하고 싶을 경우, 두 가지 방법이 있다.&lt;/i&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;커밋 메시지 보고 특정 커밋으로 되돌리기&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;git log&lt;/span&gt;&lt;br /&gt;- 명령 입력 후, 위 아래 방향키로 원하는 버전 커밋 찾기&lt;br /&gt;- 'commit' 문구 뒤의 해시코드 앞에서 4자리 이상 복사&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;194&quot; data-origin-height=&quot;123&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bIWIVk/btq97aMWrKc/v4ln7S42Wy0kD6CTcwdo40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bIWIVk/btq97aMWrKc/v4ln7S42Wy0kD6CTcwdo40/img.png&quot; data-alt=&quot;git log 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bIWIVk/btq97aMWrKc/v4ln7S42Wy0kD6CTcwdo40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbIWIVk%2Fbtq97aMWrKc%2Fv4ln7S42Wy0kD6CTcwdo40%2Fimg.png&quot; data-origin-width=&quot;194&quot; data-origin-height=&quot;123&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;git log 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;git checkout 복사한 4자리 이상 해시코드&lt;/span&gt;&lt;br /&gt;- 현재 소스가 해당 버전으로 돌아간다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;git checkout 브랜치 이름&lt;/span&gt;&lt;br /&gt;- 되돌아오기(해당 브랜치의 최신 커밋으로 돌리기)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;단계별로 되돌아가기&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;git checkout head~1&lt;/span&gt;&lt;br /&gt;- 최신 커밋으로부터 한단계 전으로 되돌린다.&lt;br /&gt;- 1에 해당하는 부분을 바꿔서 원하는 단계만큼 지정할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;git checkout 브랜치 이름&lt;/span&gt;&lt;br /&gt;- 되돌아오기(해당 브랜치의 최신 커밋으로 돌리기)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;이전 버전으로 되돌리기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;되돌렸다가 돌아오지 않고 아예 되돌리고 싶은 경우에도 두 가지 방법이 있지만, &lt;/i&gt;&lt;br /&gt;&lt;i&gt;웬만하면 revert 를 권장한다.&lt;/i&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;되돌리는 버전을 새로 커밋하기(권장 O)&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;background-color: #000000; color: #ffffff;&quot;&gt;git revert head~1 혹은 git revert 커밋해시코드&lt;/span&gt;&lt;br /&gt;- 앞서 설명한 checkout 의 두 가지 방법 모두 똑같이 revert 에 적용 가능하다.&lt;br /&gt;- revert 명령시 해당 커밋 버전으로 새로 커밋하게 되므로, 커밋 메시지 입력창이 나타난다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;(i 입력 후 커밋메시지 수정하기. :wq 입력하여 저장 후 종료하기.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;되돌리는 버전 이후의 커밋을 삭제하기(권장 X)&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;git reset --hard head~1 혹은 git reset --hard 커밋해시코드&lt;/span&gt;&lt;br /&gt;- 앞서 설명한 checkout 의 두 가지 방법 모두 똑같이 reset 에도 에 적용 가능하다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;남아있는 추가됐던 파일 지우기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Git</category>
      <category>checkout</category>
      <category>Git</category>
      <category>RESET</category>
      <category>revert</category>
      <category>과거</category>
      <category>되돌리기</category>
      <category>되돌아오기</category>
      <category>버전</category>
      <category>이전</category>
      <category>커밋</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/12</guid>
      <comments>https://mintaku.tistory.com/12#entry12comment</comments>
      <pubDate>Thu, 22 Jul 2021 00:20:48 +0900</pubDate>
    </item>
    <item>
      <title>AWS Cognito user pools(사용자 풀) 사용법</title>
      <link>https://mintaku.tistory.com/10</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Nodejs 환경 기준으로 작성하지만, 혹여 다른 환경일지라도 아마존 코그니토 사용자 풀을 처음 써보려는 사람에게는 이 글이 분명 도움될 것이라 생각한다.&lt;br /&gt;처음부터 끝까지 세세한 설명보다는, 길어보이지만 짧은 이 글을 읽고 나면 스스로 코그니토 API 를 찾고 사용하여 개발할 수 있게끔 설명하는 것이 목적이다.&lt;br /&gt;생각보다 자세하거나 쉽게 설명한 글이 보이지 않아서 직접 알아보고 시행 착오를 겪으며 시작이 오래 걸렸지만, 이 글을 읽는 누군가는 금방 시작할 수 있다거나, 한줄기 희망으로 느껴졌으면 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 sns 연동은 다루지 않았다. 추후에 이를 다룬 포스팅을 업로드할 생각은 있다.&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;기본&amp;nbsp;사용&amp;nbsp;환경&amp;nbsp;구축&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;AWS&amp;nbsp;Cognito&amp;nbsp;user&amp;nbsp;pools(사용자&amp;nbsp;풀)&amp;nbsp;생성&lt;br /&gt;- 링크 참조 : (&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/cognito/latest/developerguide/cognito-user-pool-as-user-directory.html&quot;&gt;코그니토 사용자 풀 생성 가이드 페이지)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;사용자&amp;nbsp;풀&amp;nbsp;정보&amp;nbsp;확인&lt;br /&gt;- 사용자 풀 ID, (사용자 풀 ID에 포함된)지역을 확인한다.&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;1893&quot; data-origin-height=&quot;744&quot; data-filename=&quot;userpool_1.jpg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0DncY/btq91NKZuuK/ithF0M3W4IJOZZdNvWEaKk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0DncY/btq91NKZuuK/ithF0M3W4IJOZZdNvWEaKk/img.jpg&quot; data-alt=&quot;AWS - Cognito - 사용자 풀 관리 - 생성한 사용자 풀 - 일반 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0DncY/btq91NKZuuK/ithF0M3W4IJOZZdNvWEaKk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0DncY%2Fbtq91NKZuuK%2FithF0M3W4IJOZZdNvWEaKk%2Fimg.jpg&quot; data-origin-width=&quot;1893&quot; data-origin-height=&quot;744&quot; data-filename=&quot;userpool_1.jpg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS - Cognito - 사용자 풀 관리 - 생성한 사용자 풀 - 일반 설정&lt;/figcaption&gt;
&lt;/figure&gt;
- 클라이언트 ID 를 확인한다.&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;1888&quot; data-origin-height=&quot;732&quot; data-filename=&quot;userpool_2.jpg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KUti0/btq9Tf9m0QG/eDPikvEZWkSFe1NONN9tlk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KUti0/btq9Tf9m0QG/eDPikvEZWkSFe1NONN9tlk/img.jpg&quot; data-alt=&quot;AWS - Cognito - 사용자 풀 관리 - 생성한 사용자 풀 - 앱 클라이언트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KUti0/btq9Tf9m0QG/eDPikvEZWkSFe1NONN9tlk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKUti0%2Fbtq9Tf9m0QG%2FeDPikvEZWkSFe1NONN9tlk%2Fimg.jpg&quot; data-origin-width=&quot;1888&quot; data-origin-height=&quot;732&quot; data-filename=&quot;userpool_2.jpg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS - Cognito - 사용자 풀 관리 - 생성한 사용자 풀 - 앱 클라이언트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;AWS&amp;nbsp;계정&amp;nbsp;액세스&amp;nbsp;키&amp;nbsp;생성&amp;nbsp;및&amp;nbsp;정보&amp;nbsp;확인&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;1904&quot; data-origin-height=&quot;782&quot; data-filename=&quot;userpool_3.jpg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCHCHS/btq9Y5ZY5UK/OA7NAfi76O8a4c3oKWuJnK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCHCHS/btq9Y5ZY5UK/OA7NAfi76O8a4c3oKWuJnK/img.jpg&quot; data-alt=&quot;AWS - 내 보안 자격 증명 - 액세스 키 - 새 액세스 키 만들기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCHCHS/btq9Y5ZY5UK/OA7NAfi76O8a4c3oKWuJnK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCHCHS%2Fbtq9Y5ZY5UK%2FOA7NAfi76O8a4c3oKWuJnK%2Fimg.jpg&quot; data-origin-width=&quot;1904&quot; data-origin-height=&quot;782&quot; data-filename=&quot;userpool_3.jpg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS - 내 보안 자격 증명 - 액세스 키 - 새 액세스 키 만들기&lt;/figcaption&gt;
&lt;/figure&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;액세스&amp;nbsp;키를&amp;nbsp;만들어&amp;nbsp;사용해야&amp;nbsp;한다. &lt;br /&gt;-&amp;nbsp;'액세스&amp;nbsp;키&amp;nbsp;ID'&amp;nbsp;와&amp;nbsp;&amp;lsquo;액세스&amp;nbsp;키&amp;rsquo;&amp;nbsp;를&amp;nbsp;확인한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;프로젝트&amp;nbsp;내에&amp;nbsp;npm&amp;nbsp;모듈&amp;nbsp;설치&lt;br /&gt;&lt;i&gt;-&amp;nbsp;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;npm&amp;nbsp;install&amp;nbsp;aws-sdk &lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;-&amp;nbsp;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;npm&amp;nbsp;install&amp;nbsp;jwk-to-pem &lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;-&amp;nbsp;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;npm&amp;nbsp;install&amp;nbsp;jsonwebtoken &lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;-&amp;nbsp;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;npm&amp;nbsp;install&amp;nbsp;request&lt;/span&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;npm&amp;nbsp;모듈&amp;nbsp;import&lt;br /&gt;
&lt;pre id=&quot;code_1626751396668&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const AWS = require(&quot;aws-sdk&quot;);
const jwkToPem = require('jwk-to-pem');
const jwt = require('jsonwebtoken');
const request = require('request');​&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;계정,&amp;nbsp;사용자&amp;nbsp;풀&amp;nbsp;접근&amp;nbsp;정보&amp;nbsp;저장&lt;br /&gt;
&lt;pre id=&quot;code_1626751419610&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const CLIENT_ID = '3olbmrmgsip34dtj**********';
const ACCESS_KEY_ID = 'AKIAW5QD3C**********';
const SECERET_ACCESS_KEY = 'VIOJgaq6WUxL1BnjENSChkmMF3sVAi**********';
const REGION = 'ap-northeast-2';
const USERPOOL_ID = 'ap-northeast-2_hJ*******';​&lt;/code&gt;&lt;/pre&gt;
- 암호화 후, 별도 저장이 더 좋은 방법으로 보이나, 우선 코드 내 상수로 저장하였다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;접근&amp;nbsp;정보&amp;nbsp;설정&amp;nbsp;업데이트&amp;nbsp;및&amp;nbsp;CognitoIdentityServiceProvider&amp;nbsp;생성&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;REST&amp;nbsp;API&amp;nbsp;사용법&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;API&amp;nbsp;Documents&amp;nbsp;확인&lt;br /&gt;- 링크 참조 : (&lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/cognito-user-identity-pools/latest/APIReference/API_Operations.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;코그니토 API 문서 페이지&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;원하는&amp;nbsp;기능&amp;nbsp;조회&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;527&quot; data-filename=&quot;image-20210709-022243.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p79kn/btq91mUaxrh/iLLksSAJkHK9dfOEhz5tyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p79kn/btq91mUaxrh/iLLksSAJkHK9dfOEhz5tyk/img.png&quot; data-alt=&quot;AWS - Documentation - Amazon Cognito - API Reference&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p79kn/btq91mUaxrh/iLLksSAJkHK9dfOEhz5tyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp79kn%2Fbtq91mUaxrh%2FiLLksSAJkHK9dfOEhz5tyk%2Fimg.png&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;527&quot; data-filename=&quot;image-20210709-022243.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS - Documentation - Amazon Cognito - API Reference&lt;/figcaption&gt;
&lt;/figure&gt;
-&amp;nbsp;Actions&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;사용자&amp;nbsp;생성&amp;nbsp;기능을&amp;nbsp;예로,&amp;nbsp;AdminCreateUser&amp;nbsp;를&amp;nbsp;조회할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;&amp;lsquo;create&amp;nbsp;user&amp;rsquo;&amp;nbsp;등의&amp;nbsp;검색어로&amp;nbsp;검색해서&amp;nbsp;찾을&amp;nbsp;수도&amp;nbsp;있다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;기능&amp;nbsp;확인&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;1814&quot; data-origin-height=&quot;923&quot; data-filename=&quot;image-20210709-034633.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JzP8N/btq935qAmmz/JSjqhJoV4RzVRW62hW5j6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JzP8N/btq935qAmmz/JSjqhJoV4RzVRW62hW5j6k/img.png&quot; data-alt=&quot;AWS - Documentation - Amazon Cognito - API Reference - AdminCreateUser&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JzP8N/btq935qAmmz/JSjqhJoV4RzVRW62hW5j6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJzP8N%2Fbtq935qAmmz%2FJSjqhJoV4RzVRW62hW5j6k%2Fimg.png&quot; data-origin-width=&quot;1814&quot; data-origin-height=&quot;923&quot; data-filename=&quot;image-20210709-034633.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS - Documentation - Amazon Cognito - API Reference - AdminCreateUser&lt;/figcaption&gt;
&lt;/figure&gt;
-&amp;nbsp;조회한&amp;nbsp;api&amp;nbsp;가&amp;nbsp;원하던&amp;nbsp;기능인지&amp;nbsp;확인한다.&amp;nbsp;페이지&amp;nbsp;첫&amp;nbsp;문단이&amp;nbsp;해당&amp;nbsp;api&amp;nbsp;에&amp;nbsp;대한&amp;nbsp;설명이므로,&amp;nbsp;읽어보며&amp;nbsp;생각했던&amp;nbsp;기능이&amp;nbsp;맞는지&amp;nbsp;확인해야&amp;nbsp;한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;특성&amp;nbsp;및&amp;nbsp;속성&amp;nbsp;확인&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;1811&quot; data-origin-height=&quot;857&quot; data-filename=&quot;image-20210709-034956.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V9Z1i/btq9WqJzMH6/nlKlZbLZjhxGkI7dpkJSJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V9Z1i/btq9WqJzMH6/nlKlZbLZjhxGkI7dpkJSJk/img.png&quot; data-alt=&quot;AWS - Documentation - Amazon Cognito - API Reference - AdminCreateUser&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V9Z1i/btq9WqJzMH6/nlKlZbLZjhxGkI7dpkJSJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV9Z1i%2Fbtq9WqJzMH6%2FnlKlZbLZjhxGkI7dpkJSJk%2Fimg.png&quot; data-origin-width=&quot;1811&quot; data-origin-height=&quot;857&quot; data-filename=&quot;image-20210709-034956.png&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AWS - Documentation - Amazon Cognito - API Reference - AdminCreateUser&lt;/figcaption&gt;
&lt;/figure&gt;
-&amp;nbsp;페이지&amp;nbsp;우측에&amp;nbsp;내비게이션&amp;nbsp;바가&amp;nbsp;생긴&amp;nbsp;것을&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;-&amp;nbsp;Request&amp;nbsp;Syntax&amp;nbsp;:&amp;nbsp;요청&amp;nbsp;구문의&amp;nbsp;형식을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;-&amp;nbsp;Request&amp;nbsp;Parameters&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;Response&amp;nbsp;Syntax&amp;nbsp;:&amp;nbsp;응답&amp;nbsp;구문의&amp;nbsp;형식을&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;-&amp;nbsp;Response&amp;nbsp;Elements&amp;nbsp;:&amp;nbsp;성공시&amp;nbsp;응답&amp;nbsp;요소가&amp;nbsp;무엇인지&amp;nbsp;확인할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;-&amp;nbsp;Errors&amp;nbsp;:&amp;nbsp;발생하는&amp;nbsp;Exception을&amp;nbsp;확인하여&amp;nbsp;에러&amp;nbsp;처리를&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;api&amp;nbsp;사용&lt;br /&gt;
&lt;pre id=&quot;code_1626751788910&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cognitoIdentityServiceProvider.&amp;lt;API이름&amp;gt;(&amp;lt;API의 Request Syntax 객체&amp;gt;,function(err,data){
  if(err)
  {
    console.log(err);
  }
  else
  {
    console.log(data);
  }
});​&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;실제&amp;nbsp;사용&lt;br /&gt;
&lt;pre id=&quot;code_1626751840811&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//createUser
router.post('/createUser',function(req,res){
  req.on('data', function(chunk) {
    var datalist = JSON.parse(chunk).data;
    var userName = datalist[0];
    var email = datalist[1];
    var givenName = datalist[2];
    var familyName = datalist[3];
    var phoneNumber = datalist[4];
    const createUserParams =
    {
      &quot;UserPoolId&quot;: USERPOOL_ID,
      &quot;DesiredDeliveryMediums&quot;: [ &quot;EMAIL&quot; ],
      &quot;Username&quot;: userName,
      &quot;UserAttributes&quot;:
      [
        {
          &quot;Name&quot;: &quot;email&quot;,
          &quot;Value&quot;: email //이 메일로 인증메일이 가기 때문에 잘 적어줘야 한다.
        },
        {
          &quot;Name&quot;: &quot;given_name&quot;,
          &quot;Value&quot;: givenName
        },
        {
          &quot;Name&quot;: &quot;family_name&quot;,
          &quot;Value&quot;: familyName
        },
        {
          &quot;Name&quot;: &quot;phone_number&quot;,
          &quot;Value&quot;: &quot;+82&quot;+phoneNumber
        },
        {
          &quot;Name&quot;: &quot;email_verified&quot;,
          &quot;Value&quot;: &quot;true&quot;
        }
      ]
    };
    cognitoIdentityServiceProvider.adminCreateUser(createUserParams,function(err,data){
      if(err)
      {
        console.log(err);
        if(err.message.startsWith('User account already exists')){
          res.json({code:-1, msg:'이미 존재하는 아이디입니다.'});
        }else if(err.message.startsWith('An account with the email already exists')){
          res.json({code:-2, msg:'이미 등록된 이메일 주소입니다.'});
        }
      }
      else
      {
        console.log(data);
        res.json({code:0, msg:'계정 생성 안내 이메일이 발송되었습니다.'});
      }
    });
  });
});​&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;에러&amp;nbsp;처리에&amp;nbsp;관한&amp;nbsp;참고&amp;nbsp;사항&lt;br /&gt;-&amp;nbsp;API&amp;nbsp;Document&amp;nbsp;에서&amp;nbsp;Errors&amp;nbsp;항목을&amp;nbsp;보면&amp;nbsp;Exception&amp;nbsp;을&amp;nbsp;확인하여&amp;nbsp;에러&amp;nbsp;처리를&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다고&amp;nbsp;언급하였다.&lt;br /&gt;
&lt;pre id=&quot;code_1626751875381&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cognitoIdentityServiceProvider.confirmForgotPassword(confirmForgotPwdParams, function(err,data){
  if(err)
  {
    console.log('confirmForgotPassword Err : ');
    console.log(err);
    if(err.code === 'CodeMismatchException'){
      res.json({code:-2, msg:'유효하지 않은 확인코드입니다.'});  
    }else if(err.code === 'ExpiredCodeException') {
      res.json({code:-3, msg:'만료된 확인코드입니다.'});
    }else if(err.code === 'LimitExceededException') {
      res.json({code:-4, msg:'시도 횟수 초과입니다. 나중에 다시 시도하십시오.'});
    }else {
      res.json({code:-1, msg:'비밀번호 변경에 실패하였습니다.'});
    }
  }
  else
  {
    console.log('confirmForgotPassword OK : ');
    console.log(data);
    res.json({code:0, msg:'비밀번호가 변경되었습니다.'});
  }
});​&lt;/code&gt;&lt;/pre&gt;
-&amp;nbsp;위와&amp;nbsp;같이&amp;nbsp;Documents에&amp;nbsp;나오는&amp;nbsp;Exception&amp;nbsp;코드만으로&amp;nbsp;원하는&amp;nbsp;처리를&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;경우도&amp;nbsp;있었지만,&amp;nbsp; &lt;br /&gt;앞서&amp;nbsp;api&amp;nbsp;사용법&amp;nbsp;설명을&amp;nbsp;위해&amp;nbsp;예를&amp;nbsp;들었던&amp;nbsp;&amp;lsquo;AdminCreateUser&amp;rsquo;&amp;nbsp;같은&amp;nbsp;경우는,&amp;nbsp;같은&amp;nbsp;Exception&amp;nbsp;코드에서도&amp;nbsp;다른&amp;nbsp;경우를&amp;nbsp;구분해야&amp;nbsp;원하는&amp;nbsp;처리를&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있었다.- 이처럼 err.code(Exception 코드) 가 아닌 err.message(에러 메세지)로 구분하여 처리를 해야할 수도 있다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li id=&quot;code_1626751902861&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cognitoIdentityServiceProvider.adminCreateUser(createUserParams,function(err,data){
  if(err)
  {
    console.log(err);
    if(err.message.startsWith('User account already exists')){
      res.json({code:-1, msg:'이미 존재하는 아이디입니다.'});
    }else if(err.message.startsWith('An account with the email already exists')){
      res.json({code:-2, msg:'이미 등록된 이메일 주소입니다.'});
    }
  }
  else
  {
    console.log(data);
    res.json({code:0, msg:'계정 생성 안내 이메일이 발송되었습니다.'});
  }
});​&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/AWS</category>
      <category>Amazon</category>
      <category>AWS</category>
      <category>Cognito</category>
      <category>Cognito API</category>
      <category>CognitoIdentityServiceProvider</category>
      <category>User pools</category>
      <category>사용자 풀</category>
      <category>아마존</category>
      <category>코그니토</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/10</guid>
      <comments>https://mintaku.tistory.com/10#entry10comment</comments>
      <pubDate>Wed, 21 Jul 2021 00:10:08 +0900</pubDate>
    </item>
    <item>
      <title>깃허브(GitHub) 입문자를 위한 간단 사용법(간단히 협업)</title>
      <link>https://mintaku.tistory.com/9</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;본 글에서는 깃, 그리고 깃허브 입문자가 버전 관리, 단순 협업을 할 수 있도록 하기 위해&lt;br /&gt;최대한 당장 필요한 것만 설명할 예정이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Git &amp;amp; GitHub&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃과 깃허브가 있다.&lt;br /&gt;&lt;b&gt;깃&lt;/b&gt;은 &lt;b&gt;분산형 버전 관리 시스템&lt;/b&gt;이고,&lt;br /&gt;&lt;b&gt;깃허브&lt;/b&gt;는 이를 사용하는 프로젝트를 지원하는 &lt;b&gt;웹호스팅 서비스&lt;/b&gt;이다.&lt;br /&gt;쉽게 말해 &lt;b&gt;백업과 협업을 위한 클라우드&lt;/b&gt;라고 보면 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 작업환경 세팅&lt;/h3&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&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;깃허브 홈페이지&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;깃 다운로드 및 설치(&lt;a href=&quot;https://git-scm.com/downloads&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;깃 다운로드 페이지&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;cmd(terminal) 창에서 커맨드 입력&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;git config --global user.email &quot;내 이메일&quot;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;git config --global user.name &quot;내 이름&quot;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;깃허브 로그인 요구시 로그인하기&lt;br /&gt;(윈도우는 최초 1번, 맥과 리눅스는 설정 필요)&lt;br /&gt;(윈도우 기준 [제어판]-[사용자 계정]-[자격 증명 관리자]-[Windows 자격 증명]-[일반 자격 증명] 에 로그인 정보가 저장된다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Git 사용법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃을 쓰는 방법에는&lt;br /&gt;CLI(Command Line Interface) 환경과&lt;br /&gt;GUI(Graphical User Interface)에서 쓰는 방법 두 가지가 있는데,&lt;br /&gt;여기서는 &lt;b&gt;CLI 환경에서 커맨드 입력을 통한 방법을 설명할 것이다&lt;/b&gt;.&lt;br /&gt;이유는 아래에 작성한 괄호 안의 내용과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(&amp;nbsp;&lt;br /&gt;깃은 CLI 환경이 기본이지만 사용자 편의를 위해 다양한 GUI 가 존재한다.&lt;br /&gt;CLI 에서는 모든 기능이 가능하지만, GUI 에서는 일부 불가능일 수 있다.&lt;br /&gt;게다가 CLI 로 입문하여 쓰던 사람은 GUI 를 원활하게 사용할 수 있지만,&lt;br /&gt;GUI 로 입문하여 쓰다가 CLI 환경에서 쓰려면 거의 불가능에 가깝기 때문에&lt;br /&gt;CLI 기준으로 기본 사용법을 이해한 후 GUI 사용을 권장한다.&lt;br /&gt;)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;git init&lt;/span&gt;&lt;br /&gt;&lt;b&gt;깃으로 관리하겠다는 선언&lt;/b&gt;.&lt;br /&gt;깃으로&amp;nbsp;관리할&amp;nbsp;프로젝트&amp;nbsp;폴더&amp;nbsp;경로에서&amp;nbsp;커맨드라인으로&amp;nbsp;입력. &lt;br /&gt;해당&amp;nbsp;폴더&amp;nbsp;내에&amp;nbsp;숨김&amp;nbsp;폴더로&amp;nbsp;.git&amp;nbsp;이라는&amp;nbsp;폴더가&amp;nbsp;생성된다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;.gitignore 파일 생성&lt;br /&gt;깃에서&amp;nbsp;제외시킬&amp;nbsp;파일&amp;nbsp;및&amp;nbsp;폴더&amp;nbsp;정보를&amp;nbsp;담는&amp;nbsp;설정&amp;nbsp;파일. &lt;br /&gt;.gitignore 라는 이름의 텍스트 파일.&lt;br /&gt;
&lt;pre id=&quot;code_1626710011819&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;.gitignore 문법 예시

# : 주석

# .a 확장자 파일 무시
*.a

# lib.a 파일은 .a 확장자 파일이더라도 무시 X
!lib.a

# 현재 폴더의 TODO 파일만 무시 subdir/TODO는 무시 X
/TODO

# build 폴더의 모든 파일 무시
build/

# doc/notes.txt 는 무시, doc/server/arch.txt 는 무시 X
doc/*.txt

# doc 폴더의 모든 .pdf 확장자 파일 무시
doc/**/*.pdf​&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;git add 파일명&lt;/span&gt;&lt;br /&gt;스테이지&amp;nbsp;단계로&amp;nbsp;스테이징&amp;nbsp;시키는&amp;nbsp;명령어. &lt;br /&gt;&lt;b&gt;파일명&amp;nbsp;대신&amp;nbsp;점(.)을&amp;nbsp;쓰면&lt;/b&gt;&amp;nbsp;변경사항이&amp;nbsp;있는&amp;nbsp;&lt;b&gt;모든&amp;nbsp;파일을&amp;nbsp;스테이징&lt;/b&gt;한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;git commit -m &quot;메시지&quot;&lt;/span&gt;&lt;br /&gt;커밋&amp;nbsp;명령어. &lt;br /&gt;스테이징된&amp;nbsp;파일들의&amp;nbsp;변경사항을&amp;nbsp;적용하여&amp;nbsp;&lt;b&gt;새로운&amp;nbsp;버전으로&amp;nbsp;저장&lt;/b&gt;. &lt;br /&gt;메시지와&amp;nbsp;함께&amp;nbsp;저장되기에&amp;nbsp;이력&amp;nbsp;관리에&amp;nbsp;용이.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중 .gitignore 파일 생성은 필수가 아니니, 결국 세 단계만 알면 깃으로 버전 관리를 할 수 있게 된다.&lt;br /&gt;게다가 git init 명령어를 통한 초기화는 한번이기에, 결국&lt;br /&gt;&lt;b&gt;add&lt;/b&gt; 와 &lt;b&gt;commit&lt;/b&gt; 두 명령어의 반복만 해도 기본적인 버전 관리를 하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;&lt;i&gt;git&amp;nbsp;init&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;&lt;i&gt; 코드 수정&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;&lt;i&gt;git&amp;nbsp;add&amp;nbsp;.&amp;nbsp;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;&lt;i&gt;git&amp;nbsp;commit&amp;nbsp;-m&amp;nbsp;&amp;lsquo;bla&amp;nbsp;bla&amp;rsquo;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;&lt;i&gt; 코드 수정&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;&lt;i&gt;git&amp;nbsp;add&amp;nbsp;.&amp;nbsp;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;&lt;i&gt;git commit -m &amp;lsquo;bla bla&amp;rsquo;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;&lt;i&gt;...&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;위와 같이 하면 기본 버전 관리가 된다&lt;/b&gt;. 생각보다 간단하다.&lt;br /&gt;물론 여기서 log 명령어로 커밋한 기록을 살펴보고 checkout 명령어로 버전을 전환하고 되돌아오고 하는 것 등의 작업을 할 수 있어야 진짜 버전 관리를 한다 할 수 있겠지만, 그것은 나중에 필요할 때 하면 된다. 쉽고, 구글링 하면 다 나오니까 말이다. 그러한 깃의 기능들에 대해서는 추가 포스팅을 할 예정이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. GitHub 사용법&lt;/h3&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&quot;&gt;깃허브 홈페이지&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Repository(저장소) 생성&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;303px;&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;84&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGF2Vj/btq9ZrBi23z/8RHIO6nhh4ssLH3WKITKcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGF2Vj/btq9ZrBi23z/8RHIO6nhh4ssLH3WKITKcK/img.png&quot; data-alt=&quot;로그인 후 좌측에 보인다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGF2Vj/btq9ZrBi23z/8RHIO6nhh4ssLH3WKITKcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGF2Vj%2Fbtq9ZrBi23z%2F8RHIO6nhh4ssLH3WKITKcK%2Fimg.png&quot; width=&quot;303px;&quot; data-origin-width=&quot;303&quot; data-origin-height=&quot;84&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;로그인 후 좌측에 보인다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;357px;&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;612&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qfefR/btq9WoLABpZ/zxbkYZBnGo4ecpnxnXzjlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qfefR/btq9WoLABpZ/zxbkYZBnGo4ecpnxnXzjlK/img.png&quot; data-alt=&quot;저장소 이름 정하고, 공개or비공개, readme파일 추가 여부, .gitignore 추가 여부, 라이센스 선택 여부를 정한다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qfefR/btq9WoLABpZ/zxbkYZBnGo4ecpnxnXzjlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqfefR%2Fbtq9WoLABpZ%2FzxbkYZBnGo4ecpnxnXzjlK%2Fimg.png&quot; width=&quot;357px;&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;612&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;저장소 이름 정하고, 공개or비공개, readme파일 추가 여부, .gitignore 추가 여부, 라이센스 선택 여부를 정한다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;보유 프로젝트 Repository 에 연결 후 업로드&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;752px;&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;730&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n7UpE/btq9ZsmIh4q/KpoVO96vp5u7jR4jmKG7ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n7UpE/btq9ZsmIh4q/KpoVO96vp5u7jR4jmKG7ck/img.png&quot; data-alt=&quot;빈 저장소 페이지는 가이드가 보인다. cmd로 프로젝트 경로에서 빨간 박스 부분을 따라해보자.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n7UpE/btq9ZsmIh4q/KpoVO96vp5u7jR4jmKG7ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn7UpE%2Fbtq9ZsmIh4q%2FKpoVO96vp5u7jR4jmKG7ck%2Fimg.png&quot; width=&quot;752px;&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;730&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;빈 저장소 페이지는 가이드가 보인다. cmd로 프로젝트 경로에서 빨간 박스 부분을 따라해보자.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;Collaborator(협업자) 초대&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;705px;&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;646&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zYdF0/btq91U31eli/KlkmnJaRMUCGOCSP80frp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zYdF0/btq91U31eli/KlkmnJaRMUCGOCSP80frp1/img.png&quot; data-alt=&quot;저장소 - 설정탭 - Manage access - Invite a collaborator - ID 혹은 이메일로 검색 후 초대 메일 전송&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zYdF0/btq91U31eli/KlkmnJaRMUCGOCSP80frp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzYdF0%2Fbtq91U31eli%2FKlkmnJaRMUCGOCSP80frp1%2Fimg.png&quot; width=&quot;705px;&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;646&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;저장소 - 설정탭 - Manage access - Invite a collaborator - ID 혹은 이메일로 검색 후 초대 메일 전송&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;(초대 받은 경우) 초대 메일 확인 및 수락&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;(초대 받은 경우) Repository 주소 복사&lt;br /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;894px;&quot; height=&quot;209px;&quot; data-origin-width=&quot;1232&quot; data-origin-height=&quot;288&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AhPFs/btq91qhZlwF/ErLmvqef79zk1OHpvApdj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AhPFs/btq91qhZlwF/ErLmvqef79zk1OHpvApdj0/img.png&quot; data-alt=&quot;[Code]버튼 - 주소 복사 버튼&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AhPFs/btq91qhZlwF/ErLmvqef79zk1OHpvApdj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAhPFs%2Fbtq91qhZlwF%2FErLmvqef79zk1OHpvApdj0%2Fimg.png&quot; width=&quot;894px;&quot; height=&quot;209px;&quot; data-origin-width=&quot;1232&quot; data-origin-height=&quot;288&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;[Code]버튼 - 주소 복사 버튼&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;(초대 받은 경우) cmd로 프로젝트를 위치시킬 경로에서 [git clone 주소] 입력 -&amp;gt; 프로젝트 다운로드(폴더 자동생성)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;각자 작업 시작&lt;br /&gt;깃 사용법과 동일하게 진행하지만 앞, 뒤로 명령어 하나씩만 추가하면 된다.&lt;br /&gt;작업 전에 &lt;b&gt;git pull&lt;/b&gt;, 작업 후에 &lt;b&gt;git push&lt;/b&gt; 명령을 입력하면 되겠다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;&lt;i&gt;git pull&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;&lt;i&gt;코드 수정&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;&lt;i&gt;git&amp;nbsp;add&amp;nbsp;.&amp;nbsp;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;&lt;i&gt;git commit -m &amp;lsquo;bla bla&amp;rsquo;&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;&lt;i&gt;git push&lt;/i&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 방식으로, 기존 깃으로 버전 관리만 하는 것에서 협업으로 나아갈 수 있다.&lt;br /&gt;git pull 은 현재 깃허브에 있는 최신 소스의 변경 내용을 다운로드 받아 자신의 로컬 프로젝트와 병합하는 기능이고,&lt;br /&gt;git push 는 현재 자신의 로컬 프로젝트를 깃허브에 업로드하는 기능이다.&lt;br /&gt;따라서 &lt;b&gt;다운로드(병합) - 작업 - 버전 저장 - 업로드&lt;/b&gt; 의 과정이 수행되는 것이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. Conflict(충돌) 발생시&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세상사 100프로는 존재하지 않는다는 말처럼 안타깝게도 깃과 깃허브가 100프로 모든 것을 알아서 해줄 수는 없다.&lt;br /&gt;바로 &lt;b&gt;충돌&lt;/b&gt;이 발생하는 경우인데, 간단히 말하면 &lt;b&gt;동시에 같은 파일의 같은 행을 수정하면 발생&lt;/b&gt;한다.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;철수와 영희가 작업을 한다고 가정하겠다.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;철수가 A라는 버전을 수정해서 push 하여 깃허브에 B버전이 있다.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;영희는 B버전을 pull 하여 B-1버전을 만들어 push 했지만,&lt;/i&gt;&lt;br /&gt;&lt;i&gt;그 사이 철수가 추가 작업을 통해 B-2버전을 만들었다.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;그래서 철수도 push를 하려 했지만 pull 을 받지 않아 push를 할 수 없다는 에러를 보게 되었다.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #1b711d;&quot;&gt;&lt;i&gt;이 때, 영희가 수정한 부분과 철수가 수정한 부분이 겹치지 않는다면 철수는 pull 명령 후 push 를 하여 자연스럽게 넘어갈 수 있다.&lt;/i&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;i&gt;하지만 둘의 수정 내용에서 같은 파일의 같은 행의 수정이 있을 경우, 철수는 pull 명령에서 Conflict 메시지를 받게 된다.&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결 방법은 &lt;b&gt;깃이 알려주는&lt;/b&gt; 충돌이 발생한 &lt;b&gt;파일을 살펴보고 수정&lt;/b&gt;하여 &lt;b&gt;commit&lt;/b&gt; 후 push 하는 것이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;충돌 발생 파일 열기&lt;br /&gt;메시지에서 충돌이 발생한 파일을 알려준다.&lt;br /&gt;사용하는 IDE(개발툴)에서 표시될 수도 있다.&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;523px;&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;79&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/elnQdf/btq9TeWMFIt/4tKTjYzDfm804okTz9vKi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/elnQdf/btq9TeWMFIt/4tKTjYzDfm804okTz9vKi1/img.png&quot; data-alt=&quot;Conflict(충돌) 메시지 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/elnQdf/btq9TeWMFIt/4tKTjYzDfm804okTz9vKi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FelnQdf%2Fbtq9TeWMFIt%2F4tKTjYzDfm804okTz9vKi1%2Fimg.png&quot; width=&quot;523px;&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;79&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Conflict(충돌) 메시지 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;충돌 부분 수정 후 저장&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;332px;&quot; data-origin-width=&quot;332&quot; data-origin-height=&quot;135&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djpqWQ/btq92yfCi2K/OFoGWp0xRXISm5QOwmGIz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djpqWQ/btq92yfCi2K/OFoGWp0xRXISm5QOwmGIz0/img.png&quot; data-alt=&quot;충돌 수정 전&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djpqWQ/btq92yfCi2K/OFoGWp0xRXISm5QOwmGIz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjpqWQ%2Fbtq92yfCi2K%2FOFoGWp0xRXISm5QOwmGIz0%2Fimg.png&quot; width=&quot;332px;&quot; data-origin-width=&quot;332&quot; data-origin-height=&quot;135&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;충돌 수정 전&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; width=&quot;342px;&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;87&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bI4ZJ6/btq9VkQBpEo/BQkcd0KS58Nzzzma6DyMsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bI4ZJ6/btq9VkQBpEo/BQkcd0KS58Nzzzma6DyMsk/img.png&quot; data-alt=&quot;충돌 수정 후&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bI4ZJ6/btq9VkQBpEo/BQkcd0KS58Nzzzma6DyMsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbI4ZJ6%2Fbtq9VkQBpEo%2FBQkcd0KS58Nzzzma6DyMsk%2Fimg.png&quot; width=&quot;342px;&quot; data-origin-width=&quot;342&quot; data-origin-height=&quot;87&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;충돌 수정 후&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;&amp;nbsp;커밋 후 푸시&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6. 그 외 명령어&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깃에는 굉장히 유용하고 사용자를 편하게 해주는 많은 기능과 그 명령어가 있다.&lt;br /&gt;그러나 당장은 필요가 없을 것이고 그때 그때 검색을 통해 차차 알아가는 편이 좋을 것이다.&lt;br /&gt;일단은 이 정도만 알아도 충분하지 않을까.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;git&amp;nbsp;init&lt;/span&gt;&lt;/b&gt;&amp;nbsp;:&amp;nbsp;현재&amp;nbsp;경로를&amp;nbsp;Git프로젝트로&amp;nbsp;관리하기 &lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;git clone 레포지토리 주소&lt;/b&gt;&lt;/span&gt; : 프로젝트 복제(다운로드) &lt;br /&gt;git status : 상태 보기 &lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;git pull&lt;/b&gt;&lt;/span&gt; : (fetch+merge) 깃허브에서 최신버전 다운로드(병합) &lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;git add .&lt;/b&gt;&lt;/span&gt; : 변경사항 다 스테이징 &lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;git commit -m &quot;메시지&quot;&lt;/b&gt;&lt;/span&gt; : 커밋(현재 버전 저장) &lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;git push&lt;/b&gt;&lt;/span&gt; : 깃허브에 현재 커밋 업로드 &lt;br /&gt;git log : 로그(버전 이력) 보기 &lt;br /&gt;git checkout 커밋코드4자리 : 원하는 버전으로 코드 돌려보기&lt;br /&gt;git branch 브랜치이름 : 브랜치 만들기(가지치기)&lt;br /&gt;git checkout 브랜치이름 : 해당 브랜치의 최신버전으로 코드 돌려보기 &lt;br /&gt;git merge 브랜치이름 : 해당 브랜치 변경내용을 현재 브랜치에 병합하기&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;7. 마치며.&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사내 교육 진행을 위해 만들었던 24개의 ppt 슬라이드에서도 내용을 간추렸지만,&lt;br /&gt;글로써 설명하다보니 글이 길어져서 아쉽다.&lt;br /&gt;그래도 막상 사용법은 간단하다는 말을 강조하고 싶어, 교육 마지막에 넣었던 문구로 마치도록 하겠다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;ldquo;당기고(pull),&amp;nbsp;더하고(add,&amp;nbsp;commit),&amp;nbsp;미세요(push).&amp;rdquo;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #333333; color: #ffffff;&quot;&gt;백업,&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #333333; color: #ffffff;&quot;&gt;버전&amp;nbsp;관리,&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #333333; color: #ffffff;&quot;&gt;협업을&amp;nbsp; &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #333333; color: #ffffff;&quot;&gt;빠르고&amp;nbsp;간편하게. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #333333; color: #ffffff;&quot;&gt;Github. &lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dZcjsE/btq92yGDalj/qzooFuoxvCJPSjhryKLbn0/img.png&quot; width=&quot;59px;&quot; data-image-src=&quot;https://blog.kakaocdn.net/dn/dZcjsE/btq92yGDalj/qzooFuoxvCJPSjhryKLbn0/img.png&quot; data-origin-width=&quot;52&quot; data-origin-height=&quot;48&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Git</category>
      <category>Git</category>
      <category>github</category>
      <category>교육자료</category>
      <category>깃</category>
      <category>깃허브</category>
      <category>백업</category>
      <category>버전관리</category>
      <category>사용법</category>
      <category>입문</category>
      <category>협업</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/9</guid>
      <comments>https://mintaku.tistory.com/9#entry9comment</comments>
      <pubDate>Tue, 20 Jul 2021 02:34:35 +0900</pubDate>
    </item>
    <item>
      <title>JSON 비교 웹 사이트(jsondiff.com)</title>
      <link>https://mintaku.tistory.com/8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://jsondiff.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;JSON 비교 사이트&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1626706196509&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;JSON Diff - The semantic JSON compare tool&quot; data-og-description=&quot;&quot; data-og-host=&quot;jsondiff.com&quot; data-og-source-url=&quot;http://jsondiff.com/&quot; data-og-url=&quot;http://jsondiff.com/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;http://jsondiff.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://jsondiff.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;JSON Diff - The semantic JSON compare tool&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jsondiff.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JSON 끼리 비교해야할 경우가 있는데, 그럴 때 유용한 사이트이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;689&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnuE0X/btq90mNDfS2/Yf2gQztmB6bG98wc116ZV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnuE0X/btq90mNDfS2/Yf2gQztmB6bG98wc116ZV0/img.png&quot; data-alt=&quot;간단 명료한 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnuE0X/btq90mNDfS2/Yf2gQztmB6bG98wc116ZV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnuE0X%2Fbtq90mNDfS2%2FYf2gQztmB6bG98wc116ZV0%2Fimg.png&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;689&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;간단 명료한 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;왼쪽에 복사 붙여넣기, 오른쪽에도 복붙.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;마지막으로 [Compare] 버튼만 누르면 끝!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;524&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boAMgv/btq93m0ekuT/ynOR0kVfHYbmWJpoD25VY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boAMgv/btq93m0ekuT/ynOR0kVfHYbmWJpoD25VY1/img.png&quot; data-alt=&quot;결과 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boAMgv/btq93m0ekuT/ynOR0kVfHYbmWJpoD25VY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboAMgv%2Fbtq93m0ekuT%2FynOR0kVfHYbmWJpoD25VY1%2Fimg.png&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;524&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;물론 영어, 한글 등 다양한 언어를 지원한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;굉장히 유용하다!&lt;/span&gt;&lt;/p&gt;</description>
      <category>개발/꿀팁저장소</category>
      <category>Compare</category>
      <category>diff</category>
      <category>diff site</category>
      <category>diff tool</category>
      <category>json</category>
      <category>JSON Diff</category>
      <category>JSON 비교</category>
      <category>jsondiff.com</category>
      <category>비교</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/8</guid>
      <comments>https://mintaku.tistory.com/8#entry8comment</comments>
      <pubDate>Tue, 20 Jul 2021 00:01:58 +0900</pubDate>
    </item>
    <item>
      <title>텍스트 비교 웹 사이트(text-compare.com)</title>
      <link>https://mintaku.tistory.com/7</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://text-compare.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;텍스트 비교 사이트&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1626702953840&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;Text Compare! - An online diff tool that can find the difference between two text files&quot; data-og-description=&quot;&quot; data-og-host=&quot;text-compare.com&quot; data-og-source-url=&quot;https://text-compare.com/&quot; data-og-url=&quot;https://text-compare.com/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://text-compare.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://text-compare.com/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;Text Compare! - An online diff tool that can find the difference between two text files&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;text-compare.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순 텍스트를 비교해야할 경우가 종종 있는데, 그럴 때 유용한 사이트이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1061&quot; data-origin-height=&quot;585&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cg4Wad/btq91qhVm2o/X8QUJl3SgQoinGrkzWts41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cg4Wad/btq91qhVm2o/X8QUJl3SgQoinGrkzWts41/img.png&quot; data-alt=&quot;군더더기 없는 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cg4Wad/btq91qhVm2o/X8QUJl3SgQoinGrkzWts41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcg4Wad%2Fbtq91qhVm2o%2FX8QUJl3SgQoinGrkzWts41%2Fimg.png&quot; data-origin-width=&quot;1061&quot; data-origin-height=&quot;585&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;군더더기 없는 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왼쪽에 복사 붙여넣기, 오른쪽에도 복붙.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 [Compare!] 버튼만 누르면 끝!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;773&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7GdMX/btq90mNBphc/ek2CeLXT59EqgnPkakkJZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7GdMX/btq90mNBphc/ek2CeLXT59EqgnPkakkJZ0/img.png&quot; data-alt=&quot;결과 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7GdMX/btq90mNBphc/ek2CeLXT59EqgnPkakkJZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7GdMX%2Fbtq90mNBphc%2Fek2CeLXT59EqgnPkakkJZ0%2Fimg.png&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;773&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영어, 한글 등 다양한 외국어도 물론 지원한다.&lt;/p&gt;</description>
      <category>개발/꿀팁저장소</category>
      <category>Compare</category>
      <category>text</category>
      <category>Text Compare</category>
      <category>text-compare.com</category>
      <category>글자 비교</category>
      <category>비교</category>
      <category>텍스트 비교</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/7</guid>
      <comments>https://mintaku.tistory.com/7#entry7comment</comments>
      <pubDate>Mon, 19 Jul 2021 23:01:02 +0900</pubDate>
    </item>
    <item>
      <title>jQuery 깜빡임 없이 동적 페이지 전환 구현하기(뒤로가기, 새로고침 지원)</title>
      <link>https://mintaku.tistory.com/6</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;두괄식으로 말해서,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. movePage 함수 선언&lt;/p&gt;
&lt;pre id=&quot;code_1626587770956&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function movePage(navigator) {
        var pageUrl = $(navigator).attr(&quot;url&quot;);

        if (pageUrl !== location.pathname) {
            history.pushState({ path: pageUrl }, null, pageUrl);
            var popStateEvent = new PopStateEvent('popstate', { state: null });
            dispatchEvent(popStateEvent); // event 발생시키기
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이동하려는 url 정보를 받아 path 라는 이름으로 history.state 에 저장하고,&lt;br /&gt;popstate 이벤트를 발생시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. onclick 에 movePage 함수 사용&lt;/p&gt;
&lt;pre id=&quot;code_1626587854584&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;a class=&quot;dropdown-item&quot; href=&quot;javascript:void(0);&quot; url=&quot;/cognito/settings&quot; onclick=&quot;movePage(this)&quot;&amp;gt;정보수정&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;url 이라는 속성에 이동하고자 하는 페이지 url path를 적어주고, 클릭시 해당 태그 자체를 파라미터로 movePage 함수를 실행시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. onpopstate 이벤트(url 변경) 발생시 페이지 처리&lt;/p&gt;
&lt;pre id=&quot;code_1626588521211&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;onpopstate = function (e) {
        // 페이지 GET 요청
        $.ajax({
            type: &quot;GET&quot;,
            url: history.state.path,
            data: { type: &quot;get&quot; },
            success: function (data) {
                if(data.startsWith('&amp;lt;!--login--&amp;gt;')){
                    // 세션 만료로 인한 로그인 페이지 data
                    alert('세션이 만료되었습니다. 다시 로그인하세요.');
                    location.href = '/cognito/login';
                }else{
                    var bodyData = data.substring(data.indexOf('&amp;lt;!--body start--&amp;gt;'),data.indexOf('&amp;lt;!--body end--&amp;gt;')) + ' '
                    + data.substring(data.indexOf('&amp;lt;!--script start--&amp;gt;'),data.indexOf('&amp;lt;!--script end--&amp;gt;'));
                    $('#body').html(bodyData);
                }
            }
        });
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;movePage 함수에서 이벤트를 발생시키면 페이지가 state 정보로 ajax 요청을 하고, &lt;br /&gt;받은 데이터를 통해 html 태그를 변경한다.&lt;br /&gt;위 코드에서 받은 데이터를 가공할 때, 커스텀으로 작업해둔 flag 기능의 주석 태그를 바탕으로 데이터를 가공한다.&lt;br /&gt;if(data.startsWith('&amp;lt;!--login--&amp;gt;') ~ 부분은 이 프로젝트 내에서 세션 만료시 로그인 페이지로 이동하도록 되어있기 때문에 작성한 것으로, 이러한 작업을 한다면 참고할 부분이고 아니라면 필요하지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 페이지마다 주석 태그로 flag 달기&lt;/p&gt;
&lt;pre id=&quot;code_1626589270659&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!--body start--&amp;gt;
~
~
&amp;lt;!--body end--&amp;gt;
~
~
&amp;lt;!--script start--&amp;gt;
~
~
&amp;lt;!--script end--&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;416&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NJ0xK/btq9O7i2zGc/juFdTcLHBfdxmDngNOCc31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NJ0xK/btq9O7i2zGc/juFdTcLHBfdxmDngNOCc31/img.png&quot; data-alt=&quot;예시1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NJ0xK/btq9O7i2zGc/juFdTcLHBfdxmDngNOCc31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNJ0xK%2Fbtq9O7i2zGc%2FjuFdTcLHBfdxmDngNOCc31%2Fimg.png&quot; data-origin-width=&quot;761&quot; data-origin-height=&quot;416&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;예시1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;795&quot; data-origin-height=&quot;418&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tNYp6/btq9WpWStzK/1PfCcgdVmZVkuhvk4IrDlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tNYp6/btq9WpWStzK/1PfCcgdVmZVkuhvk4IrDlk/img.png&quot; data-alt=&quot;예시2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tNYp6/btq9WpWStzK/1PfCcgdVmZVkuhvk4IrDlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtNYp6%2Fbtq9WpWStzK%2F1PfCcgdVmZVkuhvk4IrDlk%2Fimg.png&quot; data-origin-width=&quot;795&quot; data-origin-height=&quot;418&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;예시2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;275&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NAdXL/btq9Poj9KF1/fWPeiYcki8l8yvCpMxit70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NAdXL/btq9Poj9KF1/fWPeiYcki8l8yvCpMxit70/img.png&quot; data-alt=&quot;예시3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NAdXL/btq9Poj9KF1/fWPeiYcki8l8yvCpMxit70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNAdXL%2Fbtq9Poj9KF1%2FfWPeiYcki8l8yvCpMxit70%2Fimg.png&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;275&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;예시3&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 페이지마다 전달하고자 하는 부분만 지정해주기 위함이다. &lt;br /&gt;이렇게 substring을 통해 html 에 넣어주지 않고 데이터 통째로 넣으면 header 와 footer 안에 또 header 와 footer 가 생길 것이고, 각 페이지마다 header footer 등을 지우고 원하는 태그만 저장해두면 해당 페이지에서 새로고침할 때 문제가 생긴다. 새로고침을 막는 것은 키보드를 통한 방법만 막을 수 있으며 브라우저 자체의 새로고침은 페이지를 팝업창처럼 만들지 않는 이상 막기가 불가능하다.&lt;br /&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;br /&gt;body 에 원하는 페이지만 렌더링하고 싶었다.&lt;br /&gt;알아보니 ajax 비동기 통신을 통해 요청으로 받은 페이지 데이터로 html 태그를 변경하는 방법이 있었지만,&lt;br /&gt;단순히 그 방법만으로는 뒤로가기, 앞으로가기, 새로고침을 지원할 수 없었고&lt;br /&gt;window.history 객체(IE버전 10이상) 혹은 History.js 라는 제이쿼리 플러그인을 함께 사용해야 했다.&lt;br /&gt;따라서 IE버전 10 이상을 쓸 것이라는 가정 하에 따로 제이쿼리 플러그인을 사용하지 않고&lt;br /&gt;history 객체를 이용하여 구현해보았다.&lt;/p&gt;</description>
      <category>개발/Nodejs</category>
      <category>body</category>
      <category>footer</category>
      <category>header</category>
      <category>History</category>
      <category>jQuery</category>
      <category>깜빡임</category>
      <category>동적 전환</category>
      <category>뒤로가기</category>
      <category>새로고침</category>
      <category>페이지 이동</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/6</guid>
      <comments>https://mintaku.tistory.com/6#entry6comment</comments>
      <pubDate>Sun, 18 Jul 2021 15:43:17 +0900</pubDate>
    </item>
    <item>
      <title>express-ejs-layouts(공통 부분 레이아웃 공유) include에서 한 발 더 나아간 코드 작성 간소화</title>
      <link>https://mintaku.tistory.com/5</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;ejs 에서는 include 를 통해 공통되는 부분의 작성을 대신 하는데,&amp;nbsp;&lt;br /&gt;한 발 더 나아가서 전체 레이아웃을 작성해놓을 수가 있었다.&lt;br /&gt;(동적 페이지 전환은 아니다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;span style=&quot;color: #ffffff; background-color: #000000;&quot;&gt;npm install express-ejs-layouts&lt;/span&gt;&lt;br /&gt;프로젝트 경로에서 위 cmd 명령어 쳐서 모듈 설치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. app.js&lt;/p&gt;
&lt;pre id=&quot;code_1626361810118&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const expressLayouts = require('express-ejs-layouts');

app.use(expressLayouts);

app.set('layout','layout');
app.set('layout extractScripts', true);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app.js 에서 4줄 추가.&lt;br /&gt;(layout 은 html을 layout.ejs로, layout extractScripts 는 script 태그를 layout.ejs로 불러오게 설정하는 것)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. layout.ejs 파일 생성&lt;/p&gt;
&lt;pre id=&quot;code_1626362215116&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;ko&quot; dir=&quot;ltr&quot;&amp;gt;

// head ~~~
// header ~~~

&amp;lt;%- body %&amp;gt;

// footer ~~~

&amp;lt;%- script %&amp;gt;

&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 작성만 하면 된다.&lt;br /&gt;그리고 각 페이지 ejs 에 body 에 해당하는 html 태그와 script 태그만 작성하면 끝.&lt;br /&gt;그냥 작성해도 되고, header.ejs, footer.ejs 와 같이 나누어서 파일로 생성한 후에 include 를 써도 좋다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;462&quot; data-origin-height=&quot;520&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHNeDz/btq9Ehs9v4J/n8hSlKgzt6RwBoFhhA5b20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHNeDz/btq9Ehs9v4J/n8hSlKgzt6RwBoFhhA5b20/img.png&quot; data-alt=&quot;이런 방식으로&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHNeDz/btq9Ehs9v4J/n8hSlKgzt6RwBoFhhA5b20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHNeDz%2Fbtq9Ehs9v4J%2Fn8hSlKgzt6RwBoFhhA5b20%2Fimg.png&quot; data-origin-width=&quot;462&quot; data-origin-height=&quot;520&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이런 방식으로&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Nodejs</category>
      <category>body</category>
      <category>ejs</category>
      <category>express-ejs-layouts</category>
      <category>footer</category>
      <category>head</category>
      <category>header</category>
      <category>include</category>
      <category>script</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/5</guid>
      <comments>https://mintaku.tistory.com/5#entry5comment</comments>
      <pubDate>Sun, 18 Jul 2021 14:22:35 +0900</pubDate>
    </item>
    <item>
      <title>HTML 코드, ASCII(아스키) 코드, URL 인코딩 디코딩 웹 사이트(ascii.cl)</title>
      <link>https://mintaku.tistory.com/4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ascii.cl/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ascii.cl/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1626252955928&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;ASCII Codes - Table of ascii characters and symbols&quot; data-og-description=&quot;&amp;nbsp; ASCII Hex Symbol 01234567 89101112131415 01234567 89ABCDEF NULSOHSTXETXEOTENQACKBEL BSTABLFVTFFCRSOSI ASCII Hex Symbol 1617181920212223 2425262728293031 1011121314151617 18191A1B1C1D1E1F DLEDC1DC2DC3DC4NAKSYNETB CANEMSUBESCFSGSRSUS ASCII Hex Symbol 3233&quot; data-og-host=&quot;ascii.cl&quot; data-og-source-url=&quot;https://ascii.cl/&quot; data-og-url=&quot;https://ascii.cl/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://ascii.cl/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ascii.cl/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;ASCII Codes - Table of ascii characters and symbols&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; ASCII Hex Symbol 01234567 89101112131415 01234567 89ABCDEF NULSOHSTXETXEOTENQACKBEL BSTABLFVTFFCRSOSI ASCII Hex Symbol 1617181920212223 2425262728293031 1011121314151617 18191A1B1C1D1E1F DLEDC1DC2DC3DC4NAKSYNETB CANEMSUBESCFSGSRSUS ASCII Hex Symbol 3233&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ascii.cl&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;319&quot; data-origin-height=&quot;206&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QNlnB/btq9wfig0sw/otVwr2xbkhycSGpQuQSW00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QNlnB/btq9wfig0sw/otVwr2xbkhycSGpQuQSW00/img.png&quot; data-alt=&quot;ascii.cl 좌측 내비게이션 바&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QNlnB/btq9wfig0sw/otVwr2xbkhycSGpQuQSW00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQNlnB%2Fbtq9wfig0sw%2FotVwr2xbkhycSGpQuQSW00%2Fimg.png&quot; data-origin-width=&quot;319&quot; data-origin-height=&quot;206&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ascii.cl 좌측 내비게이션 바&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTML 코드, 아스키 코드를 표로 정리.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력 후 버튼 클릭으로 URL 인코딩, 디코딩.&lt;/p&gt;</description>
      <category>개발/꿀팁저장소</category>
      <category>ascii.cl</category>
      <category>html 코드</category>
      <category>URL 디코딩</category>
      <category>URL 인코딩</category>
      <category>아스키 코드</category>
      <category>유용한 사이트</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/4</guid>
      <comments>https://mintaku.tistory.com/4#entry4comment</comments>
      <pubDate>Wed, 14 Jul 2021 17:57:57 +0900</pubDate>
    </item>
    <item>
      <title>JSON.stringify() 실행시 큰따옴표(&amp;quot;)가 &amp;amp;#34 로 나올 때</title>
      <link>https://mintaku.tistory.com/3</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;두괄식으로 말하자면, 두 가지 방법은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방법1.&lt;/p&gt;
&lt;pre id=&quot;code_1626251055168&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let userList = '&amp;lt;%=JSON.stringify(userList)%&amp;gt;';

userList = userList.replaceAll('&amp;amp;#34;', '\&quot;');
userList = JSON.parse(userList);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방법2.&lt;/p&gt;
&lt;pre id=&quot;code_1626251117157&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let userList = '&amp;lt;%-JSON.stringify(userList)%&amp;gt;';

userList = JSON.parse(userList);&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;해당 문제는 요청으로 받은 JSON 데이터를 ejs 템플릿에서 처리하는 과정 중에 발생하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;amp;#34; 와 같은 형태는 HTML Code 이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-origin-width=&quot;358&quot; data-origin-height=&quot;276&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0ad4Q/btq9Ai5NcK5/lenrUy3ULFWm7E4JN3hkrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0ad4Q/btq9Ai5NcK5/lenrUy3ULFWm7E4JN3hkrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0ad4Q/btq9Ai5NcK5/lenrUy3ULFWm7E4JN3hkrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0ad4Q%2Fbtq9Ai5NcK5%2FlenrUy3ULFWm7E4JN3hkrk%2Fimg.png&quot; data-origin-width=&quot;358&quot; data-origin-height=&quot;276&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(HTML Code 정리 사이트 : &lt;a href=&quot;https://ascii.cl/htmlcodes.htm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ascii.cl/htmlcodes.htm&lt;/a&gt;)&lt;br /&gt;이것이 HTML Code 의 한 종류임을 알지 못하는 사람으로서는 난감할 수 있을 법한 게,&lt;br /&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;이를 복사해서 웹에서 붙여넣기하면 자동으로 큰따옴표(&quot;)로 출력된다. 즉, 구글링을 실수할 수 있다. ㅎㅎ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;이것은 방법1과 같이 replaceAll() 을 통해 큰따옴표(\&quot;)로 모두 치환하는 방법과,&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;방법2와 같이 &amp;lt;%= 가 아닌 &amp;lt;%- 의 형태인 이스케이프 태그를 쓰는 방법이 있다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>개발/Nodejs</category>
      <category>&amp;amp;#34;</category>
      <category>ejs</category>
      <category>HTML Code</category>
      <category>html 코드</category>
      <category>json</category>
      <category>JSON.stringify()</category>
      <category>nodejs</category>
      <category>따옴표</category>
      <category>이스케이프</category>
      <category>큰따옴표</category>
      <author>민타쿠</author>
      <guid isPermaLink="true">https://mintaku.tistory.com/3</guid>
      <comments>https://mintaku.tistory.com/3#entry3comment</comments>
      <pubDate>Wed, 14 Jul 2021 17:52:49 +0900</pubDate>
    </item>
  </channel>
</rss>