<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>104%</title>
    <link>https://simsimjae.tistory.com/</link>
    <description> SINCE 2017/8/7</description>
    <language>ko</language>
    <pubDate>Thu, 7 May 2026 03:19:35 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>심재철</managingEditor>
    <image>
      <title>104%</title>
      <url>https://tistory1.daumcdn.net/tistory/2797885/attach/938730c81ed2413295e72b1c7124beaf</url>
      <link>https://simsimjae.tistory.com</link>
    </image>
    <item>
      <title>[에듀윌 공인중개사] 5개월 단기 합격 후기 - 사업가도 할 수 있다.</title>
      <link>https://simsimjae.tistory.com/492</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요, 2025년 제36회 공인중개사 시험에 동차 합격한 수험생입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;공인중개사를 준비하게 된 계기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가족들과 함께 부동산을 운영하게 될 기회가 생겨서 공인중개사 자격증이 필요하게 되었습니다. 늦은 시작이라 걱정이 많았지만, 결국 해냈네요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;왜 에듀윌 공인중개사를 선택했나&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 학원을 비교해봤는데, 합격률이나 커리큘럼 면에서 &lt;b&gt;에듀윌 공인중개사&lt;/b&gt;가 가장 체계적이라는 평이 많았습니다. 실제로 수강해보니 그 평판이 괜히 있는 게 아니더라고요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;나만의 공부법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 준비 기간이 &lt;b&gt;5개월&lt;/b&gt;밖에 없었기 때문에 전략적으로 접근해야 했습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인터넷 강의를 최소 2~3회 반복 수강&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;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;시험 당일 팁&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔직히 시험장에서 모르는 문제가 꽤 나와서 멘붕이 왔습니다. 하지만 포기하지 않고 끝까지 풀었더니 커트라인으로 합격할 수 있었어요. &lt;b&gt;멘탈 관리&lt;/b&gt;가 정말 중요합니다. 모르는 문제에 너무 시간 쓰지 말고, 아는 문제부터 확실하게 맞추세요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;마무리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;짧은 기간이라 불가능할 거라 생각했는데, 에듀윌 공인중개사 강의와 체계적인 커리큘럼 덕분에 동차 합격이라는 결과를 얻을 수 있었습니다. 늦었다고 생각하시는 분들도 포기하지 마시고 도전해보세요!&lt;/p&gt;</description>
      <author>심재철</author>
      <guid isPermaLink="true">https://simsimjae.tistory.com/492</guid>
      <comments>https://simsimjae.tistory.com/492#entry492comment</comments>
      <pubDate>Wed, 26 Nov 2025 21:33:47 +0900</pubDate>
    </item>
    <item>
      <title>electron code signing</title>
      <link>https://simsimjae.tistory.com/490</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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 키체인 접근 &amp;gt; 상단 메뉴 &amp;gt; 인증서 지원 &amp;gt; 인증기관에서 인증서 요청 클릭&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;872&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dDON0M/btrxb02tJvQ/sdxj1BktkvVkHcdZbiickk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dDON0M/btrxb02tJvQ/sdxj1BktkvVkHcdZbiickk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dDON0M/btrxb02tJvQ/sdxj1BktkvVkHcdZbiickk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDON0M%2Fbtrxb02tJvQ%2Fsdxj1BktkvVkHcdZbiickk%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;662&quot; height=&quot;476&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;872&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디스크에 저장하면 Certificate Request 어쩌고 파일이 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(이 인증서 파일은 기기마다 다른것같으므로 Mac 기기가 바뀌면 새로 등록해줘야하는 것 같다. 다른 맥 기기로 등록해놨던 인증서를 그냥 다운로드만 받았더니 인증서 인식을 제대로 하지 못했다. 아마 private, public key 방식으로 동작해서 그런듯?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 파일을 &lt;a href=&quot;https://developer.apple.com/account/resources/certificates/list&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.apple.com/account/resources/certificates/list&lt;/a&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;1908&quot; data-origin-height=&quot;728&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bryYoq/btrxcyrzZZ2/4944jVy3E2Xw3hKIbjWhKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bryYoq/btrxcyrzZZ2/4944jVy3E2Xw3hKIbjWhKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bryYoq/btrxcyrzZZ2/4944jVy3E2Xw3hKIbjWhKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbryYoq%2FbtrxcyrzZZ2%2F4944jVy3E2Xw3hKIbjWhKk%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;1908&quot; height=&quot;728&quot; data-origin-width=&quot;1908&quot; data-origin-height=&quot;728&quot;/&gt;&lt;/span&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;b&gt;security&amp;nbsp;find-identity&amp;nbsp;-p&amp;nbsp;codesigning&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;그리고 나서 electron-builder 패키지로 일렉트론을 빌드하면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1336&quot; data-origin-height=&quot;588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LpchV/btrxgEKFkVN/45wzBVBckBC8KloHZw47l1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LpchV/btrxgEKFkVN/45wzBVBckBC8KloHZw47l1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LpchV/btrxgEKFkVN/45wzBVBckBC8KloHZw47l1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLpchV%2FbtrxgEKFkVN%2F45wzBVBckBC8KloHZw47l1%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;1336&quot; height=&quot;588&quot; data-origin-width=&quot;1336&quot; data-origin-height=&quot;588&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 코드 사이닝이 정상적으로 이뤄진다.&lt;/p&gt;</description>
      <category>Electron</category>
      <author>심재철</author>
      <guid isPermaLink="true">https://simsimjae.tistory.com/490</guid>
      <comments>https://simsimjae.tistory.com/490#entry490comment</comments>
      <pubDate>Fri, 25 Mar 2022 12:18:10 +0900</pubDate>
    </item>
    <item>
      <title>robot.js + electron 빌드시 오류</title>
      <link>https://simsimjae.tistory.com/489</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;electron, electron-builder, robot.js 이 3가지의 버전이 서로 잘 호환이 되지 않아서 골치가 매우 아프다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 개발자가 각 패키지의 호환가능한 버전을 일일이 찾아야하는데 검색해도 호환되는 버전이 어떤 버전인지 정리해놓은곳을 찾을 수가 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 이상한 오류가 난다.&lt;/p&gt;
