<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>프론트 엔드 개발 기록</title>
    <link>https://dribbles.tistory.com/</link>
    <description>프론트 엔드 개발에 대해 공부하면서 남기고 싶은 내용들을 기록합니다.</description>
    <language>ko</language>
    <pubDate>Sat, 6 Jun 2026 19:11:51 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>yemsu</managingEditor>
    <item>
      <title>[Node.js] JavaScript 개발 환경 구축하기</title>
      <link>https://dribbles.tistory.com/61</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;시작하기 전  &lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;❓ node.js 쓰면 무엇이 좋을까&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예전엔 폴더 하나 만들고 그 안에 &lt;code&gt;html&lt;/code&gt;, &lt;code&gt;js&lt;/code&gt;파일 만들어서 작업했었다.&lt;br /&gt;이번엔 node.js 환경을 구축해서 작업해보고 싶었는데, 개념과 장점을 명확히 알고 쓰고싶었다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node (또는 더 공식적으로는 Node.js) 는 오픈소스, 크로스 플랫폼이며, 개발자가 모든 종류의 서버 사이드 도구들과 어플리케이션을 JavaScript로 만들수 있도록 해주는 런타임 환경이다.런타임은 브라우져 영역 밖에서도 사용할수 있도록 의도했다.(예를들면 서버 OS 또는 컴퓨터에서 직접적으로 실행되는). 이와 같이, 이 환경에서 특정 브라우져에서의 자바스트립트 API들을 제외시키고 , HTTP 와 파일 시스템 라이브러리들을 포함하여 더 많은 전형적인 OS API들을 추가했다.&lt;br /&gt;- &lt;a href=&quot;https://developer.mozilla.org/ko/docs/Learn/Server-side/Express_Nodejs/Introduction#express%EC%99%80_node%EB%9E%80&quot;&gt;MDN&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;b&gt;node.js와 친해지는 기회 &lt;/b&gt;&lt;/li&gt;
&lt;li&gt;es6사용을 위한 라이브러리를 간편하게 설치할 수 있음&lt;/li&gt;
&lt;li&gt;새로운 라이브러리와 패키지 설치가 용이하고 package.json에 보기 좋게 정리됨&lt;/li&gt;
&lt;li&gt;간편하게 서버 구축이 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;❓ yarn or npm&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 node.js 관련 이것저것 찾아보다가 &lt;code&gt;npm&lt;/code&gt;보다 &lt;code&gt;yarn&lt;/code&gt;이 더 업그레이드된 패키지 관리 도구라고해서 &lt;code&gt;yarn&lt;/code&gt;을 사용하려고 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Yarn은 Facebook이 개발한 패키지 매니저다. 점점 거대해지는 프로젝트에서 npm을 사용하며 일관성, 보안, 빌드 시 성능 등에 문제를 겪은 Facebook은 npm을 대체할 새로운 패키지 관리 도구인 Yarn을 개발했다. 이 글에서도 프로젝트의 생성과 관리에 Yarn을 사용할 것이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://d2.naver.com/helloworld/2564557&quot;&gt;https://d2.naver.com/helloworld/2564557&lt;/a&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;br /&gt;기능 추가 및 리팩토링이 수월해진다고 보았는데 이번 기회에 해보기로 한다.&lt;br /&gt;&lt;a href=&quot;https://d2.naver.com/helloworld/2564557&quot;&gt;위 참고 페이지&lt;/a&gt;에 시작하는 방법이 나와있으니 따라서 해본다! 아주 옛날 글이지만 정리가 굉장히 잘 되어있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 프로젝트 생성&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;yarn&lt;/code&gt;을 설치한적 없다면 먼저 설치&lt;/p&gt;
&lt;pre class=&quot;cmake&quot;&gt;&lt;code&gt;npm install -g yarn&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;yarn&lt;/code&gt; 프로젝트를 생성&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;yarn init -y&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;-y&lt;/code&gt; 플래그를 사용하여 기본 설정으로 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;package파일이 생성됐다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  package.json&lt;/h4&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;vanilla-poll-graph&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;main&quot;: &quot;index.js&quot;,
  &quot;license&quot;: &quot;MIT&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 프로젝트를 git 원격 저장소에 연결하고&lt;br /&gt;&lt;code&gt;.gitignore&lt;/code&gt;에 &lt;code&gt;node_modules&lt;/code&gt;를 추가했다&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Jest로 테스트 환경 설정하기&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-1. 폴더 생성&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 폴더들을 루트 경로에 생성하고 파일들을 각 폴더 안에 생성했다.&lt;br /&gt;이번에 그래프 기능을 개발할거라 graph로 네이밍 해줬다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;  &lt;b&gt;_&lt;i&gt;test_&lt;/i&gt;&lt;/b&gt; // 테스트 코드를 저장할 폴더&lt;/li&gt;
&lt;li&gt;  &lt;b&gt;lib&lt;/b&gt; // 구현 코드를 저장할 폴더&lt;/li&gt;
&lt;li&gt;  &lt;b&gt;graph.test.js&lt;/b&gt; // 테스트 코드 파일&lt;/li&gt;
&lt;li&gt;  &lt;b&gt;graph.js&lt;/b&gt; // 구현 코드 파일&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 폴더, 파일을 생성하는 명령어.&lt;br /&gt;마우스로 손을 움직이고 커서를 또 폴더 경로로 이동시키고 우클릭 등등... 의 수고를 많이 줄여준다.&lt;/p&gt;
&lt;pre class=&quot;crystal&quot;&gt;&lt;code&gt;$ mkdir __tests__ lib
$ touch __tests__/graph.test.js lib/graph.js&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-2. Jest 설치/NPM 커맨드 지정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패키지 설치&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;yarn add -D jest&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;scripts&lt;/code&gt;속성에 테스트 명령어 지정&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  package.json&lt;/h4&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;scripts&quot;: {
    &quot;test&quot;: &quot;jest&quot;    // Jest CLI 명령문 설정
  },
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2-3. 임시 소스 삽입/테스트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 참고할 수 있는 소스를 &lt;a href=&quot;https://jestjs.io/docs/getting-started&quot;&gt;Jest 공식문서&lt;/a&gt;에서 가져와 넣어두었다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  _&lt;i&gt;test_&lt;/i&gt;/graph.test.js&lt;/h4&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;// 임시 확인용 소스
const sum = require('../lib/graph');