&lt;pre id=&quot;code_1648105564096&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ electron-builder install-app-deps
  &amp;bull; electron-builder  version=21.2.0
  &amp;bull; loaded configuration  file=package.json (&quot;build&quot; field)
  &amp;bull; rebuilding native dependencies  dependencies=robotjs@0.6.0, fsevents@1.2.13 platform=darwin arch=x64
  &amp;bull; install prebuilt binary  name=robotjs version=0.6.0 platform=darwin arch=x64
  &amp;bull; build native dependency from sources  name=robotjs
                                          version=0.6.0
                                          platform=darwin
                                          arch=x64
                                          reason=prebuild-install failed with error (run with env DEBUG=electron-builder to get more information)
                                          error=prebuild-install info begin Prebuild-install version 5.3.6
    prebuild-install info looking for cached prebuild @ /Users/simsimjae/.npm/_prebuilds/355e17-robotjs-v0.6.0-electron-v76-darwin-x64.tar.gz
    prebuild-install http request GET https://github.com/octalmage/robotjs/releases/download/v0.6.0/robotjs-v0.6.0-electron-v76-darwin-x64.tar.gz
    prebuild-install http 404 https://github.com/octalmage/robotjs/releases/download/v0.6.0/robotjs-v0.6.0-electron-v76-darwin-x64.tar.gz
    prebuild-install WARN install No prebuilt binaries found (target=8.5.2 runtime=electron arch=x64 libc= platform=darwin)
    
  &amp;bull; rebuilding native dependency  name=fsevents version=1.2.13
  &amp;bull; rebuilding native dependency  name=robotjs version=0.6.0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;electron-builder 20버전대 까지는 이런 오류가 안나는데 21, 22버전대부터는 이런 오류가 발생한다.&lt;/p&gt;
&lt;pre id=&quot;code_1648105722447&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;https://github.com/octalmage/robotjs/releases/download/v0.6.0/robotjs-v0.6.0-electron-v76-darwin-x64.tar.gz&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 링크가 404라고 하는걸 보니 robotjs 0.6.0에서 애초에 일렉트론 v76을 지원하지 않나보다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서&lt;b&gt; electron-builder의 버전을 20이하로 낮출수밖에 없는데.. 낮추면 robot.js 0.6.0을 빌드할 수 있게 되긴 한다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1648105895366&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ electron-builder install-app-deps
  &amp;bull; electron-builder version=20.44.4
  &amp;bull; loaded configuration file=package.json (&quot;build&quot; field)
  &amp;bull; rebuilding native production dependencies platform=darwin arch=x64
  &amp;bull; rebuilding native dependency name=fsevents
  &amp;bull; rebuilding native dependency name=robotjs&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이렇게 electron-builder로 일렉트론과 robotjs가 호환가능하게 되었다.&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;pre id=&quot;code_1648105962284&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;⨯ error: fork/exec /Users/simsimjae/Library/Caches/electron-builder/wine/wine-2.0.3-mac-10.13/bin/wine: bad CPU type in executable
path: /Users/simsimjae/Library/Caches/electron-builder/wine/wine-2.0.3-mac-10.13/bin/wine
args: /Users/simsimjae/Library/Caches/electron-builder/wine/wine-2.0.3-mac-10.13/bin/wine /Users/simsimjae/Library/Caches/electron-builder/winCodeSign/winCodeSign-2.4.0/rcedit-ia32.exe /Users/simsimjae/Desktop/knowledge-shopping-top/dist/win-unpacked/knowledge-shopping-top.exe --set-version-string FileDescription knowledge-shopping-top --set-version-string ProductName knowledge-shopping-top --set-version-string LegalCopyright Copyright &amp;copy; 2022 simsimjae --set-file-version 0.1.9 --set-product-version 0.1.9.0 --set-version-string InternalName knowledge-shopping-top --set-version-string OriginalFilename  --set-version-string CompanyName simsimjae
output: 
error output:
github.com/develar/app-builder/pkg/util.Execute
        /Volumes/data/Documents/app-builder/pkg/util/util.go:61
github.com/develar/app-builder/pkg/wine.execWine
        /Volumes/data/Documents/app-builder/pkg/wine/wine.go:92
github.com/develar/app-builder/pkg/wine.ConfigureCommand.func2
        /Volumes/data/Documents/app-builder/pkg/wine/wine.go:43
github.com/alecthomas/kingpin.(*actionMixin).applyActions
        /Volumes/data/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/actions.go:28
github.com/alecthomas/kingpin.(*Application).applyActions
        /Volumes/data/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:557
github.com/alecthomas/kingpin.(*Application).execute
        /Volumes/data/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:390