test('adds 1 + 2 to equal 3', () =&amp;gt; {
  expect(sum(1, 2)).toBe(3);
});    &lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  lib/graph.js&lt;/h4&gt;
&lt;pre class=&quot;fortran&quot;&gt;&lt;code&gt;// 임시 확인용 소스
function sum(a, b) {
  return a + b;
}
module.exports = sum;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커맨트 입력하여 테스트 실행&lt;/p&gt;
&lt;pre class=&quot;bash&quot;&gt;&lt;code&gt;yarn test&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PASS! 이렇게 뜨는구나.&lt;br /&gt;테스트 코드에 대해 감이 좀 잡히면 포스팅에 업데이트해야지 &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://images.velog.io/images/sssjsjj/post/f10a877f-222d-48c1-967a-1aea133294f8/image.png&quot; alt=&quot;Jest 실행 성공&quot; /&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. &lt;a href=&quot;https://babeljs.io/docs/en/usage&quot;&gt;Babel&lt;/a&gt;로 ES6+ 환경 설정하기&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-1. Babel CLI 설치&lt;/h3&gt;
&lt;pre class=&quot;llvm&quot;&gt;&lt;code&gt;yarn add -D @babel/core @babel/cli @babel/preset-env&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;@babel/core&lt;/code&gt; : babel이 트랜스파일 할 수 있게 해준다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@babel/cli&lt;/code&gt; : CLI에서 babel을 실행할 수 있게 해준다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@babel/preset-env&lt;/code&gt; : &lt;code&gt;.babelrc&lt;/code&gt;의 &lt;code&gt;targets&lt;/code&gt; 옵션에 선언된 환경에 대응할 수 있는 plugin들을 모아놓은 preset 라이브러리. 가장 많이 쓰인다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  package.json&lt;/h4&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;devDependencies&quot;: {
    &quot;@babel/cli&quot;: &quot;^7.17.3&quot;,            // NEW
    &quot;@babel/core&quot;: &quot;^7.17.5&quot;,            // NEW
    &quot;@babel/preset-env&quot;: &quot;^7.16.11&quot;,    // NEW
    &quot;jest&quot;: &quot;^27.5.1&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-2. Babel 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 루트에 &lt;code&gt;.babelrc&lt;/code&gt; 파일 생성&lt;/p&gt;
&lt;pre class=&quot;elixir&quot;&gt;&lt;code&gt;$ touch .babelrc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 &lt;code&gt;@babel/preset-env&lt;/code&gt; preset을 사용하겠다고 설정하고&lt;br /&gt;어떤 브라우저에 대응할지 &lt;code&gt;targets&lt;/code&gt; 옵션에 선언했다. (&lt;a href=&quot;https://babeljs.io/docs/en/usage&quot;&gt;바벨 공식 문서&lt;/a&gt;에 있는 옵션)&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  .babelrc&lt;/h4&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;presets&quot;: [
    [
      &quot;@babel/preset-env&quot;,
      {
        &quot;targets&quot;: {        
          &quot;edge&quot;: &quot;17&quot;,
          &quot;firefox&quot;: &quot;60&quot;,
          &quot;chrome&quot;: &quot;67&quot;,
          &quot;safari&quot;: &quot;11.1&quot;
        }
    ]
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-3. NPM 커맨드 지정&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  package.json&lt;/h4&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;scripts&quot;: {
    &quot;build&quot;: &quot;babel lib -w -d dist/js&quot;  // Babel CLI 명령어
    &quot;test&quot;: &quot;jest&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  Babel CLI 명령어&lt;/h4&gt;
&lt;pre class=&quot;crystal&quot;&gt;&lt;code&gt;babel src/lib -w -d dist/js&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;lib&lt;/code&gt; : 해당 경로의 폴더 안에 있는 JS파일을 트랜스파일링&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-w&lt;/code&gt; : 파일들의 변경 감지 (--watch 축약형)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-d dist/js&lt;/code&gt; : 트랜스파일링된 파일 저장 경로 (--out-dir 축약형)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3-4. Babel 실행&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 해보기 위해 graph.js에 &lt;code&gt;arrow function&lt;/code&gt;과 &lt;code&gt;Set&lt;/code&gt;을 사용 후 빌드해보았다.&lt;br /&gt;그러나 아래와 같이 상단에 &lt;code&gt;&quot;use strict&quot;;&lt;/code&gt;만 추가되고 변한게 없다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  lib/graph.js&lt;/h4&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function graph(num) {
  const setInstance = new Set([1, 2, 3, 4, 5]);
  const hasNum = () =&amp;gt; setInstance.has(num)
  return hasNum
}
module.exports = graph&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  dist/js/graph.js&lt;/h4&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;&quot;use strict&quot;;

function graph(num) {
  const setInstance = new Set([1, 2, 3, 4, 5]);

  const hasNum = () =&amp;gt; setInstance.has(num);

  return hasNum;
}

module.exports = graph;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;&quot;ie&quot;: &quot;11&quot;&lt;/code&gt;을 &lt;code&gt;targets&lt;/code&gt;에 추가하고 빌드해봤더니 &lt;code&gt;const&lt;/code&gt;와 &lt;code&gt;arrow function&lt;/code&gt;이 바뀐 것을 볼 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  dist/js/graph.js&lt;/h4&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;&quot;use strict&quot;;

function graph(num) {
  var setInstance = new Set([1, 2, 3, 4, 5]);

  var hasNum = function hasNum() {
    return setInstance.has(num);
  };

  return hasNum;
}

module.exports = graph;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 &lt;code&gt;Set&lt;/code&gt;은 여전하다. &lt;code&gt;Set&lt;/code&gt;같은 ES6의 객체들은 ES5로 구문 변환만 해서는 안되고 해당 객체들을 정의하는 polyfill을 추가해줘야 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. Babel Polyfill 설정하기&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-1. polyfill이란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;polyfill이 정확히 무엇이고 왜 바벨 폴리필을 가져오는 방식이 바뀌었는지 아래 글에 잘 설명되어있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폴리필(Polyfill)은 구형 브라우저에서 지원하지 않는 기능을 제공하는 코드를 의미합니다. ES6의 Promise 같은 객체들은 ES5에 존재하지 않으므로 구문 변환 뿐만 아니라 해당 객체들을 정의하는 코드인 바벨 폴리필(babel polyfill)을 추가해야 합니다.&lt;br /&gt;...&lt;br /&gt;폴리필(polyfill)은 충전솜이라는 의미를 가지고 있습니다.&lt;br /&gt;ES5에 비어있는 ES6 객체, 메소드들을 충전솜처럼 폴리필이 채워줍니다&lt;br /&gt;...&lt;br /&gt;과거에는 &lt;code&gt;@babel/polyfill&lt;/code&gt; 패키지를 직접 전역 스코프에 가져오는(import) 방식으로 바벨 폴리필을 추가했지만 deprecated 되었습니다. 현재는 &lt;code&gt;core-js/stable&lt;/code&gt;과 &lt;code&gt;regenerator-runtime/runtime&lt;/code&gt; 패키지를 직접 전역 스코프에 삽입합니다. 이러한 바벨 폴리필 삽입 방법은 웹채팅처럼 고객 페이지에 삽입되는 애플리케이션인 경우 고객의 전역 스코프를 오염시키는 문제가 있습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://tech.kakao.com/2020/12/01/frontend-growth-02/&quot;&gt;kakao Tech&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;전역 스코프를 오염시키는 문제&lt;/b&gt;가 있어서 오염시키지 않고 적용하는 방법이 있다고 하지만, 아직 완벽히 이해가 되진 않는다. 나중에 오류를 만나게되면 그때 해결하면서 이해하기로 했다.&lt;br /&gt;요번엔 전역으로 우선 설정한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-2. useBuiltIns 옵션 설정&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;preset-env&lt;/code&gt; 프리셋의 폴리필 삽입 방식을 설정하는 옵션입니다. 옵션 값으로 &lt;code&gt;usage&lt;/code&gt;, &lt;code&gt;entry&lt;/code&gt;, &lt;code&gt;false&lt;/code&gt;를 사용할 수 있습니다. &lt;code&gt;false&lt;/code&gt; 이외의 옵션을 사용하면 최신 자바스크립트 폴리필이 포함된 standard javascript library인 &lt;code&gt;core-js&lt;/code&gt; 모듈을 가져오는(import) 코드를 타깃 브라우저에 맞게 삽입/수정합니다. 옵션 값에 따른 폴리필 삽입 방식을 살펴보겠습니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://tech.kakao.com/2020/12/01/frontend-growth-02/&quot;&gt;kakao Tech&lt;/a&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  useBuiltIns 옵션 종류&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;&lt;b&gt;usage&lt;/b&gt;&lt;/code&gt;&lt;br /&gt;: 실제 사용한 폴리필만 삽입된다. import 문 변경이 아닌 삽입이므로 폴리필 모듈을 전역 스코프에 삽입하지 않아도 된다.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-javascript&quot;&gt;//before transpiling
Promise.resolve().finally();

//after transpiling
require(&quot;core-js/modules/es.promise.finally&quot;);

Promise.resolve().finally();&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;b&gt;entry&lt;/b&gt;&lt;/code&gt;&lt;br /&gt;: 폴리필 모듈을 전역 스코프에 직접 삽입하면 타깃 환경에 필요한 폴리필만 전역 스코프에 추가된다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&lt;b&gt;false&lt;/b&gt;&lt;/code&gt;&lt;br /&gt;: default 값. 사용 안함.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 사용한 폴리필만 삽입되는 &lt;code&gt;usage&lt;/code&gt;옵션이 있으면, 전역으로 타깃 환경에 필요한 폴리필을 미리 추가하는 &lt;code&gt;entry&lt;/code&gt;를 사용할 일은 없지않나 싶었다.&lt;br /&gt;&lt;code&gt;entry&lt;/code&gt;의 사용해도 되고 사용하면 얻을 수 있는 이점이 무엇인지 궁금했다.&lt;br /&gt;하지만 이쪽을 계속 파자니 한도 끝도 없어서 우선 나는 여기까지만 알아보고 &lt;code&gt;usage&lt;/code&gt;를 사용하기로 결정! &lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-3. corejs 옵션 설정&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;corejs 옵션은 useBuiltIns 옵션과 함께 사용해야 합니다. 해당 옵션은 삽입되는 core-js 모듈의 버전을 설정합니다. default 값은 2이고, version 2는 업데이트가 중단되었기 때문에 현재는 version 3를 사용해야 합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://tech.kakao.com/2020/12/01/frontend-growth-02/&quot;&gt;kakao Tech&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;꼼꼼하게 정리된 kakao Tech 글을 보면서 차근차근 따라했다.&lt;br /&gt;테스트를 위해 넣었던 ie는 타겟옵션에서 제거했다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  .babelrc&lt;/h4&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;presets&quot;: [
    [
      &quot;@babel/preset-env&quot;,
      {
        &quot;targets&quot;: {
          &quot;edge&quot;: &quot;17&quot;,
          &quot;firefox&quot;: &quot;60&quot;,
          &quot;chrome&quot;: &quot;67&quot;,
          &quot;safari&quot;: &quot;11.1&quot;
        },
        &quot;useBuiltIns&quot;: &quot;usage&quot;,
        &quot;corejs&quot;: &quot;3&quot;  // NEW
      }
    ]
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4-4. Babel 실행&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈이 추가 된 것을 확인할 수 있다. ️&amp;zwj;♀️&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  dist/js/graph.js&lt;/h4&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;&quot;use strict&quot;;

require(&quot;core-js/modules/web.dom-collections.iterator.js&quot;);

function graph(num) {
  const setInstance = new Set([1, 2, 3, 4, 5]);

  const hasNum = () =&amp;gt; setInstance.has(num);

  return hasNum;
}

module.exports = graph;&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. 로컬 서버 구축하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Express가 많이 나와있지만 우선 Node.js로만 구축해보기로했다.&lt;br /&gt;Node.js로만 서버 구축하는건 아래처럼 불편한점이 많다고 한다.&lt;br /&gt;직접 느껴보고 나중에 Express 프레임워크를 써보기로 한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 HTML을 전송해보았는데요. 코드가 너무 반복되고, 페이지 별로 HTML을 따로 만들어야하며, 이를 각각 주소와 일일히 연결해야하는 단점이 있습니다. 페이지가 수십 페이지 이상 늘어난다고 생각해보세요. 매번 GET 요청인지 확인하고, 주소를 파악하고, fs로 매칭되는 파일을 읽어서 브라우저로 전송해야 합니다. 이렇게 해서는 실제 서비스는 무리겠죠? 다음 시간에는 이 귀찮은 과정을 간단히 해결해 줄 Express 프레임워크에 대해서 알아봅시다!&lt;br /&gt;...&lt;br /&gt;Express 프레임워크는 코드의 양도 줄여주고 추후 유지보수가 쉽도록 만들어주기 때문에 사용합니다. 하지만 성능은 이전 시간의 생 코드보다는 떨어집니다. 하지만 크게 영향은 없기 때문에 사용해도 됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;a href=&quot;https://www.zerocho.com/category/NodeJS/post/57774a8eacbd2e9803de0195&quot;&gt;zerocho&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-1. Node.js 서버 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  개발 서버 실행을 위해 세팅 했던 것으로, 뒤쪽에서 webpack-dev-server로 대체됨  &lt;br /&gt;프로젝트 루트에 &lt;code&gt;app.js&lt;/code&gt; 파일 생성&lt;/p&gt;
&lt;pre class=&quot;elixir&quot;&gt;&lt;code&gt;$ touch app.js&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://nodejs.org/ko/docs/guides/getting-started-guide/&quot;&gt;node.js 공식 문서&lt;/a&gt; 와 &lt;a href=&quot;https://www.zerocho.com/category/NodeJS/post/57774a8eacbd2e9803de0195&quot;&gt;zerocho 블로그&lt;/a&gt;를 참고해서 아래와 같이 작성했다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  app.js&lt;/h4&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;const http = require('http'); // 서버 만드는 모듈
const url = require('url'); // 주소 분석 모듈
const fs = require('fs'); // 파일을 읽고 쓰는 모듈

const hostname = '127.0.0.1';
const port = 3000;
/*
localhost주소를 입력하면 서버에 '정보'를 달라고 '요청'한다.
대기중이던 서버는 '요청'을 처리 후 클라리언트로 '정보'를 돌려준다.
&amp;gt; 요청(request)와 정보(response)에는 header와 body가 있다.
    * header - request, response에 대한 정보(종류, 크기, 캐시) 등
    * body - 주고 받고자 하는 메인 정보
*/
const server = http.createServer((req, res) =&amp;gt; { // 서버 만드는 메소드
  // url모듈을 이용해서 url에 따라 다른 HTML을 전송하는 라우팅을 구현
  const path = url.parse(req.url, true).pathname; 
  if (req.method === 'GET') { // GET 요청이면 
    if (path.includes('.js')) {
      res.writeHead (200, 'Content-Type', 'text/javascript');
      // readFile 메소드로 HTML 파일을 읽어서 읽은 데이터를 브라우저로 보낸다.
      fs.readFile(__dirname + path, (err, data) =&amp;gt; {
        if (err) {
          return console.error(err);
        }
        res.end(data);
      });
    } else if (path === '/') {
      res.writeHead (200, 'Content-Type', 'text/html');
      // __dirname - 현재 프로젝트의 경로
      fs.readFile(__dirname + '/index.html', (err, data) =&amp;gt; {
        if (err) {
          return console.error(err);
        }
        res.end(data, 'utf-8');
      });
    } else {
      res.writeHead(404, 'Content-Type', 'text/plain; charset=UTF-8');
      res.end('주소가 없습니다', 'utf-8');
    }
  }
}).listen(port);

console.log(`Server running at http://${hostname}:${port}/`);&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5-2. 커맨드 지정/서버 실행&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  package.json&lt;/h4&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;scripts&quot;: {
    &quot;dev&quot;: &quot;node app.js&quot;,                 // NEW
    &quot;build&quot;: &quot;babel lib -w -d dist/js&quot; 
    &quot;test&quot;: &quot;jest&quot;
  },
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엇..! 그런데 &lt;code&gt;Uncaught ReferenceError: require is not defined&lt;/code&gt; 에러가 떴다.&lt;br /&gt;요고 아까 바벨로 트랜스파일링한 파일에서도 봤엇는데.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  &lt;code&gt;require&lt;/code&gt; ?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node.js의 모듈시스템인 CommonJs에서 모듈을 불러오는 키워드라고 한다.&lt;br /&gt;CommonJs는 웹에서 쓰려면 번들러를 사용해야 한단다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. Webpack 사용하기&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹팩이란 최신 프런트엔드 프레임워크에서 가장 많이 사용되는 모듈 번들러(Module Bundler)입니다. 모듈 번들러란 웹 애플리케이션을 구성하는 자원(HTML, CSS, Javscript, Images 등)을 모두 각각의 모듈로 보고 이를 조합해서 병합된 하나의 결과물을 만드는 도구를 의미합니다. 그럼 모듈과 모듈 번들링에 대해서 조금 더 살펴보겠습니다.&lt;br /&gt;...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹팩의 등장 배경에서도 살펴봤지만 웹팩에서 해결하고자 하는 기존의 문제점은 다음 4가지 입니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자바스크립트 변수 유효 범위&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;브라우저별 HTTP 요청 숫자의 제약&lt;/li&gt;
&lt;li&gt;사용하지 않는 코드의 관리&lt;/li&gt;
&lt;li&gt;Dynamic Loading &amp;amp; Lazy Loading 미지원 - &lt;a href=&quot;https://joshua1988.github.io/webpack-guide/webpack/what-is-webpack.html#%EC%9B%B9%ED%8C%A9%EC%9D%B4%EB%9E%80&quot;&gt;joshua1988 - 웹팩 핸드북&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;a href=&quot;https://webpack.kr/configuration&quot;&gt;webpack 공식 문서&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://joshua1988.github.io/webpack-guide/getting-started.html#%EC%8B%A4%EC%8A%B5-%EC%A0%88%EC%B0%A8-%EC%9B%B9-%ED%8E%98%EC%9D%B4%EC%A7%80-%EC%9E%90%EC%9B%90-%EA%B5%AC%EC%84%B1&quot;&gt;joshua1988 - 웹팩 핸드북&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://poiemaweb.com/es6-babel-webpack-2&quot;&gt;poiemaweb&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-1. Webpack 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Webpack V4는 webpack-cli 설치가 필요하다.&lt;/p&gt;
&lt;pre class=&quot;avrasm&quot;&gt;&lt;code&gt;$ yarn add --D webpack webpack-cli&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Webpack이 모듈을 번들링할 때 Babel을 사용하여 ES6+ 코드를 ES5 코드로 트랜스파일링하도록 babel-loader를 설치한다.&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;$ yarn add --D babel-loader&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패키지가 아래와 같이 설치되었다.&lt;br /&gt;&lt;code&gt;scripts&lt;/code&gt; 의 &lt;code&gt;build&lt;/code&gt;를 babel에서 webpack으로 수정한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  package.json&lt;/h4&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;scripts&quot;: {
    &quot;dev&quot;: &quot;node app.js&quot;,
    &quot;build&quot;: &quot;webpack -w&quot;,        //NEW
    &quot;test&quot;: &quot;jest&quot;
  },
  &quot;devDependencies&quot;: {
    &quot;@babel/cli&quot;: &quot;^7.17.3&quot;,
    &quot;@babel/core&quot;: &quot;^7.17.5&quot;,
    &quot;@babel/preset-env&quot;: &quot;^7.16.11&quot;,
    &quot;babel-loader&quot;: &quot;^8.2.3&quot;,
    &quot;jest&quot;: &quot;^27.5.1&quot;,
    &quot;webpack&quot;: &quot;^5.69.1&quot;,        //NEW
    &quot;webpack-cli&quot;: &quot;^4.9.2&quot;        //NEW
  },
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-2. Webpack 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js 파일을 생성한다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;$ touch webpack.config.js&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack 설정은 내용이 많아 단계별로 정리하려고 한다.&lt;br /&gt;먼저 &lt;code&gt;entry&lt;/code&gt;와 &lt;code&gt;output&lt;/code&gt;이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  entry &amp;amp; output&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;entry&lt;/code&gt;: 해당 파일 대상으로 웹팩이 빌드를 수행&lt;/li&gt;
&lt;li&gt;&lt;code&gt;output&lt;/code&gt;: 빌드된 파일에 대한 옵션
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;path&lt;/code&gt;: 빌드된 파일이 저장될 경로. dist 폴더가 범용적으로 쓰임
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;path.resolve()&lt;/code&gt;: 인자로 넘어온 경로들을 조합하여 유효한 파일 경로를 만들어주는 Node.js API&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;filename&lt;/code&gt;: 빌드된 파일명 옵션
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;[name].bundle.js&lt;/code&gt;: 결과 파일 이름에 entry 속성을 포함하는 옵션
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;[id].bundle.js&lt;/code&gt; : 결과 파일 이름에 웹팩 내부적으로 사용하는 모듈 ID를 포함하는 옵션&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[name].[hash].bundle.js&lt;/code&gt; : 매 빌드시 마다 고유 해시 값을 붙이는 옵션&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[chunkhash].bundle.js&lt;/code&gt; : 웹팩의 각 모듈 내용을 기준으로 생생된 해시 값을 붙이는 옵션  webpack.config.js&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-javascript&quot;&gt;const path = require('path');
&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;module.exports = {&lt;br /&gt;entry: './index.js',&lt;br /&gt;output: {&lt;br /&gt;path: path.resolve(__dirname, 'dist/js'),&lt;br /&gt;filename: 'bundle.js'&lt;br /&gt;},&lt;br /&gt;}&lt;/p&gt;
&lt;pre class=&quot;clean&quot;&gt;&lt;code&gt;
####   module &amp;amp; module.rules
- &amp;lt;code&amp;gt;module&amp;lt;/code&amp;gt;:로더(Loader)는 웹팩이 웹 애플리케이션을 해석할 때 자바스크립트 파일이 아닌 웹 자원(HTML, CSS, Images, 폰트 등)들을 변환할 수 있도록 도와주는 속성.
엔트리나 아웃풋 속성과는 다르게 module라는 이름을 사용.
- &amp;lt;code&amp;gt;module.rules&amp;lt;/code&amp;gt;
    - &amp;lt;code&amp;gt;test&amp;lt;/code&amp;gt;: 로더를 적용할 파일 유형 (일반적으로 정규 표현식 사용)
    - &amp;lt;code&amp;gt;include&amp;lt;/code&amp;gt;: 해당 로더를 사용해서 컴파일할 파일을 지정
    - &amp;lt;code&amp;gt;exclude&amp;lt;/code&amp;gt;: 컴파일에서 제외할 폴더나 파일
    - &amp;lt;code&amp;gt;use.loader&amp;lt;/code&amp;gt;: 컴파일을 실행할 로더 지정
    - &amp;lt;code&amp;gt;use.options&amp;lt;/code&amp;gt;: 로더에 대한 옵션. 현재는 어떤 프리셋을 사용할지 지정
        - &amp;lt;code&amp;gt;modules&amp;lt;/code&amp;gt;: &amp;lt;code&amp;gt;false&amp;lt;/code&amp;gt;로 해야 최신 묘듈 시스템이 그대로 유지되어 트리쉐이킹(사용하지 않는 코드를 제거하는 방식)이 된다. ES2015 모듈 시스템에서 import되지 않은 export들을 정리해주는 기능. 용량이 많이 줄어들기 때문에 사용하는 것이 좋다. 단, commonJS나 AMD, UMD같은 모듈 시스템을 사용해야하는 클라이언트에서 쓰면 제대로 처리되지 않는다.
####   webpack.config.js
```javascript
const path = require('path');

odule.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.js$/,
        include: [
          path.resolve(__dirname, 'index.js')
        ],
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env', {
              modules: 'false',
            }],
          }
        },
      }
    ],
  },
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  plugins&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;plugins&lt;/code&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;플러그인의 배열에는 생성자 함수로 생성한 객체 인스턴스만 추가될 수 있다.  HtmlWebpackPlugin나는 &lt;code&gt;HtmlWebpackPlugin&lt;/code&gt;을 사용했다.&lt;br /&gt;webpack 번들을 호출하는 HTML 파일을 자동으로 생성해준다.&lt;br /&gt;사용하기 위해서는 package 설치가 필요하다.
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;yarn add -D html-webpack-plugin&lt;/code&gt;&lt;/pre&gt;
그리고 webpack.config.js파일 상단에서 모듈을 가져와 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  webpack.config.js&lt;/h4&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // ...
  plugins: [
    new HtmlWebpackPlugin({
      template: path.join(__dirname, 'index.html'),
    }),
  ],  
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  devServer&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용하기 위해서는 package 설치가 필요하다.&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;yarn add -D webpack-dev-server&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;웹팩 데브 서버에서 output은 파일 생성/수정 없이 메모리에 저장된다.(컴퓨터 자원이 덜 소모됨)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hot&lt;/code&gt; 옵션으로 코드 수정 후 저장하면 브라우저를 자동으로 새로고침해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  webpack.config.js&lt;/h4&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;module.exports = {
  // ...
  devServer: {
    hot: true,
    port: 5500
  },  
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  package.json&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack dev server 사용으로 package.json의 scripts 옵션을 수정했다.&lt;br /&gt;기존에 &lt;code&gt;dev&lt;/code&gt; 값에 지정되어 있던 Node.js 서버 실행 커맨드를 &lt;code&gt;webpack serve&lt;/code&gt;로 바꾸고, &lt;code&gt;build&lt;/code&gt;의 &lt;code&gt;watch&lt;/code&gt;옵션을 제거했다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;&quot;scripts&quot;: {
  &quot;dev&quot;: &quot;webpack serve&quot;,
  &quot;build&quot;: &quot;webpack&quot;,
  &quot;test&quot;: &quot;jest&quot;
},&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  devtool&lt;/h4&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;Source Map?
&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;보통 서버에 배포를 할 때 성능 최적화를 위해 HTML, CSS, JS와 같은 웹 자원들을 압축한다. 이때, 배포 파일에서 디버깅이 어렵다. 그래서 소스맵을 이용해 배포용 파일의 특정 부분이 원본 소스의 어떤 부분인지 확인 가능하게 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  webpack.config.js&lt;/h4&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;module.exports = {
  // ...
  devtool: 'source-map',
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  mode options&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;development&lt;/code&gt;: 개발 모드&lt;/li&gt;
&lt;li&gt;&lt;code&gt;production&lt;/code&gt;: 배포 모드. 모듈 번들링 과정에서 자체적으로 코드 최적화 (default)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;none&lt;/code&gt;: 기본 최적화 옵션 설정 해제&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  webpack.config.js&lt;/h4&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;module.exports = {
  // ...
  mode: 'development'
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;6-3. webpack.config.js&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;  webpack.config.js&lt;/h4&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './index.js', 
  output: {
    path: path.resolve(__dirname, 'dist/js'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/, 
        include: [
          path.resolve(__dirname, 'index.js')
        ],
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
          }
        },
      }
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.join(__dirname, 'index.html'),
    }),
  ],
  devServer: {
    hot: true,
    port: 5500
  },
  devtool: 'source-map',
  mode: 'development'
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Javascript/node.js</category>
      <category>Babel</category>
      <category>jest</category>
      <category>nodes.js</category>
      <category>polyfill</category>
      <category>webpack</category>
      <author>yemsu</author>
      <guid isPermaLink="true">https://dribbles.tistory.com/61</guid>
      <comments>https://dribbles.tistory.com/61#entry61comment</comments>
      <pubDate>Sun, 27 Feb 2022 09:50:33 +0900</pubDate>
    </item>
    <item>
      <title>[Git] 시맨틱 커밋 메시지</title>
      <link>https://dribbles.tistory.com/60</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;feat : 새로운 기능에 대한 커밋&lt;/li&gt;
&lt;li&gt;fix : 버그 수정에 대한 커밋&lt;/li&gt;
&lt;li&gt;build : 빌드 관련 파일 수정에 대한 커밋&lt;/li&gt;
&lt;li&gt;chore : 그 외 자잘한 수정에 대한 커밋&lt;/li&gt;
&lt;li&gt;ci : CI관련 설정 수정에 대한 커밋&lt;/li&gt;
&lt;li&gt;docs : 문서 수정에 대한 커밋&lt;/li&gt;
&lt;li&gt;style : 코드 스타일 혹은 포맷 등에 관한 커밋&lt;/li&gt;
&lt;li&gt;refactor : 코드 리팩토링에 대한 커밋&lt;/li&gt;
&lt;li&gt;test : 테스트 코드 수정에 대한 커밋&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;589&quot; data-origin-height=&quot;533&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceAvt3/btrtuvxRcyF/o968pmbq40EpwKaYNGpV5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceAvt3/btrtuvxRcyF/o968pmbq40EpwKaYNGpV5K/img.png&quot; data-alt=&quot;커밋 예시 / 출처 - https://github.com/angular/angular/commits/master&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceAvt3/btrtuvxRcyF/o968pmbq40EpwKaYNGpV5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceAvt3%2FbtrtuvxRcyF%2Fo968pmbq40EpwKaYNGpV5K%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;589&quot; height=&quot;533&quot; data-origin-width=&quot;589&quot; data-origin-height=&quot;533&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;커밋 예시 / 출처 - https://github.com/angular/angular/commits/master&lt;/figcaption&gt;
&lt;/figure&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;a href=&quot;https://beomseok95.tistory.com/328&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://beomseok95.tistory.com/328&lt;/a&gt;&lt;/p&gt;</description>
      <category>ETC</category>
      <author>yemsu</author>
      <guid isPermaLink="true">https://dribbles.tistory.com/60</guid>
      <comments>https://dribbles.tistory.com/60#entry60comment</comments>
      <pubDate>Wed, 16 Feb 2022 18:32:32 +0900</pubDate>
    </item>
    <item>
      <title>[GITLENS] 브랜치끼리 소스 비교하기</title>
      <link>https://dribbles.tistory.com/58</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #444444;&quot;&gt;블로그가 이관되었습니다!&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #444444;&quot;&gt;&lt;a href=&quot;https://yemsu.github.io/compare-two-git-branches-vscode/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://yemsu.github.io/compare-two-git-branches-vscode/&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1648778149322&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;VScode Git 브랜치끼리 작업 내용 비교하기&quot; data-og-description=&quot;VScode의 Gitlens 확장프로그램을 이용하여 브랜치끼리 작업 내용을 비교합니다.&quot; data-og-host=&quot;yemsu.github.io&quot; data-og-source-url=&quot;https://yemsu.github.io/compare-two-git-branches-vscode/&quot; data-og-url=&quot;https://yemsu.github.io/compare-two-git-branches-vscode&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/clYeAu/hyNTn6hR4o/b1sezNxRhMFxgvSdyrJsC1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/y0vGI/hyNTx8TBaC/wgQ1omc2bnn0J3AXjaf8qk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/iLBbx/hyNRZML119/3PP5v3eZiTlBkBWKuXz9QK/img.jpg?width=780&amp;amp;height=576&amp;amp;face=0_0_780_576&quot;&gt;&lt;a href=&quot;https://yemsu.github.io/compare-two-git-branches-vscode/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yemsu.github.io/compare-two-git-branches-vscode/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/clYeAu/hyNTn6hR4o/b1sezNxRhMFxgvSdyrJsC1/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/y0vGI/hyNTx8TBaC/wgQ1omc2bnn0J3AXjaf8qk/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/iLBbx/hyNRZML119/3PP5v3eZiTlBkBWKuXz9QK/img.jpg?width=780&amp;amp;height=576&amp;amp;face=0_0_780_576');&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;VScode Git 브랜치끼리 작업 내용 비교하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;VScode의 Gitlens 확장프로그램을 이용하여 브랜치끼리 작업 내용을 비교합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yemsu.github.io&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>ETC</category>
      <author>yemsu</author>
      <guid isPermaLink="true">https://dribbles.tistory.com/58</guid>
      <comments>https://dribbles.tistory.com/58#entry58comment</comments>
      <pubDate>Mon, 27 Dec 2021 10:44:38 +0900</pubDate>
    </item>
    <item>
      <title>[Vue] Computed와 Methods</title>
      <link>https://dribbles.tistory.com/55</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Computed&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;인자 값을 받지 않음&lt;/b&gt; (가능하긴 하나 인자 값을 받으면 computed의 특장점인 캐싱 기능이 없어지기 때문에 권장되지 않음)&lt;/li&gt;
&lt;li&gt;주로 기존 데이터를 재조립, 계산해서 template에서 사용하는 용도&lt;/li&gt;
&lt;li&gt;&lt;b&gt;캐시가 저장된다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;computed 속성에서 사용된 데이터와 연결되어 값이 변할때만 재실행된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Methods&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;인자 값을 받을 수 있음&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;주로 이벤트 발생에 따른 기능들, 반복되는 로직들을 묶을 때 사용&lt;/li&gt;
&lt;li&gt;&lt;b&gt;캐시가 저장되지 않는다&lt;/b&gt;.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;methods 속성에서 사용된 데이터와 연결되지 않아, update라이프 사이클이 동작할때마다(특정 변수가 바뀔 때마다) 재실행된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/40522634/can-i-pass-parameters-in-computed-properties-in-vue-js&quot; target=&quot;_blank&quot;&gt;https://stackoverflow.com/questions/40522634/can-i-pass-parameters-in-computed-properties-in-vue-js&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://vuejs.org/v2/guide/computed.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kamang-it.tistory.com/entry/Vue23computed-%EA%B7%B8%EB%A6%AC%EA%B3%A0-methods%EC%99%80%EC%9D%98-%EC%B0%A8%EC%9D%B4featwatch&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kamang-it.tistory.com/entry/Vue23computed-%EA%B7%B8%EB%A6%AC%EA%B3%A0-methods%EC%99%80%EC%9D%98-%EC%B0%A8%EC%9D%B4featwatch&lt;/a&gt;&lt;/p&gt;</description>
      <category>Javascript/Vue</category>
      <author>yemsu</author>
      <guid isPermaLink="true">https://dribbles.tistory.com/55</guid>
      <comments>https://dribbles.tistory.com/55#entry55comment</comments>
      <pubDate>Mon, 15 Nov 2021 17:22:13 +0900</pubDate>
    </item>
    <item>
      <title>[Vue 3] Vue.js devtools - not detected</title>
      <link>https://dribbles.tistory.com/54</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;블로그가 이관되었습니다!&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yemsu.github.io/vue-devtools-not-detected-vue3&quot;&gt;https://yemsu.github.io/vue-devtools-not-detected-vue3&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1648772705500&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;Vue3 Vue.js devtools - not detected&quot; data-og-description=&quot;Vue.js devtools - not detected 이슈 해결&quot; data-og-host=&quot;yemsu.github.io&quot; data-og-source-url=&quot;https://yemsu.github.io/vue-devtools-not-detected-vue3&quot; data-og-url=&quot;https://yemsu.github.io/vue-devtools-not-detected-vue3&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/QRv7R/hyNSbzxI2T/pKKs7LZpwrlwJl4lvHLjZK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bxiLzL/hyNTvJXqUy/Tkjy9erVa4OlkW7tSGjs6k/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://yemsu.github.io/vue-devtools-not-detected-vue3&quot; data-source-url=&quot;https://yemsu.github.io/vue-devtools-not-detected-vue3&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/QRv7R/hyNSbzxI2T/pKKs7LZpwrlwJl4lvHLjZK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bxiLzL/hyNTvJXqUy/Tkjy9erVa4OlkW7tSGjs6k/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;Vue3 Vue.js devtools - not detected&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Vue.js devtools - not detected 이슈 해결&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yemsu.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Javascript/Vue</category>
      <author>yemsu</author>
      <guid isPermaLink="true">https://dribbles.tistory.com/54</guid>
      <comments>https://dribbles.tistory.com/54#entry54comment</comments>
      <pubDate>Fri, 12 Nov 2021 14:21:08 +0900</pubDate>
    </item>
    <item>
      <title>[Vue 3] Router 설정하기</title>
      <link>https://dribbles.tistory.com/51</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;블로그가 이관되었습니다!&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yemsu.github.io/vue3-router&quot;&gt;https://yemsu.github.io/vue3-router&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1648772887863&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;Vue3 Router 사용하기  (+ 동적 라우팅)&quot; data-og-description=&quot;Vue CLI에서 Router를 설치하고 사용합니다. 각 옵션에 대한 내용과 함께 동적 라우팅도 설정합니다.&quot; data-og-host=&quot;yemsu.github.io&quot; data-og-source-url=&quot;https://yemsu.github.io/vue3-router&quot; data-og-url=&quot;https://yemsu.github.io/vue3-router&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/qhfjM/hyNR74ZuFQ/Ws1z9awHL1pqiEsdLPfK51/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/xmzOS/hyNTwhMyoG/UJddW12cRjzAkX9ctFtEBK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://yemsu.github.io/vue3-router&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yemsu.github.io/vue3-router&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/qhfjM/hyNR74ZuFQ/Ws1z9awHL1pqiEsdLPfK51/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/xmzOS/hyNTwhMyoG/UJddW12cRjzAkX9ctFtEBK/img.jpg?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;Vue3 Router 사용하기 (+ 동적 라우팅)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Vue CLI에서 Router를 설치하고 사용합니다. 각 옵션에 대한 내용과 함께 동적 라우팅도 설정합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yemsu.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Javascript/Vue</category>
      <author>yemsu</author>
      <guid isPermaLink="true">https://dribbles.tistory.com/51</guid>
      <comments>https://dribbles.tistory.com/51#entry51comment</comments>
      <pubDate>Mon, 1 Nov 2021 17:57:56 +0900</pubDate>
    </item>
    <item>
      <title>Optional Chaining 연산자</title>
      <link>https://dribbles.tistory.com/49</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대박! 이거 너무 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실험기술이라고 되어있긴 하지만, IE 빼고 다 된다고 되어있따.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1635384646959&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const nestedProp = obj.first ? obj.first.second : undefined;&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;pre id=&quot;code_1635384716504&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const nestedProp = obj.first?.second;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 요로케 Optional Chaining 연산자를 쓰면 된다! 아름다워....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1635384807234&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const nestedProp = obj.first?.second?.third&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;pre id=&quot;code_1635384844352&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const nestedProp = obj.first?.second ?? 'second'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Optional Chaining을 사용한 후에 아무 값을 찾을 수 없을땐, 널 병합 연산자 '??' 를 사용하여 기본값을 지정할 수 있다!&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;참고 url&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Optional_chaining&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Optional_chaining&lt;/a&gt;&lt;/p&gt;</description>
      <category>Javascript</category>
      <author>yemsu</author>
      <guid isPermaLink="true">https://dribbles.tistory.com/49</guid>
      <comments>https://dribbles.tistory.com/49#entry49comment</comments>
      <pubDate>Thu, 28 Oct 2021 10:37:24 +0900</pubDate>
    </item>
    <item>
      <title>node-sass\vendor 에러</title>
      <link>https://dribbles.tistory.com/48</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;잘되던 소스 빌드가 갑자기 되지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확인해보니 node환경 개선으로 다른 개발자분이 package.json을 수정하셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm update를 해도 잘 되지 않아서 node modules를 제거하고 다시 install한 뒤 소스를 빌드하였는데 아래와 같은 에러가 났다.&lt;/p&gt;
&lt;pre id=&quot;code_1630296498667&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;no such file or directory, scandir '~\node_modules\node-sass\vendor&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;아래 명령어로 node-sass를 rebuild해주니 해결되었다.&lt;/p&gt;
&lt;pre id=&quot;code_1630297029753&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;npm rebuild node-sass&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/45251645/error-enoent-no-such-file-or-directory-scandir&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/45251645/error-enoent-no-such-file-or-directory-scandir&lt;/a&gt;&lt;/p&gt;</description>
      <category>Javascript/node.js</category>
      <author>yemsu</author>
      <guid isPermaLink="true">https://dribbles.tistory.com/48</guid>
      <comments>https://dribbles.tistory.com/48#entry48comment</comments>
      <pubDate>Mon, 30 Aug 2021 13:17:46 +0900</pubDate>
    </item>
    <item>
      <title>[Vue.js] axios__WEBPACK_IMPORTED_MODULE_2___default.a.get(...).then(...).error is not a function</title>
      <link>https://dribbles.tistory.com/47</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;api호출은 정상적으로 잘 되는데 자꾸 빨간 콘솔에러가 떠있어서 너무 거슬렸다.&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;span style=&quot;color: #ee2323;&quot;&gt;axios__WEBPACK_IMPORTED_MODULE_2___default.a.get(...).then(...).error&amp;nbsp;is&amp;nbsp;not&amp;nbsp;a&amp;nbsp;function&lt;/span&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;.error로 써놨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.catch로 바꿔주니까 콘솔창 깔꿈!&lt;/p&gt;
&lt;pre id=&quot;code_1624845635824&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;      fetchList(type)
        .then(response =&amp;gt; commit(`SET_LIST`, {data: response.data, type}))
        .error(error =&amp;gt; console.log(error)) //.error를 .catch로 바꿔야함&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Javascript/Vue</category>
      <category>API</category>
      <category>axios</category>
      <category>fetch</category>
      <category>VUE</category>
      <author>yemsu</author>
      <guid isPermaLink="true">https://dribbles.tistory.com/47</guid>
      <comments>https://dribbles.tistory.com/47#entry47comment</comments>
      <pubDate>Mon, 28 Jun 2021 11:03:46 +0900</pubDate>
    </item>
    <item>
      <title>[Vue.js] router - url에 삽입되는 해시(#) 제거하기</title>
      <link>https://dribbles.tistory.com/46</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;mode: 'history'&lt;/b&gt; 를 아래 예시와 같이 라우터 설정에 넣어 준다.&lt;/p&gt;
&lt;pre id=&quot;code_1624509712048&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export const router = new VueRouter({
  mode: 'history', // #값 제거 설정
  routes: [
    {
      path: '/news',
      component: NewsView,
    }
  ]
})&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Javascript/Vue</category>
      <category>Router</category>
      <category>VUE</category>
      <category>vueRouter</category>
      <author>yemsu</author>
      <guid isPermaLink="true">https://dribbles.tistory.com/46</guid>
      <comments>https://dribbles.tistory.com/46#entry46comment</comments>
      <pubDate>Thu, 24 Jun 2021 13:43:44 +0900</pubDate>
    </item>
  </channel>
</rss>