github.com/alecthomas/kingpin.(*Application).Parse
        /Volumes/data/go/pkg/mod/github.com/alecthomas/kingpin@v2.2.6+incompatible/app.go:222
main.main
        /Volumes/data/Documents/app-builder/main.go:78
runtime.main
        /usr/local/Cellar/go/1.12.6/libexec/src/runtime/proc.go:200
runtime.goexit
        /usr/local/Cellar/go/1.12.6/libexec/src/runtime/asm_amd64.s:1337
 
Error: /Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-bin/mac/app-builder exited with code 1
    at ChildProcess.&amp;lt;anonymous&amp;gt; (/Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/builder-util/src/util.ts:244:14)
    at Object.onceWrapper (events.js:520:26)
    at ChildProcess.emit (events.js:400:28)
    at maybeClose (internal/child_process.js:1058:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:293:5)
From previous event:
    at processImmediate (internal/timers.js:464:21)
From previous event:
    at WinPackager.signAndEditResources (/Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/winPackager.ts:260:158)
    at /Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/winPackager.ts:362:21
    at /Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/graceful-fs/graceful-fs.js:209:16
    at FSReqCallback.oncomplete (fs.js:179:23)
From previous event:
    at /Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/winPackager.ts:360:27
    at Generator.next (&amp;lt;anonymous&amp;gt;)
From previous event:
    at WinPackager.signApp (/Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/winPackager.ts:354:73)
    at /Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/platformPackager.ts:250:16
From previous event:
    at WinPackager.doPack (/Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/platformPackager.ts:167:165)
    at /Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/platformPackager.ts:113:16
    at Generator.next (&amp;lt;anonymous&amp;gt;)
From previous event:
    at WinPackager.pack (/Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/platformPackager.ts:111:95)
    at /Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/packager.ts:430:24
    at Generator.next (&amp;lt;anonymous&amp;gt;)
    at processImmediate (internal/timers.js:464:21)
From previous event:
    at Packager.doBuild (/Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/packager.ts:396:24)
    at /Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/packager.ts:366:57
    at Generator.next (&amp;lt;anonymous&amp;gt;)
    at /Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/graceful-fs/graceful-fs.js:143:16
    at /Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/graceful-fs/graceful-fs.js:61:14
    at FSReqCallback.oncomplete (fs.js:179:23)
From previous event:
    at Packager._build (/Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/packager.ts:335:133)
    at /Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/packager.ts:331:23
    at Generator.next (&amp;lt;anonymous&amp;gt;)
    at processImmediate (internal/timers.js:464:21)
From previous event:
    at Packager.build (/Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/packager.ts:288:14)
    at build (/Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/app-builder-lib/src/index.ts:59:28)
    at build (/Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/electron-builder/src/builder.ts:228:10)
    at /Users/simsimjae/Desktop/knowledge-shopping-top/node_modules/electron-builder/src/cli/cli.ts:49:19&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에러를 대략 유추해보자면.. &lt;b&gt;electron-builder(20버전대)에서 현재 Mac OS 버전(monteray, 카탈리나 이후부터)&lt;/b&gt;와 충돌이 있는듯하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/electron-userland/electron-builder-binaries/issues/30&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/electron-userland/electron-builder-binaries/issues/30&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 이걸 해결할라면 또 electron-builder를 22버전으로 업데이트 해야 한단다 ㅋㅋ&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;근데 electron-builder 22 버전과 robot.js 0.6.0은 같이 쓸 수 없다. 다른 방법을 찾아야겠다. 이거 빌드하자고 Mac OS 버전을 내릴수도 없는 노릇이고 상당히 난감하다.&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;electron 버전과는 딱히 상관없는거같고 electron-builder와 robot.js를 잘 호환시키면 문제가 해결 될 듯 하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;994&quot; data-origin-height=&quot;134&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3VZWd/btrxcaJXWsf/4lhT8WcnfAxo1FWvZUtP61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3VZWd/btrxcaJXWsf/4lhT8WcnfAxo1FWvZUtP61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3VZWd/btrxcaJXWsf/4lhT8WcnfAxo1FWvZUtP61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3VZWd%2FbtrxcaJXWsf%2F4lhT8WcnfAxo1FWvZUtP61%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;994&quot; height=&quot;134&quot; data-origin-width=&quot;994&quot; data-origin-height=&quot;134&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/mapbox/node-pre-gyp/blob/master/lib/util/abi_crosswalk.json&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/mapbox/node-pre-gyp/blob/master/lib/util/abi_crosswalk.json&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;abi라는것이 있는데 이게 node.js를 통해 컴파일된 다른 네이티브 모듈을 실행시켜주는 브릿지 역할을 하는것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 노드 버전과 abi 버전이 일치해야 제대로 빌드가 되는 듯 하다.&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;electron-builder 20버전 이상에서는 robot.js가 절대로 빌드 되지 않는 현상이 발견됬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 electron-builder를 20버전으로 맞춰놓고 다른 패키지를 여기에 맞추는게 낫겠다.&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;찾아보니까 electron-builder로 빌드 할때 bad cpu type이라는 오류가 발생하는 이유가&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #232629;&quot;&gt;If it says something in the lines of&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Mach-O executable i386&lt;span style=&quot;background-color: #ffffff; color: #232629;&quot;&gt;: Apple dropped support for 32bit executables with Catalina 10.15.&lt;/span&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;카탈리나부터 32비트 실행파일에 대한 지원을 중단했다고 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 32비트 실행파일이 포함된걸 빌드하려고 하면 오류가 나는 것 같다. 그래서 로컬에서 도커를 깔아서 도커로 빌드를 하라는데.. 무슨 빌드 하나 하자고 그렇게 까지 해야하나 싶다. wine대신 wine64를 써야 한다는데 뭔 소린지 잘 모르겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/electron/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/electron/releases&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1648110270994&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 - electron/releases:   Complete and up-to-date info about every release of Electron&quot; data-og-description=&quot;  Complete and up-to-date info about every release of Electron - GitHub - electron/releases:   Complete and up-to-date info about every release of Electron&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/electron/releases&quot; data-og-url=&quot;https://github.com/electron/releases&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/GZmbE/hyNOiKKpEE/igKUNGUwkzVc0sV3itHsUK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/electron/releases&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/electron/releases&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/GZmbE/hyNOiKKpEE/igKUNGUwkzVc0sV3itHsUK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&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 - electron/releases:   Complete and up-to-date info about every release of Electron&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;  Complete and up-to-date info about every release of Electron - GitHub - electron/releases:   Complete and up-to-date info about every release of Electron&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기 들어가보면 일렉트론 버전 별로 어떤 abi가 매칭되어있는지 나와있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-paste-markdown-skip=&quot;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;Please upgrade to the latest v23.0.3 for macOS 12.3 support.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, Mac OS 몬터레이는 12.3버전인데 이 OS에서 빌드하려면 electron-builder를 23.0.3로 업데이트 해야 한다고 한다.&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;pre id=&quot;code_1648110696219&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;devDependencies
{
    &quot;electron&quot;: &quot;6.1.12&quot;,
    &quot;electron-builder&quot;: &quot;23.0.2&quot;,
    &quot;robotjs&quot;: &quot;^0.6.0&quot;,
}

package.json &amp;gt; scripts
{
    &quot;postinstall&quot;: &quot;npm rebuild --runtime=electron --target=6.1.12 --disturl=https://atom.io/download/atom-shell --abi=73&quot;,
    &quot;rebuild&quot;: &quot;npm rebuild --runtime=electron --target=6.1.12 --disturl=https://atom.io/download/atom-shell --abi=73&quot;
}

node -&amp;gt; 14.19.1
mac -&amp;gt; monterey v12.3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 일렉트론 버전이 너무 낮아졌다.. 다른 조합도 가능한지 찾아보자.&lt;/p&gt;
&lt;pre id=&quot;code_1648111068972&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    &quot;electron&quot;: &quot;8.5.2&quot;,
    &quot;electron-builder&quot;: &quot;23.0.2&quot;,
    &quot;robotjs&quot;: &quot;^0.6.0,
}

package.json &amp;gt; scripts
{
    &quot;postinstall&quot;: &quot;npm rebuild --runtime=electron --target=8.5.2 --disturl=https://atom.io/download/atom-shell --abi=76&quot;,
    &quot;rebuild&quot;: &quot;npm rebuild --runtime=electron --target=8.5.2 --disturl=https://atom.io/download/atom-shell --abi=76&quot;
}

node -&amp;gt; 14.19.1
mac -&amp;gt; monterey v12.3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- 일렉트론: 6.1.12, abi: 73 -&amp;gt;&lt;span&gt; &lt;b&gt;맥 빌드 성공,&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;- 일렉트론: 7.3.3, abi: 75 -&amp;gt;&lt;span&gt;&amp;nbsp;&lt;b&gt;맥 빌드 성공,&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일렉트론: 8.5.2, abi: 76 -&amp;gt; &lt;b&gt;맥 빌드 성공,&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일렉트론: 9.4.4, abi: 80 -&amp;gt; &lt;b&gt;맥 빌드 실패,&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;-&amp;gt; abi 80부터는 robot.js와 호환이 불가한듯하다.&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;결론은 robot.js 를 사용하려면 현재 17버전이 최신인 일렉트론을 8.5.2까지 밖에 못올린다는 얘기다..&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그래도 성공한 조합을 찾아서 다행이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;robot.js와 같은 오픈소스를 가져다 사용할때 이게 진짜 큰 문제다. 저걸 만든 개발자도 무료로 만들어 배포하다보니 관리, 유지보수, 업데이트가 잘 되지 않는다. 차라리 개발문화가 오픈소스가 아니라 유료였으면 더 좋았을것같다는 생각도 든다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Electron</category>
      <author>심재철</author>
      <guid isPermaLink="true">https://simsimjae.tistory.com/489</guid>
      <comments>https://simsimjae.tistory.com/489#entry489comment</comments>
      <pubDate>Thu, 24 Mar 2022 18:07:13 +0900</pubDate>
    </item>
    <item>
      <title>node-gyp 에러 정리</title>
      <link>https://simsimjae.tistory.com/488</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Node.js로 매크로를 만들어보고 있는 도중에 문제가 발생했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Robot.js라는 라이브러리가 있는데 이 라이브러리는 내부적으로 node-gyp라는 모듈을 사용한다.&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;이 node-gyp라는 모듈은 내부적으로 파이썬 코드가 작성되어 있는 것 같다. 파이썬 코드가 C++로 변환되고 이 C++코드가 최종적으로 네이티브(PC 운영체제)를 조작할 수 있게끔 해주는것이다.&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;그래서 node-gyp 모듈을 포함하는 node 모듈을 설치하려면 ms build tools라고 하는게 미리 설치되어있어야한다.&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;robot.js에서는 node-gyp@5.1.0 버전을 사용하고 있는것같다. 현재 최신버전은 node-gyp@9.1.0이지만 업데이트가 이뤄지지 않고 있는듯하다.&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;어쨌든 node-gyp@5.1.0버전이 의존하고 있는 ms build tools 버전은 2017년 버전이다. 아무 버전이나 설치하면 안되고 반드시&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;node-gyp@5.1.0 버전과 ms build tools 2017년 버전이 같이 쌍으로 설치되어야 동작하는것같다. 그렇지 않으면 robot.js를 설치할때 오류가 난다.&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;</description>
      <category>Electron</category>
      <author>심재철</author>
      <guid isPermaLink="true">https://simsimjae.tistory.com/488</guid>
      <comments>https://simsimjae.tistory.com/488#entry488comment</comments>
      <pubDate>Wed, 23 Mar 2022 18:43:43 +0900</pubDate>
    </item>
    <item>
      <title>electron auto update 기능 총&amp;nbsp;정리</title>
      <link>https://simsimjae.tistory.com/486</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;순서 정리&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. 애플 개발자 계정 준비&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2. Developer Id Application Certificate 발급&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3. 로컬 컴퓨터에 설치&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4. 일렉트론앱에서 업데이트 코드 작성&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;5. hombrew install minio&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;6. mkdir ~/minio-data/test-update&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;7. minio server ~/minio-data&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;8. package.json의 build.publish 부분에 아래 내용 삽입&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1639321434488&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;publish&quot;: {
  &quot;provider&quot;: &quot;s3&quot;,
  &quot;endpoint&quot;: &quot;http://192.168.0.3:9000&quot;, // 로컬 IP
  &quot;bucket&quot;: &quot;test-update&quot; // 로컬 버킷
},&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;9. export AWS_ACCESS_KEY, AWS_SECRET_KEY (각각 minioadmin에서 생성해야함)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;10. package.json의 version 패치 버전 업 (0.1.0 =&amp;gt; 0.1.1)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;11. package.json의 scripts에 electron-builder로 빌드 한 후 publish&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1639321311361&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;clear&quot;: &quot;rm -rf build &amp;amp;&amp;amp; rm -rf dist&quot;,
&quot;build:electron&quot;: &quot;react-app-rewired build &amp;amp;&amp;amp; yarn tsc:electron &amp;amp;&amp;amp; yarn copy:adb&quot;,
&quot;package:publish&quot;: &quot;yarn clear &amp;amp;&amp;amp; yarn build:electron &amp;amp;&amp;amp; electron-builder build -mw -c.extraMetadata.main=build/electron/main.js --publish always&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;12. package.json의 버전 다시 다운 그레이드 (0.1.1 -&amp;gt; 0.1.0)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;13. electorn-builder로 빌드후 패키징 된 앱 실행시 업데이트 코드가 순차적으로 실행됨.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;참고&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://github.com/electron-userland/electron-builder/issues/3053&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/electron-userland/electron-builder/issues/3053&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>Electron</category>
      <author>심재철</author>
      <guid isPermaLink="true">https://simsimjae.tistory.com/486</guid>
      <comments>https://simsimjae.tistory.com/486#entry486comment</comments>
      <pubDate>Mon, 13 Dec 2021 01:11:02 +0900</pubDate>
    </item>
    <item>
      <title>시/도 + 시/군/구 CSV파일</title>
      <link>https://simsimjae.tistory.com/485</link>
      <description>&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/Keg3K/btrmCOkrhAc/UwefACB7zeDJnHHmSO4tHK/%E1%84%89%E1%85%B5%E1%84%83%E1%85%A9%E1%84%89%E1%85%B5%E1%84%80%E1%85%AE%E1%86%AB%E1%84%80%E1%85%AE.csv?attach=1&amp;amp;knm=tfile.csv&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;시도시군구.csv&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.02MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Nest.js</category>
      <author>심재철</author>
      <guid isPermaLink="true">https://simsimjae.tistory.com/485</guid>
      <comments>https://simsimjae.tistory.com/485#entry485comment</comments>
      <pubDate>Wed, 1 Dec 2021 12:02:16 +0900</pubDate>
    </item>
    <item>
      <title>전국에 있는 모든 시/군/구의 동/읍/면/리 데이터</title>
      <link>https://simsimjae.tistory.com/484</link>
      <description>&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://www.code.go.kr/stdcode/regCodeL.do&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.code.go.kr/stdcode/regCodeL.do&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에서 제공하는 데이터는 시/도, 시/군/구 2뎁스 까지 밖에 제공을 안해준다. 동/읍/면/리까지 표현하기 위해서 테이블을 업데이트 쳐야함&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bhu9TY/btrlZvSGX9n/pykHhR4uMATDExKB4Ew640/dong-query.txt?attach=1&amp;amp;knm=tfile.txt&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;dong-query.txt&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;3.13MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/wavt9/btrlYN0AxX7/OfzhVX26gwlkuNOvbHKCFk/dong.json?attach=1&amp;amp;knm=tfile.json&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;dong.json&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.96MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bqC0bS/btrl0agrDTC/4qCJXk2aooGLKdIM30VbZ1/address.txt?attach=1&amp;amp;knm=tfile.txt&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;address.txt&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;2.58MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/uxMcb/btrlUOzcEub/gbWNxRtDWTr2klOJ4dikHk/address.js?attach=1&amp;amp;knm=tfile.js&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;address.js&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Nest.js</category>
      <author>심재철</author>
      <guid isPermaLink="true">https://simsimjae.tistory.com/484</guid>
      <comments>https://simsimjae.tistory.com/484#entry484comment</comments>
      <pubDate>Tue, 23 Nov 2021 20:11:38 +0900</pubDate>
    </item>
    <item>
      <title>DTO Validation을 PickType으로 생성할때 발생하는 이슈</title>
      <link>https://simsimjae.tistory.com/483</link>
      <description>&lt;pre id=&quot;code_1631073044995&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Exclude()
@Entity()
export class User extends BaseEntity {
  @ApiProperty()
  @Expose()
  @PrimaryGeneratedColumn('uuid', { name: 'user_id' })
  id: string;

  @ApiProperty({ default: '01024094270' })
  @Expose()
  @IsNotEmpty({ message: '휴대폰번호를 입력해주세요.' })
  @IsPhone({ message: '휴대폰번호가 잘못 입력되었습니다.' })
  @Column({ unique: true })
  phone: string;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 아래와 같이 Custom Validator를 만들었다.&lt;/p&gt;
&lt;pre id=&quot;code_1631073254879&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@ValidatorConstraint({ name: 'PhoneValidator' })
@Injectable()
export class PhoneValidator implements ValidatorConstraintInterface {
  message = '휴대폰 번호가 잘못 입력되었습니다.';

  constructor(private readonly authService: AuthService, private readonly usersService: UsersService) {}

  async validate(phone: string, { object }: ValidationArguments) {
    try {
      if (phone &amp;amp;&amp;amp; !object['code']) {
        this.message = '휴대폰 인증번호를 입력해주세요.';
        return false;
      }
      if (phone &amp;amp;&amp;amp; !(await this.authService.isPhoneAuthenticated(phone, object['code']))) {
        this.message = '휴대폰번호를 인증해주세요.';
        return false;
      }
      if (await this.usersService.findByPhone(phone)) {
        this.message = '이미 사용중인 휴대폰번호입니다.';
        return false;
      }
    } catch (e) {
      return false;
    }
    return true;
  }

  defaultMessage(args: ValidationArguments) {
    return this.message;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1631073286632&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Exclude()
@Entity()
export class User extends BaseEntity {
  @ApiProperty()
  @Expose()
  @PrimaryGeneratedColumn('uuid', { name: 'user_id' })
  id: string;

  @ApiProperty({ default: '01024094270' })
  @Expose()
  @Validate(PhoneValidator) // Custom Validator 추가
  @IsNotEmpty({ message: '휴대폰번호를 입력해주세요.' })
  @IsPhone({ message: '휴대폰번호가 잘못 입력되었습니다.' })
  @Column({ unique: true })
  phone: string;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고나서 방금 만든 Custom Validator를 엔티티에 추가하고 나서 PickType을 활용하여 아래와 같이 Dto를 만들었다.&lt;/p&gt;
&lt;pre id=&quot;code_1631073363412&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class UserDto extends IntersectionType(PickType(User, ['phone', 'thumbnail']) {};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전혀 아무런 문제가 없어야 정상이지만..&lt;/p&gt;
&lt;pre id=&quot;code_1631073385287&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ cross-env NODE_ENV=local node ./node_modules/typeorm/cli.js schema:drop
Error during schema drop:

TypeError: Cannot read property 'prototype' of undefined
    at Object.PickType (/Users/simsimjae/Desktop/chium-back/node_modules/@nestjs/swagger/dist/type-helpers/pick-type.helper.js:13:39)
    at Object.&amp;lt;anonymous&amp;gt; (/Users/simsimjae/Desktop/chium-back/dist/src/modules/auth/dto/auth.dto.js:24:60)&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;나는 로컬에서 개발할때 스키마를 drop, sync, seeding을 순차적으로 진행하게끔 설정했는데 맨 처음에 스키마를 drop할때 문제가 발생했다.&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;원인을 찾아보고 난 결론은 Entity에 Validator가 섞여있게 되면 알 수 없는 오류가 발생할 가능성이 높아진다는것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;typeorm이 무언가 Entity를 조작하는 과정에서 Custom Validator 때문에 망가진것같으나 정확한 원인은 찾을 수 없었다.&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;그래서 아래와 같이 Validator와 Entity를 분리하는 방식으로 해결하였다.&lt;/p&gt;
&lt;pre id=&quot;code_1631073555919&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class UserDto extends IntersectionType(PickType(User, ['phone', 'thumbnail']) {
  @Validate(PhoneValidator)
  phone: string;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Nest.js</category>
      <category>Nest.js</category>
      <category>swagger</category>
      <category>typeorm</category>
      <author>심재철</author>
      <guid isPermaLink="true">https://simsimjae.tistory.com/483</guid>
      <comments>https://simsimjae.tistory.com/483#entry483comment</comments>
      <pubDate>Wed, 8 Sep 2021 12:59:21 +0900</pubDate>
    </item>
    <item>
      <title>토큰을 어디에 저장해야 안전할까</title>
      <link>https://simsimjae.tistory.com/482</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;이 글은 독자가 JWT, 세션등에 대한 이해를 갖고 있다는 전제하에 정리 차원에서 작성한 글입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;TL;DR&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. &lt;b&gt;리프레시 토큰&lt;/b&gt;은 HTTP ONLY SECURE 쿠키에 저장하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;액세스 토큰&lt;/b&gt;은 프로그램상 자바스크립트 로컬 변수에 저장하고, http 헤더에 bearer 토큰으로 담아서 매 요청마다 보내도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 로컬스토리지는 사용하지 말자. (보안에 매우 취약)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;브라우저 어디에 토큰을 저장해야 안전할까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저에서 JWT를 저장할 수 있는 곳은 로컬스토리지, 쿠키 두군데가 있다. 하지만 로컬스토리지나 쿠키나 모두 자바스크립트로 읽을 수 있는 값들이기 때문에 아무런 처리없이 이곳에 저장하면 굉장히 보안에 취약하다. 해커가 이미지 태그 혹은 브라우저 URL에 자바스크립트를 삽입 할 수 있는 취약점이 있다면 이렇게 로컬스토리지나 쿠키에 저장된 토큰은 바로 허술하게 털려버린다.&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;브라우저의 로컬스토리지는 정말 편리하지만 XSS를 방어할 수 있는 방법이 없기 때문에 로컬스토리지보다는 쿠키가 그나마 더 보안에 낫다. &lt;b&gt;단, 이 쿠키카 Http Only이며 Secure(https)옵션이 켜져있을때 그렇다. 이 말은 쿠키를 자바스크립트로 읽어올 수 없다는 말이고 네트워크 감청을 통한 쿠키값 읽기를 방어한다는 말이다. 즉, XSS 공격을 통한 토큰 탈취를 방지할 수 있다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 &lt;u&gt;Http Only Secure 쿠키에 액세스토큰과 리프레시 토큰을 둘다 저장해야 하는가?&lt;/u&gt; 라고 질문하면 &lt;u&gt;&lt;b&gt;그것도 그렇지 않다.&lt;/b&gt;&lt;/u&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;왜냐면, 쿠키라는것이 브라우저가 서버에 요청을 보낼떄 자동으로 포함해서 보내는 값이기 때문이다. 만약에 그 쿠키값안에 세션ID나 엑세스토큰이 들어있다면 해커가 내 인증정보를 활용해서 서버에 나인것처럼 속여서 요청을 보낼 수 있게 된다. 이게 CSRF공격이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;CSRF 공격?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안은 시나리오를 생각해보면 이해가 빠른 것 같다. 내 사이트에 관리자로 로그인한 상태로(쿠키에 세션ID 혹은 엑세스토큰이 담겨져있다고 해보자.) 네이버 메일을 열었는데, 해커가 보낸 메일 속 이미지에 내 사이트 서버에 어떤 A 유저의 정보를 삭제하는 API 주소가 적혀있다고 해보자. &lt;br /&gt;&lt;br /&gt;나는 그 유저 정보 삭제 API를 호출하고 싶지 않았는데 브라우저는 이미지 태그 안에 있는 스크립트를 자동으로 실행하기 때문에 갑자기 A유저 정보가 삭제되는 대참사가 발생한다. (내 브라우저 쿠키에는 인증 정보를 갖고 있기 때문에.. 브라우저 입장에서는 해커가 그 요청을 보낸게 아니라 내가 보낸게 되어버림..) 이게 바로 &lt;b&gt;Cross Site Resource Forgery(교차 사이트 요청 위조 공격)이다.&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Referer 체크 (요청이 어디서 왔는가?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. CSRF 토큰 (난수 생성해서 서버에서 확인하는 방법)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두가지가 있다. 아무튼 여기까지가 CSRF에 대한 설명이다.&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;쿠키라는것이 결국에 브라우저에서 자동으로 보내는값이기 때문에 인증에 활용하기도 하지만 그것때문에 CSRF 보안에 취약하다. 그래서 결론은 &lt;u&gt;&lt;b&gt;리프레시 토큰만 http only secure 쿠키에 저장하고 액세스 토큰은 프로그램상 로컬변수에 담아 놓는것이 그나마 제일 안전하다.&lt;/b&gt;&lt;/u&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;1. 해커가 CSRF 공격을 하더라도 쿠키에는 액세스토큰이 없기 때문에 인증 불가 상태가 되어 공격이 차단된다.&lt;br /&gt;2. 해커는 http only secure 쿠키 특성상 리프레시 토큰 자체를 털 방법이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 액세스 토큰은 로컬 변수에 저장되어 있기 때문에 XSS를 통해 액세스 토큰 자체를 털 수 없다.&lt;br /&gt;&amp;nbsp; &amp;nbsp; 외부에서 삽입한 자바스크립트로 로컬 변수에 접근하는것이 불가능하기 때문에 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;-&amp;gt; 물론 액세스 토큰을 활용하여 유저 정보를 탈취할 수 는있다. (그래서 어찌됬건 XSS 처리는 꼭 해야함)&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;XSS는 완벽하게 막을 수 없는데 그 이유는 어찌됬건 내가 인증을 한 상태에서는 서버에서 나에게 허용된 어떤 API들이 있는데 그 API들은 마찬가지로 XSS를 통해 해커도 호출할 수 있다는 얘기기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어쨌든 &lt;b&gt;&lt;u&gt;액세스토큰은 지속적으로 네트워크를 타며 노출될 가능성이 높기 때문에 만료시간을 짧게 가져가야 한다.&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 &lt;b&gt;쿠키에 저장된 리프레시토큰을 가지고 매번 액세스 토큰을 갱신해가면서 사용하도록 로직을 구성해야한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로, 사용성을 위해 액세스 토큰이 HTTP 헤더에 없거나 만료된 경우 리프레시 토큰으로 조용히 토큰 재발급 과정이 일어날 수 있도록 로직을 작성해야한다. &lt;b&gt;(silent token refresh)&lt;/b&gt;&lt;/p&gt;</description>
      <category>Today I Learned</category>
      <author>심재철</author>
      <guid isPermaLink="true">https://simsimjae.tistory.com/482</guid>
      <comments>https://simsimjae.tistory.com/482#entry482comment</comments>
      <pubDate>Thu, 2 Sep 2021 10:41:04 +0900</pubDate>
    </item>
    <item>
      <title>컴포넌트의 네이밍</title>
      <link>https://simsimjae.tistory.com/480</link>
      <description>&lt;p&gt;작업을 하다가 갑자기 궁금한게 생겨서 레퍼런스를 조사해야겠다는 생각이 들었다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;비슷하게 생기고 비슷한 기능들을 컴포넌트들을 과연 어떻게 네이밍하는것이 좋은 네이밍일까??&lt;/p&gt;
&lt;p&gt;예를들어 서로 비슷하게 생긴 카드들을 카드1, 카드2, 카드3 ... 이렇게 하는게 차선일까?? 아니면 그 카드가 어떻게 생겼는지 형태에 따라 구분하는게 맞을까? 아니면 그 카드가 어디서 쓰이는지를 기준으로 네이밍하는게 맞을까?? 여러 생각들이 들었다. 다른사람들은 어떻게 생각하는지 레퍼런스를 정리해보겠다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;네이밍은 카테고리와 역할에 따라 구분해야한다.&lt;/p&gt;
&lt;ul&gt;
&lt;li data-text-variant=&quot;body-copy-400&quot;&gt;&lt;b&gt;Category:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;mobile, inverse, ui&lt;/li&gt;
&lt;li data-text-variant=&quot;body-copy-400&quot;&gt;&lt;b&gt;Type:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;header, hero, title, subtitle, paragraph, button, input, caption&lt;/li&gt;
&lt;li data-text-variant=&quot;body-copy-400&quot;&gt;&lt;b&gt;Size:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;large, medium, small, default&lt;/li&gt;
&lt;li data-text-variant=&quot;body-copy-400&quot;&gt;&lt;b&gt;Alignment:&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;left, center, right&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;웹페이지상에서 해당 컴포넌트가 어떤 역할을 하느냐?(헤더인지 히어로인지 타이틀인지 서브타이틀인지 등등...)를 기준으로 네이밍해야한다라는 의견이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;반면 material-ui에서는 형태에 따라 컴포넌트를 네이밍하고 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;하나의 Avatar라는 컴포넌트가 있고 이 아바타에 어떤 props를 넘기냐에 따라서 다르게 네이밍하고있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cx0fjO/btq4bP9Re3i/eMI3OaqGiw4XtusO5g4SHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cx0fjO/btq4bP9Re3i/eMI3OaqGiw4XtusO5g4SHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cx0fjO/btq4bP9Re3i/eMI3OaqGiw4XtusO5g4SHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcx0fjO%2Fbtq4bP9Re3i%2FeMI3OaqGiw4XtusO5g4SHK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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&gt;반면 Antd는 기능에따라 컴포넌트를 네이밍하고있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;350&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3CQt6/btq4f9Mhh9Z/BSGzQbQWgbUjQq8TNqgPB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3CQt6/btq4f9Mhh9Z/BSGzQbQWgbUjQq8TNqgPB1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3CQt6/btq4f9Mhh9Z/BSGzQbQWgbUjQq8TNqgPB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3CQt6%2Fbtq4f9Mhh9Z%2FBSGzQbQWgbUjQq8TNqgPB1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;350&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;메뉴, 네비게이션, 레이아웃, 페이지네이션 등등은 해당 컴포넌트가 어떤 기능을 하는지를 요약한 이름인것이다. 형태에 따른 구분이 아니다. 둥근, 네모난, 각진.. 이런 형용사들이 들어가야 형태에 따른 구분이라고 할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다음은 내가 좋아하는 차크라UI의 네이밍이다. 여기도 마찬가지로 형태가 아닌 컴포넌트의 기능과 역할을 기준으로 네이밍하고 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;288&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ArRL4/btq4gaj7fFN/a52nhLwIRib7GXEMnbKCok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ArRL4/btq4gaj7fFN/a52nhLwIRib7GXEMnbKCok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ArRL4/btq4gaj7fFN/a52nhLwIRib7GXEMnbKCok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FArRL4%2Fbtq4gaj7fFN%2Fa52nhLwIRib7GXEMnbKCok%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; width=&quot;288&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&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&gt;몇개의 레퍼런스들을 더 찾아보니 아직까지도 &lt;b&gt;절대적인 best practices는 없는 것 같다. &lt;/b&gt;하지만 형태보다는 기능을 기준으로 네이밍한곳이 더 많은 것 같긴 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://material-ui.com/components/dialogs/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;material-ui.com/components/dialogs/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.invisionapp.com/inside-design/naming-conventions/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.invisionapp.com/inside-design/naming-conventions/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>React</category>
      <author>심재철</author>
      <guid isPermaLink="true">https://simsimjae.tistory.com/480</guid>
      <comments>https://simsimjae.tistory.com/480#entry480comment</comments>
      <pubDate>Wed, 5 May 2021 21:13:43 +0900</pubDate>
    </item>
  </channel>
</rss>