<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>devlog</title>
    <link>https://mugon-devlog.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 28 Jul 2026 19:22:00 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>MG_conny</managingEditor>
    <image>
      <title>devlog</title>
      <url>https://tistory1.daumcdn.net/tistory/4635723/attach/08b6cfc64946445694dda7b6d7f61f4a</url>
      <link>https://mugon-devlog.tistory.com</link>
    </image>
    <item>
      <title>nextjs api error, axios error handling</title>
      <link>https://mugon-devlog.tistory.com/112</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;api.jpg&quot; data-origin-width=&quot;13362&quot; data-origin-height=&quot;4836&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmp6me/btrHi3t6Hqx/ihZrKBeGn4fSGezGiwOg30/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmp6me/btrHi3t6Hqx/ihZrKBeGn4fSGezGiwOg30/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmp6me/btrHi3t6Hqx/ihZrKBeGn4fSGezGiwOg30/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdmp6me%2FbtrHi3t6Hqx%2FihZrKBeGn4fSGezGiwOg30%2Fimg.jpg&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;13362&quot; height=&quot;4836&quot; data-filename=&quot;api.jpg&quot; data-origin-width=&quot;13362&quot; data-origin-height=&quot;4836&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Process&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. user api request&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. enter middleware&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. need auth ( x =&amp;gt; logger middleware )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. session middleware ( iron-session )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. auth middleware ( get access token or refresh token or response UnAuthorization)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. logger middleware ( who , what log api request )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. server axios response ( if error return error response from next api server to client )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. client get response ( if error catch throw error to error boundary )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9. error boundary catch error&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Structure/diagram</category>
      <category>diagram</category>
      <category>Error Handling</category>
      <author>MG_conny</author>
      <guid isPermaLink="true">https://mugon-devlog.tistory.com/112</guid>
      <comments>https://mugon-devlog.tistory.com/112#entry112comment</comments>
      <pubDate>Thu, 14 Jul 2022 17:11:53 +0900</pubDate>
    </item>
    <item>
      <title>카카오 rest api login, 서버 jwt, refresh token 프로세스</title>
      <link>https://mugon-devlog.tistory.com/111</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;login2.jpg&quot; data-origin-width=&quot;9834&quot; data-origin-height=&quot;3803&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfMljP/btrHhcMpH8N/3cH9o7lKnb85cj4pc7bJ71/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfMljP/btrHhcMpH8N/3cH9o7lKnb85cj4pc7bJ71/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfMljP/btrHhcMpH8N/3cH9o7lKnb85cj4pc7bJ71/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfMljP%2FbtrHhcMpH8N%2F3cH9o7lKnb85cj4pc7bJ71%2Fimg.jpg&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;9834&quot; height=&quot;3803&quot; data-filename=&quot;login2.jpg&quot; data-origin-width=&quot;9834&quot; data-origin-height=&quot;3803&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Process basic&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. web open&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. cookie 내 server refresh token 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. refresh token으로 서버용 access token 발급&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. server refresh api 호출시 kakao 토큰 갱신, 서버 토큰 갱신&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 갱신된 토큰 받아 cookie 저장&lt;/p&gt;</description>
      <category>Structure/diagram</category>
      <category>JWT</category>
      <category>kakako</category>
      <category>restAPI</category>
      <category>server</category>
      <author>MG_conny</author>
      <guid isPermaLink="true">https://mugon-devlog.tistory.com/111</guid>
      <comments>https://mugon-devlog.tistory.com/111#entry111comment</comments>
      <pubDate>Thu, 14 Jul 2022 17:05:09 +0900</pubDate>
    </item>
    <item>
      <title>webpack@4 - 개발서버,API,HMR,최적화</title>
      <link>https://mugon-devlog.tistory.com/110</link>
      <description>&lt;h1&gt;webpack - 개발서버,API,HMR,최적화&lt;/h1&gt;
&lt;h1&gt;웹팩 개발 서버&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;배경&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영환경과 맞춤으로써 배포시 잠재적 문제를 미리 확인할 수 있다. 게다가 ajax 방식의 api 연동은 cors 정책 때문에 반드시 서버가 필요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트엔드 개발환경에서 이러한 개발용 서버를 제공해 주는 것이&amp;nbsp;&lt;a href=&quot;https://webpack.js.org/configuration/dev-server/&quot;&gt;webpack-dev-server&lt;/a&gt;다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설치 및 사용&lt;/h2&gt;
&lt;pre class=&quot;axapta&quot;&gt;&lt;code&gt;npm i -D webpack-dev-server
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;package.json&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;scripts&quot;: {
    &quot;start&quot;: &quot;webpack-dev-server&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹팩 서버는 파일 변화를 감지하면 웹팩 빌드를 다시 수행하고 브라우져를 리프레시하여 변경된 결과물을 보여준다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기본 설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;module.exports = {
  devServer: {
    contentBase: path.join(__dirname, &quot;dist&quot;),
    publicPath: &quot;/&quot;,
    host: &quot;dev.domain.com&quot;,
    overlay: true,
    port: 8081,
    stats: &quot;errors-only&quot;,
    historyApiFallback: true,
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;contentBase&lt;/b&gt;: 정적파일을 제공할 경로. 기본값은 웹팩 아웃풋이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;publicPath&lt;/b&gt;: 브라우져를 통해 접근하는 경로. 기본값은 '/' 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;host&lt;/b&gt;: 개발환경에서 도메인을 맞추어야 하는 상황에서 사용한다. 예를들어 쿠기 기반의 인증은 인증 서버와 동일한 도메인으로 개발환경을 맞추어야 한다. 운영체제의 호스트 파일에 해당 도메인과 127.0.0.1 연결한 추가한 뒤 host 속성에 도메인을 설정해서 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;overlay&lt;/b&gt;: 빌드시 에러나 경고를 브라우져 화면에 표시한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;port&lt;/b&gt;: 개발 서버 포트 번호를 설정한다. 기본값은 8080.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;stats&lt;/b&gt;: 메시지 수준을 정할수 있다. 'none', 'errors-only', 'minimal', 'normal', 'verbose' 로 메세지 수준을 조절한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;historyApiFallBack&lt;/b&gt;: 히스토리 API를 사용하는 SPA 개발시 설정한다. 404가 발생하면 index.html로 리다이렉트한다.&lt;/p&gt;
&lt;h1&gt;API 연동&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;목업 API 1 : devServer.before&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;module.exports = {
  devServer: {
    before: (app, server, compiler) =&amp;gt; {
      app.get(&quot;/api/keywords&quot;, (req, res) =&amp;gt; {
        res.json([
          { keyword: &quot;이탈리아&quot; },
          { keyword: &quot;세프의요리&quot; },
          { keyword: &quot;제철&quot; },
          { keyword: &quot;홈파티&quot; },
        ])
      })
    },
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;before에 설정한 미들웨어는 익스프레스에 의해서 app 객체가 인자로 전달되는데 Express 인스턴스다. 이 객체에 라우트 컨트롤러를 추가할 수 있는데 app.get(url, controller) 형태로 함수를 작성한다. 컨트롤러에서는 요청 req과 응답 res 객체를 받는데 여기서는 res.json() 함수로 응답하는 코드를 만들었다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;목업 API 2 : connect-api-mocker&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/muratcorlu/connect-api-mocker&quot;&gt;connect-api-mocker&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 목업 폴더를 만들어 api 응답을 담은 파일을 저장한 뒤, 이 폴더를 api로 제공해 주는 기능을 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mocks / api / users / GET.json&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[
  { &quot;keyword&quot;: &quot;이탈리아&quot; },
  { &quot;keyword&quot;: &quot;세프의요리&quot; },
  { &quot;keyword&quot;: &quot;제철&quot; },
  { &quot;keyword&quot;: &quot;홈파티 &quot; }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const apiMocker = require(&quot;connect-api-mocker&quot;)

module.exports = {
  devServer: {
    before: (app, server, compiler) =&amp;gt; {
      app.use(apiMocker(&quot;/api&quot;, &quot;mocks/api&quot;)) // root url , mocks 파일 위치
    },
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;proxy setting&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;module.exports = {
  devServer: {
    proxy: {
      &quot;/api&quot;: &quot;&amp;lt;http://localhost:8081&amp;gt;&quot;, // 프록시
    },
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;&lt;b&gt;핫 모듈 리플레이스먼트&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체화면을 갱신하지 않고 변경한 모듈만 바꿔치기하는 웹팩 개발서버의 한 기능&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;module.exports = {
  devServer = {
    hot: true,
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app.js&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;view.js파일의 변경이 감지되면 그 부분만 모듈이 변경되어 랜더링됨&lt;/p&gt;
&lt;pre class=&quot;openscad&quot;&gt;&lt;code&gt;// module.hot 실행
if (module.hot) {
	// 변경 감지
  module.hot.accept(&quot;./view&quot;, async () =&amp;gt; {
		// 리랜더링
    view.render(await model.get(), controller.el) // 변경된 모듈로 교체
  })
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;핫로딩을 지원하는 로더&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 핫 모듈 리플레이스먼트(HMR)인터페이스를 구현한 로더만이 핫 로딩을 지원함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://webpack.js.org/guides/hot-module-replacement/#other-code-and-frameworks&quot;&gt;지원하는 모듈&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;최적화&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드가 많아지면 번들링된 결과물도 커지기 마련 &amp;rarr; 성능에 영향&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;production 모드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹팩에 내장되어 있는 최적화 방법중&amp;nbsp;&lt;a href=&quot;https://webpack.js.org/configuration/mode/&quot;&gt;mode&lt;/a&gt;&amp;nbsp;값을 설정하는 방식이 가장 기본이다. 세 가지 값이 올 수 있는데 지금까지 설정한 &quot;development&quot;는 디버깅 편의를 위해 아래 두 개 플러그인을 사용한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;NamedChunksPlugin&lt;/li&gt;
&lt;li&gt;NamedModulesPlugin&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DefinePlugin을 사용한다면 process.env.NODE_ENV 값이 &quot;development&quot;로 설정되어 어플리케이션에 전역변수로 주입된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 mode를 &quot;production&quot;으로 설정하면 자바스크립트 결과물을 최소화 하기 위해 다음 일곱 개 플러그인을 사용한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;FlagDependencyUsagePlugin&lt;/li&gt;
&lt;li&gt;FlagIncludedChunksPlugin&lt;/li&gt;
&lt;li&gt;ModuleConcatenationPlugin&lt;/li&gt;
&lt;li&gt;NoEmitOnErrorsPlugin&lt;/li&gt;
&lt;li&gt;OccurrenceOrderPlugin&lt;/li&gt;
&lt;li&gt;SideEffectsFlagPlugin&lt;/li&gt;
&lt;li&gt;TerserPlugin&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DefinePlugin을 사용한다면 process.env.NODE_ENV 값이 &quot;production&quot; 으로 설정되어 어플리케이션 전역변수로 들어간다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;환경변수 NODE_ENV 값에 따라 모드를 설정&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;const mode = process.env.NODE_ENV || &quot;development&quot; // 기본값을 development로 설정

module.exports = {
  mode,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 시에 production 모드로 설정하여 실행하도록 npm script 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;package.json&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;scripts&quot;: {
    &quot;start&quot;: &quot;webpack-dev-server --progress&quot;,
    &quot;build&quot;: &quot;NODE_ENV=production webpack --progress&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;optimazation 속성으로 최적화&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 과정을 커스터마지징할 수 있는 속성 &amp;rArr; &amp;nbsp;&lt;a href=&quot;https://webpack.js.org/configuration/optimization/&quot;&gt;optimazation&lt;/a&gt; 속성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HtmlWebpackPlugin이 html 파일을 압축한것 처럼 css 파일도 빈칸을 없애는 압축 &amp;rArr; &lt;a href=&quot;https://webpack.js.org/plugins/mini-css-extract-plugin/#minimizing-for-production&quot;&gt;assets-webpack-plugin&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;npm i -D optimize-css-assets-webpack-plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;const OptimizeCSSAssetsPlugin = require(&quot;optimize-css-assets-webpack-plugin&quot;)

module.exports = {
  optimization: {
    minimizer: mode === &quot;production&quot; ? [new OptimizeCSSAssetsPlugin()] : [],
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://webpack.js.org/configuration/optimization/#optimizationminimizer&quot;&gt;optimization.minimizer&lt;/a&gt; 는 웹팩이 결과물을 압축할때 사용할 플러그인을 넣는 배열&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://webpack.js.org/plugins/terser-webpack-plugin/&quot;&gt;TerserWebpackPlugin&lt;/a&gt;은 자바스크립트 코드를 난독화하고 debugger 구문을 제거한다. 기본 설정 외에도&amp;nbsp;&lt;a href=&quot;https://github.com/terser/terser#compress-options&quot;&gt;콘솔 로그를 제거하는 옵션&lt;/a&gt;도 있다&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;npm i -D terser-webpack-plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;const TerserPlugin = require(&quot;terser-webpack-plugin&quot;)
module.exports = {
  optimization: {
    minimizer:
      mode === &quot;production&quot;
        ? [
            new TerserPlugin({
              terserOptions: {
                compress: {
                  drop_console: true, // 콘솔 로그를 제거한다
                },
              },
            }),
          ]
        : [],
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;코드 스플리팅&lt;/h2&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;빌드하면 엔트리별로 js 파일이 생성됨 그러나 중복코드가 존재함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://webpack.js.org/guides/code-splitting/#prevent-duplication&quot;&gt;SplitChunksPlugin&lt;/a&gt; 이 플러그인을 사용해 중복 코드 제거 &amp;rArr; 중복되어 사용되는 코드는 vendor.js 파일에 저장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;module.exports = {
	entry: {
    main: &quot;./src/app.js&quot;,
    controller: &quot;./src/controller.js&quot;,
  },
  optimization: {
    splitChunks: {
      chunks: &quot;all&quot;, // 중복 코드 제거
    },
  },
}
&lt;/code&gt;&lt;/pre&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;p data-ke-size=&quot;size16&quot;&gt;app.js&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;import controller from &quot;./controller&quot;

document.addEventListener(&quot;DOMContentLoaded&quot;, () =&amp;gt; {
  controller.init(document.querySelector(&quot;#app&quot;))
})
// ----- dynamic import로 변경 ----
function getController() {
  return import(/* webpackChunkName: &quot;controller&quot; */ &quot;./controller&quot;).then(m =&amp;gt; {
    return m.default
  })
}

document.addEventListener(&quot;DOMContentLoaded&quot;, () =&amp;gt; {
  getController().then(controller =&amp;gt; {
    controller.init(document.querySelector(&quot;#app&quot;))
  })
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;import() 함수로 가져올 컨트롤러 모듈 경로를 전달하는데 주석으로 webpackHunkName: &quot;controller&quot;를 전달했다. 이것은 웹펙이 이 파일을 처리할때 청크로 분리하는데 그 청그 이름을 설정한 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 webpack.config.js의 entry를 하나로 유지하면서 중복코드도 제거하며 코드를 분리할 수 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;externals&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;axios 같은 써드파티 라이브러리는 패키지로 제공될때 이미 빌드 과정을 거쳤기 때문에 빌드 프로세스에서 제외하는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;module.exports = {
  externals: {
    axios: &quot;axios&quot;,
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;externals에 추가하면 웹팩은 코드에서 axios를 사용하더라도 번들에 포함하지 않고 빌드한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;axios는 이미 node_modules에 위치해 있기 때문에 이를 웹팩 아웃풋 폴더에 옮기고 index.html에서 로딩해야한다. 파일을 복사하는&amp;nbsp;&lt;a href=&quot;https://webpack.js.org/plugins/copy-webpack-plugin/&quot;&gt;CopyWebpackPlugin&lt;/a&gt;을 설치한다.&lt;/p&gt;
&lt;pre class=&quot;dockerfile&quot;&gt;&lt;code&gt;npm i -D copy-webpack-plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;const CopyPlugin = require(&quot;copy-webpack-plugin&quot;)

module.exports = {
  plugins: [
    new CopyPlugin([
      {
        from: &quot;./node_modules/axios/dist/axios.min.js&quot;,
        to: &quot;./axios.min.js&quot;, // 목적지 파일에 들어간다
      },
    ]),
  ],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 index.html에서 axios를 로딩하는 코드를 추가한다.&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://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1654365375927&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&quot; data-og-description=&quot;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bL6Lsp/hyOEgMACft/i24pyfRbFN6PFpk0HNz7P0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/fH0Jd/hyOEar7BVe/V742bxlOUxqKbegGyJopo0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/SrTHo/hyOEaMn8qz/BdbRj7Zsp0GcOS181CkMpk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bL6Lsp/hyOEgMACft/i24pyfRbFN6PFpk0HNz7P0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/fH0Jd/hyOEar7BVe/V742bxlOUxqKbegGyJopo0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/SrTHo/hyOEaMn8qz/BdbRj7Zsp0GcOS181CkMpk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500');&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;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/webpack</category>
      <category>hmr</category>
      <category>MOCK_API</category>
      <category>Optimization</category>
      <category>Webpack</category>
      <author>MG_conny</author>
      <guid isPermaLink="true">https://mugon-devlog.tistory.com/110</guid>
      <comments>https://mugon-devlog.tistory.com/110#entry110comment</comments>
      <pubDate>Sun, 5 Jun 2022 02:55:58 +0900</pubDate>
    </item>
    <item>
      <title>webpack@4 - lint,prettier</title>
      <link>https://mugon-devlog.tistory.com/109</link>
      <description>&lt;h1&gt;webpack - lint,prettier&lt;/h1&gt;
&lt;h1&gt;배경&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드의 오류나 버그, 스타일 따위를 점검하는 것을&amp;nbsp;&lt;a href=&quot;https://en.wikipedia.org/wiki/Lint_(software)&quot;&gt;린트(Lint) 혹은 린터(Linter)&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;EsLint&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;개념&lt;/h2&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;포맷팅
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일관된 코드 스타일&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;코드 품질
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어플리케이션의 잠재적인 오류나 버그 예방&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설치 및 사용법&lt;/h2&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;npm i -D eslint
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Rules&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서의&amp;nbsp;&lt;a href=&quot;https://eslint.org/docs/rules/&quot;&gt;Rules&lt;/a&gt;&amp;nbsp;메뉴에서 규칙 목록을 확인&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;규칙에 설정하는 값은 세 가지다. &quot;off&quot;나 0은 끔, &quot;warn&quot;이나 1은 경고, &quot;error&quot;나 2는 오류.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정한 규칙에 어긋나는 코드를 발견하면 오류를 출력&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.eslintrc.js&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;module.exports = {
  rules: {
    &quot;no-unexpected-multiline&quot;: &quot;error&quot;,
    &quot;no-extra-semi&quot;: &quot;error&quot;,
  },
};
&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;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.eslintrc.js&lt;/p&gt;
&lt;pre class=&quot;ceylon&quot;&gt;&lt;code&gt;module.exports = {
  extends: [
    &quot;eslint:recommended&quot;, // 미리 설정된 규칙 세트을 사용한다
  ],
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;초기화&lt;/h2&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;npx eslint --init
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Prettier&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;설치 및 사용법&lt;/h2&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;npm i -D prettier
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;prettier 검사&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;mdash;write 옵션은 파일을 재작성&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;npx prettier app.js --write
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;통합방법&lt;/h1&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;npm i -D eslint-config-prettier
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.eslintrc.js&lt;/p&gt;
&lt;pre class=&quot;ceylon&quot;&gt;&lt;code&gt;module.exports = {
  extends: [
    &quot;eslint:recommended&quot;, // 미리 설정된 규칙 세트을 사용한다
    &quot;eslint-config-prettier&quot;, // prettier와 충돌하는 옵션 끄기
  ],
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/prettier/eslint-plugin-prettier&quot;&gt;eslint-plugin-prettier&lt;/a&gt;는 프리티어 규칙을 ESLint 규칙으로 추가하는 플러그인이다. 프리티어의 모든 규칙이 ESLint로 들어오기 때문에 ESLint만 실행&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;npm i -D eslint-plugin-prettier
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.eslintrc.js&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;module.exports = {
  extends: [
    &quot;eslint:recommended&quot;, // 미리 설정된 규칙 세트을 사용한다
    &quot;eslint-config-prettier&quot;,
  ],
  plugins: [&quot;prettier&quot;], // 플러그인 추가
  rules: {
    &quot;prettier/prettier&quot;: &quot;error&quot;,
  },
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.eslintrc.js&lt;/p&gt;
&lt;pre class=&quot;ceylon&quot;&gt;&lt;code&gt;module.exports = {
  extends: [
    &quot;eslint:recommended&quot;, // 미리 설정된 규칙 세트을 사용한다
    &quot;plugin:prettier/recommended&quot;, // prettier 단순 설정
  ],
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;자동화&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;husky&lt;/h2&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://github.com/typicode/husky&quot;&gt;husky&lt;/a&gt;는 깃 훅을 쉽게 사용할 수 있는 도구이다.&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;npm i -D husky
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;package.json&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;husky&quot;: {
    &quot;hooks&quot;: {
      &quot;pre-commit&quot;: &quot;eslint app.js --fix&quot;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;스테이징된 파일만 린트 수행&lt;/h3&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;npm i -D lint-staged
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;package.json&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;{
  &quot;husky&quot;: {
    &quot;hooks&quot;: {
      &quot;pre-commit&quot;: &quot;lint-staged&quot;
    }
  },
  &quot;lint-staged&quot;: {
    &quot;*.js&quot;: &quot;eslint --fix&quot;
  }
}&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;&lt;a href=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1654338998908&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&quot; data-og-description=&quot;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bL6Lsp/hyOEgMACft/i24pyfRbFN6PFpk0HNz7P0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/fH0Jd/hyOEar7BVe/V742bxlOUxqKbegGyJopo0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/SrTHo/hyOEaMn8qz/BdbRj7Zsp0GcOS181CkMpk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bL6Lsp/hyOEgMACft/i24pyfRbFN6PFpk0HNz7P0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/fH0Jd/hyOEar7BVe/V742bxlOUxqKbegGyJopo0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/SrTHo/hyOEaMn8qz/BdbRj7Zsp0GcOS181CkMpk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500');&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;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/webpack</category>
      <category>ESLint</category>
      <category>Husky</category>
      <category>Prettier</category>
      <category>Webpack</category>
      <author>MG_conny</author>
      <guid isPermaLink="true">https://mugon-devlog.tistory.com/109</guid>
      <comments>https://mugon-devlog.tistory.com/109#entry109comment</comments>
      <pubDate>Sat, 4 Jun 2022 19:36:18 +0900</pubDate>
    </item>
    <item>
      <title>webpack@4 - babel - basic</title>
      <link>https://mugon-devlog.tistory.com/108</link>
      <description>&lt;h1&gt;babel - basic&lt;/h1&gt;
&lt;h1&gt;배경&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;크로스 브라우징&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저 마다 사용하는 언어가 달라 프론트엔트 코드는 일관적이지 못할 때가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바벨은 ECMAScript2015+로 작성한 코드를 모든 브라우저에서 동작하도록 호환성을 지켜준다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;트랜스 파일과 빌드&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변환 전후의 추상화 수준이 다른 빌드와는 달리 트랜스파일은 추상화 수준을 유지한 상태로 코드를 변환한다. 타입스크립트 &amp;rarr; 자바스크립트, JSX &amp;rarr; 자바스크립트처럼 트랜스파일 후에도 여전히 코드를 읽을 수 있다.&lt;/p&gt;
&lt;h1&gt;바벨의 기본 동작&lt;/h1&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;npm install -D @babel/core  @babel/cli
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바벨은 세 단계로 빌드를 진행한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파싱(Parsing)
&lt;ol 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;/ol&gt;
&lt;/li&gt;
&lt;li&gt;변환(Transforming)
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;바벨의 플러그인이 담당&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;출력 (Printing)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;플러그인&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;커스텀 플러그인&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://babeljs.io/docs/en/plugins#plugin-development&quot;&gt;바벨 홈페이지 예제&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;xquery&quot;&gt;&lt;code&gt;// my-babel-plugin.js:
module.exports = function myBabelPlugin() {
  return {
    visitor: {
      Identifier(path) {
        const name = path.node.name

        // 바벨이 만든 AST 노드를 출력한다
        console.log(&quot;Identifier() name:&quot;, name)

        // 변환작업: 코드 문자열을 역순으로 변환한다
        path.node.name = name.split(&quot;&quot;).reverse().join(&quot;&quot;)
      },
    },
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사용법&lt;/h3&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;npx babel --help

  --plugins [list]                            A comma-separated list of plugin names.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;99&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Gm8Fh/btrDV5iqqpT/8BQGVmnURHe7PkGS2WnhOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Gm8Fh/btrDV5iqqpT/8BQGVmnURHe7PkGS2WnhOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Gm8Fh/btrDV5iqqpT/8BQGVmnURHe7PkGS2WnhOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGm8Fh%2FbtrDV5iqqpT%2F8BQGVmnURHe7PkGS2WnhOK%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;380&quot; height=&quot;99&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;99&quot;/&gt;&lt;/span&gt;&lt;/figure&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;const 코드를 var로 변경하는 플러그인&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;module.exports = function myBabelPlugin() {
  return {
    visitor: {
      VariableDeclaration(path) {
        console.log(&quot;VariableDeclaration() kind:&quot;, path.node.kind); // const

        if (path.node.kind === &quot;const&quot;) {
          path.node.kind = &quot;var&quot;;
        }
      },
    },
  };
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;livescript&quot;&gt;&lt;code&gt;$ npx babel app.js --plugins './my-babel-plugin.js'
// VariableDeclaration() kind: const
// var alert = msg =&amp;gt; window.alert(msg);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실제 플러그인 사용하기&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;b&gt;plugin-transform-block-scoping&lt;/b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;npm install -D @babel/plugin-transform-block-scoping
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;$ npx babel app.js --plugins @babel/plugin-transform-block-scoping
var alert = msg =&amp;gt; window.alert(msg);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;화살표 함수&lt;/h3&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;npm install -D @babel/plugin-transform-arrow-functions
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;$ npx babel app.js --plugins @babel/plugin-transform-block-scoping --plugins @babel/plugin-transform-arrow-functions
var alert = function (msg) {
  return window.alert(msg);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;엄격모드 &amp;ldquo;use strict&amp;rdquo;&lt;/h3&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;npm install -D @babel/plugin-transform-strict-mode
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;$ npx babel app.js --plugins @babel/plugin-transform-block-scoping --plugins @babel/plugin-transform-arrow-functions --plugins @babel/plugin-transform-strict-mode
&quot;use strict&quot;;

var alert = function (msg) {
  return window.alert(msg);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;babel.config.js&lt;/h1&gt;
&lt;pre class=&quot;perl&quot;&gt;&lt;code&gt;module.exports = {
  plugins: [
    &quot;@babel/plugin-transform-block-scoping &quot;,
    &quot;@babel/plugin-transform-arrow-functions &quot;,
    &quot;@babel/plugin-transform-strict-mode&quot;,
  ],
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;$ npx babel app.js
&quot;use strict&quot;;

var alert = function (msg) {
  return window.alert(msg);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;프리셋&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ECMAScript2015+으로 코딩할 때 필요한 플러그인을 일일이 설정하는 일은 무척 비효율적인 일이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적에 맞게 여러가지 플러그인을 세트로 모아놓은 것을 &quot;&lt;b&gt;프리셋&lt;/b&gt;&quot;이라고 한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;커스텀 프리셋&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;my-babel-preset.js&lt;/p&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;module.exports = function myBabelPreset() {
  return {
    plugins: [
      &quot;@babel/plugin-transform-block-scoping&quot;,
      &quot;@babel/plugin-transform-arrow-functions&quot;,
      &quot;@babel/plugin-transform-strict-mode&quot;,
    ],
  };
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;babel.config.js&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;module.exports = {
  presets: [&quot;./my-babel-preset.js&quot;],
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;프리셋 사용하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://babeljs.io/docs/en/presets&quot;&gt;프리셋 docs&lt;/a&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;preset-env&lt;/li&gt;
&lt;li&gt;preset-flow&lt;/li&gt;
&lt;li&gt;preset-react&lt;/li&gt;
&lt;li&gt;preset-typescript&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;preset-env&lt;/h3&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;npm install -D @babel/preset-env
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;babel.config.js&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;module.exports = {
  presets: [&quot;@babel/preset-env&quot;],
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;$ npx babel app.js                
&quot;use strict&quot;;

var alert = function alert(msg) {
  return window.alert(msg);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;&lt;b&gt;env 프리셋 설정과 폴리필&lt;/b&gt;&lt;/h1&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;pre class=&quot;dts&quot;&gt;&lt;code&gt;module.exports = {
  presets: [
    [
      &quot;@babel/preset-env&quot;,
      {
        targets: {
          chrome: &quot;79&quot;,
          ie: &quot;11&quot;, // ie 11까지 지원하는 코드를 만든다
        },
      },
    ],
  ],
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;폴리필&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바벨은 ECMAScript2015+를 ECMAScript5 버전으로 변환할 수 있는 것만 빌드한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇지 못한 것들은 &quot;&lt;b&gt;폴리필&lt;/b&gt;&quot;이라고부르는 코드조각을 추가해서 해결&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app.js&lt;/p&gt;
&lt;pre class=&quot;haxe&quot;&gt;&lt;code&gt;new Promise();
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;babel.config.js&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;useBuiltIns는 어떤 방식으로 폴리필을 사용할지 설정하는 옵션이다. &quot;usage&quot; , &quot;entry&quot;, false 세 가지 값을 사용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바벨 문서의&amp;nbsp;&lt;a href=&quot;https://babeljs.io/docs/en/babel-preset-env#usebuiltins&quot;&gt;useBuiltIns&lt;/a&gt;와&amp;nbsp;&lt;a href=&quot;https://babeljs.io/docs/en/babel-preset-env#corejs&quot;&gt;corejs&lt;/a&gt;&amp;nbsp;섹션을 참고&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;module.exports = {
  presets: [
    [
      &quot;@babel/preset-env&quot;,
      {
        useBuiltIns: &quot;usage&quot;, // 폴리필 사용 방식 지정
        corejs: {
          // 폴리필 버전 지정
          version: 2,
        },
      },
    ],
  ],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;$ npx babel app.js
&quot;use strict&quot;;

require(&quot;core-js/modules/es.object.to-string.js&quot;);

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

var alert = function alert(msg) {
  return window.alert(msg);
};

new Promise();
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;웹팩으로 통합&lt;/h1&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;npm install -D babel-loader
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;module.exports = {
  module: {
    rules: [
      {
        test: /\\.js$/,
        exclude: /node_modules/,
        loader: &quot;babel-loader&quot;, // 바벨 로더를 추가한다
      },
    ],
  },
}
&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;&lt;a href=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1654329603671&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&quot; data-og-description=&quot;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bL6Lsp/hyOEgMACft/i24pyfRbFN6PFpk0HNz7P0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/fH0Jd/hyOEar7BVe/V742bxlOUxqKbegGyJopo0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/SrTHo/hyOEaMn8qz/BdbRj7Zsp0GcOS181CkMpk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bL6Lsp/hyOEgMACft/i24pyfRbFN6PFpk0HNz7P0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/fH0Jd/hyOEar7BVe/V742bxlOUxqKbegGyJopo0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/SrTHo/hyOEaMn8qz/BdbRj7Zsp0GcOS181CkMpk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500');&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;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/webpack</category>
      <category>Babel</category>
      <category>Webpack</category>
      <author>MG_conny</author>
      <guid isPermaLink="true">https://mugon-devlog.tistory.com/108</guid>
      <comments>https://mugon-devlog.tistory.com/108#entry108comment</comments>
      <pubDate>Sat, 4 Jun 2022 16:59:40 +0900</pubDate>
    </item>
    <item>
      <title>webpack@4 - plugin</title>
      <link>https://mugon-devlog.tistory.com/107</link>
      <description>&lt;h1&gt;webpack - plugin&lt;/h1&gt;
&lt;h1&gt;플러그인&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;플러그인 역할&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러그인은 번들된 결과물을 처리 ( &amp;harr;&amp;nbsp; 로더는 파일 단위로 처리)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 자바스크립트 난독화 , 특정 텍스트 추출&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;커스텀 플러그인&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;만들기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹팩 문서의&amp;nbsp;&lt;a href=&quot;https://webpack.js.org/contribute/writing-a-plugin/&quot;&gt;Writing a plugin&lt;/a&gt;을 보면 클래스로 플러그인을 정의&lt;/p&gt;
&lt;pre class=&quot;livescript&quot;&gt;&lt;code&gt;class MyPlugin {
  apply(compiler) {
    compiler.hooks.done.tap(&quot;My Plugin&quot;, stats =&amp;gt; {
      console.log(&quot;MyPlugin: done&quot;)
    })
  }
}

module.exports = MyPlugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;const MyPlugin = require(&quot;./myplugin&quot;)

module.exports = {
  plugins: [new MyPlugin()],
}
&lt;/code&gt;&lt;/pre&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;웹팩 내장 플러그인&amp;nbsp;&lt;a href=&quot;https://github.com/lcxfs1991/banner-webpack-plugin/blob/master/index.js&quot;&gt;BannerPlugin 코드&lt;/a&gt;를 참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; compilation 객체를 이용해서 접근&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;class MyPlugin {
  apply(compiler) {
    compiler.hooks.done.tap(&quot;My Plugin&quot;, stats =&amp;gt; {
      console.log(&quot;MyPlugin: done&quot;)
    })

    // compiler.plugin() 함수로 후처리한다
    compiler.plugin(&quot;emit&quot;, (compilation, callback) =&amp;gt; {
      const source = compilation.assets[&quot;main.js&quot;].source()
      console.log(source)
      callback()
    })
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;webpack 번들링된 결과물에 banner 추가해보기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;myplugin.js&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;class MyPlugin {
  apply(compiler) {
    compiler.plugin(&quot;emit&quot;, (compilation, callback) =&amp;gt; {
      const source = compilation.assets[&quot;main.js&quot;].source();
      compilation.assets[&quot;main.js&quot;].source = () =&amp;gt; {
        const banner = [
          &quot;/**&quot;,
          &quot; * 이것은 BannerPlugin이 처리한 결과입니다.&quot;,
          &quot; * Build Date 2022-06-04&quot;,
          &quot; */&quot;,
        ].join(&quot;\\n&quot;);
        return banner + &quot;\\n\\n&quot; + source;
      };
      callback();
    });
  }
}
module.exports = MyPlugin;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;154&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U5SdH/btrDWELTIi7/zvciaWUkR2IiX9RoHnDdk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U5SdH/btrDWELTIi7/zvciaWUkR2IiX9RoHnDdk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U5SdH/btrDWELTIi7/zvciaWUkR2IiX9RoHnDdk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU5SdH%2FbtrDWELTIi7%2FzvciaWUkR2IiX9RoHnDdk1%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;594&quot; height=&quot;154&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;154&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;자주 사용하는 플러그인&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;BannerPlugin&lt;/h2&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;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const webpack = require(&quot;webpack&quot;);
const childProcess = require(&quot;child_process&quot;);
module.exports = {
...
  plugins: [
    new webpack.BannerPlugin({
      banner: `
      Build Date: ${new Date().toLocaleString()}
      Commit Version: ${childProcess.execSync(&quot;git rev-parse --short HEAD&quot;)}
      Author: ${childProcess.execSync(&quot;git config user.name&quot;)}
      `,
    }),
  ],
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DefinePlugin&lt;/h2&gt;
&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;a href=&quot;https://webpack.js.org/plugins/define-plugin/&quot;&gt;DefinePlugin&lt;/a&gt;을 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;const webpack = require(&quot;webpack&quot;)

export default {
  plugins: [
		new webpack.DefinePlugin({
      TWO: &quot;1+1&quot;,
      THREE: JSON.stringify(&quot;1+1&quot;),
      &quot;api.domain&quot;: JSON.stringify(&quot;&amp;lt;http://dev.api.domain.com&amp;gt;&quot;),
    }),
	],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app.js&lt;/p&gt;
&lt;pre class=&quot;livecodeserver&quot;&gt;&lt;code&gt;console.log(process.env.NODE_ENV); // development
console.log(TWO); // 2
console.log(THREE); // 1+1
console.log(api.domain); // &amp;lt;http://dev.api.domain.com&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;HtmlWebpackPlugin&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/jantimon/html-webpack-plugin/&quot;&gt;HtmlWebpackPlugin&lt;/a&gt;은 HTML 파일을 후처리하는데 사용한다. 빌드 타임의 값을 넣거나 코드를 압축할수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 플러그인으로 빌드하면 HTML파일로 아웃풋에 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 유동적으로 HTML 파일을 생성가능&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;$ npm install -D html-webpack-plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;src/index.html&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;타이틀&amp;lt;%= env %&amp;gt;&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;!-- 로딩 스크립트 제거 --&amp;gt;
    &amp;lt;!-- &amp;lt;script src=&quot;dist/main.js&quot;&amp;gt;&amp;lt;/script&amp;gt; --&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;%= env %&amp;gt;&amp;nbsp;는 전달받은 env 변수 값을 출력한다. HtmlWebpackPlugin은 이 변수에 데이터를 주입시켜 동적으로 HTML 코드를 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports {
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html', // 템플릿 경로를 지정
      templateParameters: { // 템플릿에 주입할 파라매터 변수 지정
        env: process.env.NODE_ENV === 'development' ? '(개발용)' : '',
      },
			// 파일 압축
			minify: process.env.NODE_ENV === 'production' ? {
			    collapseWhitespace: true, // 빈칸 제거
			    removeComments: true, // 주석 제거
			  } : false,
	    }),
			// 정적파일 배포할때 캐쉬때문에 브라우저에 바로 반영되지 않는 경우
			hash: true, // 정적 파일을 불러올때 쿼리문자열에 웹팩 해쉬값을 추가한다
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;CleanWebpackPlugin&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 이전 결과물을 제거하는 플러그인 ( dist폴더 삭제 후 재생성)&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;npm install -D clean-webpack-plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;const { CleanWebpackPlugin } = require(&quot;clean-webpack-plugin&quot;)

module.exports = {
  plugins: [new CleanWebpackPlugin()],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;MiniCssExtractPlugin&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;번들 결과에서 스타일시트 코드만 뽑아서 별도의 CSS파일로 만들어줌&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;$ npm install -D mini-css-extract-plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;production 환경일 경우만 이 플러그인을 추가 filename 에 설정한 값으로 아웃풋 경로에 생성&lt;/li&gt;
&lt;li&gt;프로덕션 환경에서는 별도의 CSS 파일으로 추출하는 플러그인을 적용했으므로 다른 로더가 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;webpack - plugin&lt;/h1&gt;
&lt;h1&gt;플러그인&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;플러그인 역할&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러그인은 번들된 결과물을 처리 ( &amp;harr;&amp;nbsp; 로더는 파일 단위로 처리)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 자바스크립트 난독화 , 특정 텍스트 추출&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;커스텀 플러그인&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;만들기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹팩 문서의&amp;nbsp;&lt;a href=&quot;https://webpack.js.org/contribute/writing-a-plugin/&quot;&gt;Writing a plugin&lt;/a&gt;을 보면 클래스로 플러그인을 정의&lt;/p&gt;
&lt;pre class=&quot;livescript&quot;&gt;&lt;code&gt;class MyPlugin {
  apply(compiler) {
    compiler.hooks.done.tap(&quot;My Plugin&quot;, stats =&amp;gt; {
      console.log(&quot;MyPlugin: done&quot;)
    })
  }
}

module.exports = MyPlugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;const MyPlugin = require(&quot;./myplugin&quot;)

module.exports = {
  plugins: [new MyPlugin()],
}
&lt;/code&gt;&lt;/pre&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;웹팩 내장 플러그인&amp;nbsp;&lt;a href=&quot;https://github.com/lcxfs1991/banner-webpack-plugin/blob/master/index.js&quot;&gt;BannerPlugin 코드&lt;/a&gt;를 참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; compilation 객체를 이용해서 접근&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;class MyPlugin {
  apply(compiler) {
    compiler.hooks.done.tap(&quot;My Plugin&quot;, stats =&amp;gt; {
      console.log(&quot;MyPlugin: done&quot;)
    })

    // compiler.plugin() 함수로 후처리한다
    compiler.plugin(&quot;emit&quot;, (compilation, callback) =&amp;gt; {
      const source = compilation.assets[&quot;main.js&quot;].source()
      console.log(source)
      callback()
    })
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;webpack 번들링된 결과물에 banner 추가해보기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;myplugin.js&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;class MyPlugin {
  apply(compiler) {
    compiler.plugin(&quot;emit&quot;, (compilation, callback) =&amp;gt; {
      const source = compilation.assets[&quot;main.js&quot;].source();
      compilation.assets[&quot;main.js&quot;].source = () =&amp;gt; {
        const banner = [
          &quot;/**&quot;,
          &quot; * 이것은 BannerPlugin이 처리한 결과입니다.&quot;,
          &quot; * Build Date 2022-06-04&quot;,
          &quot; */&quot;,
        ].join(&quot;\\n&quot;);
        return banner + &quot;\\n\\n&quot; + source;
      };
      callback();
    });
  }
}
module.exports = MyPlugin;
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;자주 사용하는 플러그인&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;BannerPlugin&lt;/h2&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;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const webpack = require(&quot;webpack&quot;);
const childProcess = require(&quot;child_process&quot;);
module.exports = {
...
  plugins: [
    new webpack.BannerPlugin({
      banner: `
      Build Date: ${new Date().toLocaleString()}
      Commit Version: ${childProcess.execSync(&quot;git rev-parse --short HEAD&quot;)}
      Author: ${childProcess.execSync(&quot;git config user.name&quot;)}
      `,
    }),
  ],
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DefinePlugin&lt;/h2&gt;
&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;a href=&quot;https://webpack.js.org/plugins/define-plugin/&quot;&gt;DefinePlugin&lt;/a&gt;을 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;const webpack = require(&quot;webpack&quot;)

export default {
  plugins: [
		new webpack.DefinePlugin({
      TWO: &quot;1+1&quot;,
      THREE: JSON.stringify(&quot;1+1&quot;),
      &quot;api.domain&quot;: JSON.stringify(&quot;&amp;lt;http://dev.api.domain.com&amp;gt;&quot;),
    }),
	],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app.js&lt;/p&gt;
&lt;pre class=&quot;livecodeserver&quot;&gt;&lt;code&gt;console.log(process.env.NODE_ENV); // development
console.log(TWO); // 2
console.log(THREE); // 1+1
console.log(api.domain); // &amp;lt;http://dev.api.domain.com&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;HtmlWebpackPlugin&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/jantimon/html-webpack-plugin/&quot;&gt;HtmlWebpackPlugin&lt;/a&gt;은 HTML 파일을 후처리하는데 사용한다. 빌드 타임의 값을 넣거나 코드를 압축할수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 플러그인으로 빌드하면 HTML파일로 아웃풋에 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 유동적으로 HTML 파일을 생성가능&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;$ npm install -D html-webpack-plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;src/index.html&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;타이틀&amp;lt;%= env %&amp;gt;&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;!-- 로딩 스크립트 제거 --&amp;gt;
    &amp;lt;!-- &amp;lt;script src=&quot;dist/main.js&quot;&amp;gt;&amp;lt;/script&amp;gt; --&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;%= env %&amp;gt;&amp;nbsp;는 전달받은 env 변수 값을 출력한다. HtmlWebpackPlugin은 이 변수에 데이터를 주입시켜 동적으로 HTML 코드를 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports {
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html', // 템플릿 경로를 지정
      templateParameters: { // 템플릿에 주입할 파라매터 변수 지정
        env: process.env.NODE_ENV === 'development' ? '(개발용)' : '',
      },
			// 파일 압축
			minify: process.env.NODE_ENV === 'production' ? {
			    collapseWhitespace: true, // 빈칸 제거
			    removeComments: true, // 주석 제거
			  } : false,
	    }),
			// 정적파일 배포할때 캐쉬때문에 브라우저에 바로 반영되지 않는 경우
			hash: true, // 정적 파일을 불러올때 쿼리문자열에 웹팩 해쉬값을 추가한다
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;CleanWebpackPlugin&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 이전 결과물을 제거하는 플러그인 ( dist폴더 삭제 후 재생성)&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;npm install -D clean-webpack-plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;java&quot;&gt;&lt;code&gt;const { CleanWebpackPlugin } = require(&quot;clean-webpack-plugin&quot;)

module.exports = {
  plugins: [new CleanWebpackPlugin()],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;MiniCssExtractPlugin&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;번들 결과에서 스타일시트 코드만 뽑아서 별도의 CSS파일로 만들어줌&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;$ npm install -D mini-css-extract-plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;production 환경일 경우만 이 플러그인을 추가 filename 에 설정한 값으로 아웃풋 경로에 생성&lt;/li&gt;
&lt;li&gt;프로덕션 환경에서는 별도의 CSS 파일으로 추출하는 플러그인을 적용했으므로 다른 로더가 필요&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;※ 출저&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1654322970945&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&quot; data-og-description=&quot;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bBw2Yi/hyOEmeyXX8/hmm4KcVT6ufj3zUL1Dnox0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/glOgZ/hyOEgyE9Dv/IBNWlfJfQ4e9HUxSgx1df1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/WGJ5T/hyOCD96WNV/7mIWkRoU7Agg0gOGZvetS0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bBw2Yi/hyOEmeyXX8/hmm4KcVT6ufj3zUL1Dnox0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/glOgZ/hyOEgyE9Dv/IBNWlfJfQ4e9HUxSgx1df1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/WGJ5T/hyOCD96WNV/7mIWkRoU7Agg0gOGZvetS0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500');&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;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/webpack</category>
      <category>BannerPlugin</category>
      <category>cleanwebpackplugin</category>
      <category>CustomWebpackPlugin</category>
      <category>DefinPlugin</category>
      <category>htmlwebpackplugin</category>
      <category>MiniCssExtractPlugin</category>
      <category>plugin</category>
      <category>Webpack</category>
      <author>MG_conny</author>
      <guid isPermaLink="true">https://mugon-devlog.tistory.com/107</guid>
      <comments>https://mugon-devlog.tistory.com/107#entry107comment</comments>
      <pubDate>Sat, 4 Jun 2022 15:09:11 +0900</pubDate>
    </item>
    <item>
      <title>webpack@4 - loader</title>
      <link>https://mugon-devlog.tistory.com/106</link>
      <description>&lt;h1&gt;webpack - loader&lt;/h1&gt;
&lt;h1&gt;로더&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;로더의 역할&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹팩은 모든 파일을 모듈로 바라본다. 자바스크립트로 만든 모듈 뿐만아니라 스타일시트, 이미지, 폰트까지도 전부 모듈로 보기 때문에 import 구문을 사용하면 자바스크립트 코드 안으로 가져올수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것이 가능한 이유는 웹팩의&amp;nbsp;&lt;b&gt;로더&lt;/b&gt;&amp;nbsp;덕분이다. 로더는 타입스크립트 같은 다른 언어를 자바스크립트 문법으로 변환해 주거나 이미지를 data URL 형식의 문자열로 변환한다. 뿐만아니라 CSS 파일을 자바스크립트에서 직접 로딩할수 있도록 해준다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;커스텀 로더&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;만들기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;myloader.js&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;module.exports = function myloader(content) {
  console.log(&quot;myloader가 동작함&quot;)
  return content
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사용하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로더를 사용하려면 웹팩 설정파일의&amp;nbsp;module&amp;nbsp;객체에 추가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;module: {
  rules: [{
    test: /\\.js$/, // .js 확장자로 끝나는 모든 파일
    use: [path.resolve('./myloader.js')] // 방금 만든 로더를 적용한다
  }],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;module.rules&amp;nbsp;배열에 모듈을 추가하는데 test와 use로 구성된 객체를 전달한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;test에는 로딩에 적용할 파일을 지정한다. 파일명 뿐만아니라 파일 패턴을 정규표현식으로 지정할수 있는데 위 코드는 .js 확장자를 갖는 모든 파일을 처리하겠다는 의미다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;use에는 이 패턴에 해당하는 파일에 적용할 로더를 설정하는 부분이다. 방금 만든 myloader 함수의 경로를 지정한다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BwqvU/btrDU4xUAHa/DmESLTS9UAYDMR6KWNI0q0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BwqvU/btrDU4xUAHa/DmESLTS9UAYDMR6KWNI0q0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BwqvU/btrDU4xUAHa/DmESLTS9UAYDMR6KWNI0q0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBwqvU%2FbtrDU4xUAHa%2FDmESLTS9UAYDMR6KWNI0q0%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;429&quot; height=&quot;225&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&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;console.log() 함수를 alert() 함수로 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;myloader.js&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;module.exports = function myloader(content) {
  console.log(&quot;myloader가 동작함&quot;)
  return content.replace(&quot;console.log(&quot;, &quot;alert(&quot;) // console.log( -&amp;gt; alert( 로 치환
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;자주 사용하는 로더&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;css-loader&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app.js&lt;/p&gt;
&lt;pre class=&quot;xl&quot;&gt;&lt;code&gt;import &quot;./style.css&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;style.css&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;body {
  background-color: green;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSS 파일을 자바스크립트에서 불러와 사용하려면 CSS를 모듈로 변환하는 작업이 필요&lt;/p&gt;
&lt;pre class=&quot;cmake&quot;&gt;&lt;code&gt;$ npm install -D css-loader
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;openscad&quot;&gt;&lt;code&gt;module.exports = {
  module: {
    rules: [
      {
        test: /\\.css$/, // .css 확장자로 끝나는 모든 파일
        use: [&quot;css-loader&quot;], // css-loader를 적용한다
      },
    ],
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹팩은 엔트리 포인트부터 시작해서 모듈을 검색하다가 CSS 파일을 찾으면 css-loader로 처리할 것이다. use.loader에 로더 경로를 설정하는 대신 배열에 로더 이름을 문자열로 전달해도 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;style-loader&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈로 변경된 스타일 시트는 돔에 추가되어야만 브라우져가 해석할 수 있다. css-loader로 처리하면 자바스크립트 코드로만 변경되었을 뿐 돔에 적용되지 않았기 때문에 스트일이 적용되지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/webpack-contrib/style-loader&quot;&gt;style-loader&lt;/a&gt;는 자바스크립트로 변경된 스타일을 동적으로 돔에 추가하는 로더이다. CSS를 번들링하기 위해서는 css-loader와 style-loader를 함께 사용한다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;$ npm install -D style-loader
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;openscad&quot;&gt;&lt;code&gt;module.exports = {
  module: {
    rules: [
      {
        test: /\\.css$/,
        use: [&quot;style-loader&quot;, &quot;css-loader&quot;], // style-loader를 앞에 추가한다
      },
    ],
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열로 설정하면 뒤에서부터 앞으로 순서대로 로더가 동작한다. 위 설정은 모든 .css 확장자로 끝나는 모듈을 읽어 들여 css-loader를 적용하고 그 다음 style-loader를 적용한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;file-loader&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일을 모듈 형태로 지원하고 웹팩 아웃풋에 파일을 옮겨주는 것이&amp;nbsp;&lt;a href=&quot;https://github.com/webpack-contrib/file-loader&quot;&gt;file-loader&lt;/a&gt;가 하는 일이다. 가령 CSS에서 url() 함수에 이미지 파일 경로를 지정할 수 있는데 웹팩은 file-loader를 이용해서 이 파일을 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;style.css&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;body {
  background-image: url(bg.png);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 스타일시트는 url() 함수로 bg.png를 사용하는데 이때 로더를 동작시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;module.exports = {
  module: {
    rules: [
      {
        test: /\\.png$/, // .png 확장자로 마치는 모든 파일
        loader: &quot;file-loader&quot;, // 파일 로더를 적용한다
      },
    ],
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹팩이 .png 파일을 발견하면 file-loader를 실행할 것이다. 로더가 동작하고 나면 아웃풋에 설정한 경로로 이미지 파일을 복사된다. 아래 그림처럼 파일명이 해쉬코드로 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;file-loader 옵션을 조정해서 경로를 바로 잡아 주어야 한다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;module.exports = {
  module: {
    rules: [
      {
        test: /\\.png$/, // .png 확장자로 마치는 모든 파일
        loader: &quot;file-loader&quot;,
        options: {
          publicPath: &quot;./dist/&quot;, // prefix를 아웃풋 경로로 지정
          name: &quot;[name].[ext]?[hash]&quot;, // 파일명 형식
        },
      },
    ],
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;publicPath&amp;nbsp;옵션은 file-loader가 처리하는 파일을 모듈로 사용할 때 경로 앞에 추가되는 문자열이다. output에 설정한 'dist' 폴더에 이미지 파일을 옮길 것이므로 publicPath 값을 이것으로로 지정했다. 파일을 사용하는 측에서는 'bg.png'를 'dist/bg.png'로 변경하여 사용할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한&amp;nbsp;name&amp;nbsp;옵션을 사용했는데 이것은 로더가 파일을 아웃풋에 복사할때 사용하는 파일 이름이다. 기본적으로 설정된 해쉬값을 쿼리스트링으로 옮겨서 'bg.png?6453a9c65953c5c28aa2130dd437bbde' 형식으로 파일을 요청하도록 변경&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;url-loader&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용하는 이미지 갯수가 많다면 네트웍 리소스를 사용하는 부담이 있고 사이트 성능에 영향을 줄 수도 있다. 만약 한 페이지에서 작은 이미지를 여러 개 사용한다면&amp;nbsp;&lt;a href=&quot;https://en.wikipedia.org/wiki/Data_URI_scheme&quot;&gt;Data URI Scheme&lt;/a&gt; 을 이용하는 방법이 더 나은 경우도 있다. 이미지를 Base64로 인코딩하여 문자열 형태로 소스코드에 넣는 형식이다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;npm install -D url-loader
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;gams&quot;&gt;&lt;code&gt;{
  test: /\\.png$/,
  use: {
    loader: 'url-loader', // url 로더를 설정한다
    options: {
      publicPath: './dist/', // file-loader와 동일
      name: '[name].[ext]?[hash]', // file-loader와 동일
      limit: 5000 // 5kb 미만 파일만 data url로 처리
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈로 사용한 파일중 크기가 5kb 미만인 파일만 url-loader를 적용하는 설정이다. 만약 이보다 크면 file-loader가 처리하는데 옵션 중&amp;nbsp;&lt;a href=&quot;https://github.com/webpack-contrib/url-loader#options&quot;&gt;fallback&lt;/a&gt;&amp;nbsp;기본값이 file-loader이기 때문&lt;/p&gt;
&lt;h1&gt;webpack - loader&lt;/h1&gt;
&lt;h1&gt;로더&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;로더의 역할&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹팩은 모든 파일을 모듈로 바라본다. 자바스크립트로 만든 모듈 뿐만아니라 스타일시트, 이미지, 폰트까지도 전부 모듈로 보기 때문에 import 구문을 사용하면 자바스크립트 코드 안으로 가져올수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것이 가능한 이유는 웹팩의&amp;nbsp;&lt;b&gt;로더&lt;/b&gt;&amp;nbsp;덕분이다. 로더는 타입스크립트 같은 다른 언어를 자바스크립트 문법으로 변환해 주거나 이미지를 data URL 형식의 문자열로 변환한다. 뿐만아니라 CSS 파일을 자바스크립트에서 직접 로딩할수 있도록 해준다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;커스텀 로더&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;만들기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;myloader.js&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;module.exports = function myloader(content) {
  console.log(&quot;myloader가 동작함&quot;)
  return content
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사용하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로더를 사용하려면 웹팩 설정파일의&amp;nbsp;module&amp;nbsp;객체에 추가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;module: {
  rules: [{
    test: /\\.js$/, // .js 확장자로 끝나는 모든 파일
    use: [path.resolve('./myloader.js')] // 방금 만든 로더를 적용한다
  }],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;module.rules&amp;nbsp;배열에 모듈을 추가하는데 test와 use로 구성된 객체를 전달한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;test에는 로딩에 적용할 파일을 지정한다. 파일명 뿐만아니라 파일 패턴을 정규표현식으로 지정할수 있는데 위 코드는 .js 확장자를 갖는 모든 파일을 처리하겠다는 의미다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;use에는 이 패턴에 해당하는 파일에 적용할 로더를 설정하는 부분이다. 방금 만든 myloader 함수의 경로를 지정한다&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;활용하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;console.log() 함수를 alert() 함수로 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;myloader.js&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;module.exports = function myloader(content) {
  console.log(&quot;myloader가 동작함&quot;)
  return content.replace(&quot;console.log(&quot;, &quot;alert(&quot;) // console.log( -&amp;gt; alert( 로 치환
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;자주 사용하는 로더&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;css-loader&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app.js&lt;/p&gt;
&lt;pre class=&quot;xl&quot;&gt;&lt;code&gt;import &quot;./style.css&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;style.css&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;body {
  background-color: green;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSS 파일을 자바스크립트에서 불러와 사용하려면 CSS를 모듈로 변환하는 작업이 필요&lt;/p&gt;
&lt;pre class=&quot;cmake&quot;&gt;&lt;code&gt;$ npm install -D css-loader
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;openscad&quot;&gt;&lt;code&gt;module.exports = {
  module: {
    rules: [
      {
        test: /\\.css$/, // .css 확장자로 끝나는 모든 파일
        use: [&quot;css-loader&quot;], // css-loader를 적용한다
      },
    ],
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹팩은 엔트리 포인트부터 시작해서 모듈을 검색하다가 CSS 파일을 찾으면 css-loader로 처리할 것이다. use.loader에 로더 경로를 설정하는 대신 배열에 로더 이름을 문자열로 전달해도 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;style-loader&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈로 변경된 스타일 시트는 돔에 추가되어야만 브라우져가 해석할 수 있다. css-loader로 처리하면 자바스크립트 코드로만 변경되었을 뿐 돔에 적용되지 않았기 때문에 스트일이 적용되지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/webpack-contrib/style-loader&quot;&gt;style-loader&lt;/a&gt;는 자바스크립트로 변경된 스타일을 동적으로 돔에 추가하는 로더이다. CSS를 번들링하기 위해서는 css-loader와 style-loader를 함께 사용한다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;$ npm install -D style-loader
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;openscad&quot;&gt;&lt;code&gt;module.exports = {
  module: {
    rules: [
      {
        test: /\\.css$/,
        use: [&quot;style-loader&quot;, &quot;css-loader&quot;], // style-loader를 앞에 추가한다
      },
    ],
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열로 설정하면 뒤에서부터 앞으로 순서대로 로더가 동작한다. 위 설정은 모든 .css 확장자로 끝나는 모듈을 읽어 들여 css-loader를 적용하고 그 다음 style-loader를 적용한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;file-loader&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일을 모듈 형태로 지원하고 웹팩 아웃풋에 파일을 옮겨주는 것이&amp;nbsp;&lt;a href=&quot;https://github.com/webpack-contrib/file-loader&quot;&gt;file-loader&lt;/a&gt;가 하는 일이다. 가령 CSS에서 url() 함수에 이미지 파일 경로를 지정할 수 있는데 웹팩은 file-loader를 이용해서 이 파일을 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;style.css&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;body {
  background-image: url(bg.png);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 스타일시트는 url() 함수로 bg.png를 사용하는데 이때 로더를 동작시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;module.exports = {
  module: {
    rules: [
      {
        test: /\\.png$/, // .png 확장자로 마치는 모든 파일
        loader: &quot;file-loader&quot;, // 파일 로더를 적용한다
      },
    ],
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웹팩이 .png 파일을 발견하면 file-loader를 실행할 것이다. 로더가 동작하고 나면 아웃풋에 설정한 경로로 이미지 파일을 복사된다. 아래 그림처럼 파일명이 해쉬코드로 변경&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;file-loader 옵션을 조정해서 경로를 바로 잡아 주어야 한다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;module.exports = {
  module: {
    rules: [
      {
        test: /\\.png$/, // .png 확장자로 마치는 모든 파일
        loader: &quot;file-loader&quot;,
        options: {
          publicPath: &quot;./dist/&quot;, // prefix를 아웃풋 경로로 지정
          name: &quot;[name].[ext]?[hash]&quot;, // 파일명 형식
        },
      },
    ],
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;publicPath&amp;nbsp;옵션은 file-loader가 처리하는 파일을 모듈로 사용할 때 경로 앞에 추가되는 문자열이다. output에 설정한 'dist' 폴더에 이미지 파일을 옮길 것이므로 publicPath 값을 이것으로로 지정했다. 파일을 사용하는 측에서는 'bg.png'를 'dist/bg.png'로 변경하여 사용할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한&amp;nbsp;name&amp;nbsp;옵션을 사용했는데 이것은 로더가 파일을 아웃풋에 복사할때 사용하는 파일 이름이다. 기본적으로 설정된 해쉬값을 쿼리스트링으로 옮겨서 'bg.png?6453a9c65953c5c28aa2130dd437bbde' 형식으로 파일을 요청하도록 변경&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;url-loader&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용하는 이미지 갯수가 많다면 네트웍 리소스를 사용하는 부담이 있고 사이트 성능에 영향을 줄 수도 있다. 만약 한 페이지에서 작은 이미지를 여러 개 사용한다면&amp;nbsp;&lt;a href=&quot;https://en.wikipedia.org/wiki/Data_URI_scheme&quot;&gt;Data URI Scheme&lt;/a&gt; 을 이용하는 방법이 더 나은 경우도 있다. 이미지를 Base64로 인코딩하여 문자열 형태로 소스코드에 넣는 형식이다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;npm install -D url-loader
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;gams&quot;&gt;&lt;code&gt;{
  test: /\\.png$/,
  use: {
    loader: 'url-loader', // url 로더를 설정한다
    options: {
      publicPath: './dist/', // file-loader와 동일
      name: '[name].[ext]?[hash]', // file-loader와 동일
      limit: 5000 // 5kb 미만 파일만 data url로 처리
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈로 사용한 파일중 크기가 5kb 미만인 파일만 url-loader를 적용하는 설정이다. 만약 이보다 크면 file-loader가 처리하는데 옵션 중&amp;nbsp;fallback&amp;nbsp;기본값이 file-loader이기 때문&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://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1654284968496&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&quot; data-og-description=&quot;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bBw2Yi/hyOEmeyXX8/hmm4KcVT6ufj3zUL1Dnox0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/glOgZ/hyOEgyE9Dv/IBNWlfJfQ4e9HUxSgx1df1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/WGJ5T/hyOCD96WNV/7mIWkRoU7Agg0gOGZvetS0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bBw2Yi/hyOEmeyXX8/hmm4KcVT6ufj3zUL1Dnox0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/glOgZ/hyOEgyE9Dv/IBNWlfJfQ4e9HUxSgx1df1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/WGJ5T/hyOCD96WNV/7mIWkRoU7Agg0gOGZvetS0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500');&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;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/webpack</category>
      <category>css-loader</category>
      <category>file-loader</category>
      <category>LOADER</category>
      <category>style-loader</category>
      <category>Webpack</category>
      <author>MG_conny</author>
      <guid isPermaLink="true">https://mugon-devlog.tistory.com/106</guid>
      <comments>https://mugon-devlog.tistory.com/106#entry106comment</comments>
      <pubDate>Sat, 4 Jun 2022 04:33:52 +0900</pubDate>
    </item>
    <item>
      <title>webpack@4 - 엔트리/아웃풋</title>
      <link>https://mugon-devlog.tistory.com/105</link>
      <description>&lt;h1&gt;webpack - 엔트리/아웃풋&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;a href=&quot;https://webpack.js.org/&quot;&gt;웹팩&lt;/a&gt;은 여러개 파일을 하나의 파일로 합쳐주는 번들러(bundler)다. 하나의 시작점(entry point)으로부터 의존적인 모듈을 전부 찾아내서 하나의 결과물을 만들어 낸다. app.js부터 시작해 math.js 파일을 찾은 뒤 하나의 파일로 만드는 방식이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;421&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csbCry/btrDXoVG87S/8JMMjRC5y2TQ55Chl3SEok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csbCry/btrDXoVG87S/8JMMjRC5y2TQ55Chl3SEok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csbCry/btrDXoVG87S/8JMMjRC5y2TQ55Chl3SEok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsbCry%2FbtrDXoVG87S%2F8JMMjRC5y2TQ55Chl3SEok%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;751&quot; height=&quot;421&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;421&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;webpack 설치&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;번들 작업을 하는&amp;nbsp;&lt;a href=&quot;https://github.com/webpack/webpack&quot;&gt;webpack&lt;/a&gt;&amp;nbsp;패키지와 웹팩 터미널 도구인&amp;nbsp;&lt;a href=&quot;https://github.com/webpack/webpack-cli&quot;&gt;webpack-cli&lt;/a&gt;를 설치한다.&lt;/p&gt;
&lt;pre class=&quot;avrasm&quot;&gt;&lt;code&gt;npm install -D webpack webpack-cli
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 완료하면&amp;nbsp;node_modules/.bin 폴더에 실행 가능한 명령어가 몇 개 생긴다. webpack과 webpack-cli가 있는데 둘 중 하나를 실행하면 된다&lt;/p&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;$ node_modules/.bin/webpack --help

  --mode &amp;lt;value&amp;gt;                         Defines the mode to pass to webpack.
                                     [선택: &quot;development&quot;, &quot;production&quot;, &quot;none&quot;]
  --entry &amp;lt;value...&amp;gt;                     The entry point(s) of your application e.g. ./src/main.js.
  -o, --output-path &amp;lt;value&amp;gt;              Output location of the file generated by webpack e.g. ./dist/.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;--mode,&amp;nbsp;--entry,&amp;nbsp;--output&amp;nbsp;세 개 옵션만 사용하면 코드를 묶을 수 있다.&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;$ node_modules/.bin/webpack --mode development --entry ./src/app.js --output-path dist/main.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;-mode는 웹팩 실행 모드는 의미하는데 개발 버전인 development를 지정한다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&quot;development&quot;, &quot;production&quot;, &quot;none&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;-entry는 시작점 경로를 지정하는 옵션이다&lt;/li&gt;
&lt;li&gt;-output은 번들링 결과물을 위치할 경로다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;entry를 통해 웹팩의 모든 모듈들을 하나로 합치고 그 결과물을 저장하는 경로&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;config file 생성&lt;/h1&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;$ node_modules/.bin/webpack --help

  --config               Path to the config file
                         [문자열] [기본: webpack.config.js or webpackfile.js]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 옵션은 웹팩 설정파일의 경로를 지정할 수 있는데 기본 파일명이 webpack.config.js 혹은 webpackfile.js다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;const path = require(&quot;path&quot;)

module.exports = {
  mode: &quot;development&quot;,
  entry: {
    main: &quot;./src/app.js&quot;,
  },
  output: {
    filename: &quot;[name].js&quot;, // [name]은 entry에서 설정한 key 값 =&amp;gt; entry가 여러개일 경우
    path: path.resolve(&quot;./dist&quot;),
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm custom 명령어 추가&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;scripts&quot;: {
    &quot;build&quot;: &quot;webpack&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm run build &amp;rArr; NPM은 현재 프로젝트의 node_modules를 검색해 웹팩 명령어를 찾음&lt;/p&gt;
&lt;h1&gt;webpack - 엔트리/아웃풋&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;aside&amp;gt;   &lt;a href=&quot;https://webpack.js.org/&quot;&gt;웹팩&lt;/a&gt;은 여러개 파일을 하나의 파일로 합쳐주는 번들러(bundler)다. 하나의 시작점(entry point)으로부터 의존적인 모듈을 전부 찾아내서 하나의 결과물을 만들어 낸다. app.js부터 시작해 math.js 파일을 찾은 뒤 하나의 파일로 만드는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lt;/aside&amp;gt;&lt;/p&gt;
&lt;h1&gt;webpack 설치&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;번들 작업을 하는&amp;nbsp;&lt;a href=&quot;https://github.com/webpack/webpack&quot;&gt;webpack&lt;/a&gt;&amp;nbsp;패키지와 웹팩 터미널 도구인&amp;nbsp;&lt;a href=&quot;https://github.com/webpack/webpack-cli&quot;&gt;webpack-cli&lt;/a&gt;를 설치한다.&lt;/p&gt;
&lt;pre class=&quot;avrasm&quot;&gt;&lt;code&gt;npm install -D webpack webpack-cli
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 완료하면&amp;nbsp;node_modules/.bin 폴더에 실행 가능한 명령어가 몇 개 생긴다. webpack과 webpack-cli가 있는데 둘 중 하나를 실행하면 된다&lt;/p&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;$ node_modules/.bin/webpack --help

  --mode &amp;lt;value&amp;gt;                         Defines the mode to pass to webpack.
                                     [선택: &quot;development&quot;, &quot;production&quot;, &quot;none&quot;]
  --entry &amp;lt;value...&amp;gt;                     The entry point(s) of your application e.g. ./src/main.js.
  -o, --output-path &amp;lt;value&amp;gt;              Output location of the file generated by webpack e.g. ./dist/.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;--mode,&amp;nbsp;--entry,&amp;nbsp;--output&amp;nbsp;세 개 옵션만 사용하면 코드를 묶을 수 있다.&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;$ node_modules/.bin/webpack --mode development --entry ./src/app.js --output-path dist/main.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;-mode는 웹팩 실행 모드는 의미하는데 개발 버전인 development를 지정한다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&quot;development&quot;, &quot;production&quot;, &quot;none&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;-entry는 시작점 경로를 지정하는 옵션이다&lt;/li&gt;
&lt;li&gt;-output은 번들링 결과물을 위치할 경로다
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;entry를 통해 웹팩의 모든 모듈들을 하나로 합치고 그 결과물을 저장하는 경로&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;config file 생성&lt;/h1&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;$ node_modules/.bin/webpack --help

  --config               Path to the config file
                         [문자열] [기본: webpack.config.js or webpackfile.js]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 옵션은 웹팩 설정파일의 경로를 지정할 수 있는데 기본 파일명이 webpack.config.js 혹은 webpackfile.js다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;webpack.config.js&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;const path = require(&quot;path&quot;)

module.exports = {
  mode: &quot;development&quot;,
  entry: {
    main: &quot;./src/app.js&quot;,
  },
  output: {
    filename: &quot;[name].js&quot;, // [name]은 entry에서 설정한 key 값 =&amp;gt; entry가 여러개일 경우
    path: path.resolve(&quot;./dist&quot;),
  },
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm custom 명령어 추가&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;scripts&quot;: {
    &quot;build&quot;: &quot;webpack&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;npm run build &amp;rArr; NPM은 현재 프로젝트의 node_modules를 검색해 웹팩 명령어를 찾음&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://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1654284957713&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&quot; data-og-description=&quot;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bBw2Yi/hyOEmeyXX8/hmm4KcVT6ufj3zUL1Dnox0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/glOgZ/hyOEgyE9Dv/IBNWlfJfQ4e9HUxSgx1df1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/WGJ5T/hyOCD96WNV/7mIWkRoU7Agg0gOGZvetS0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bBw2Yi/hyOEmeyXX8/hmm4KcVT6ufj3zUL1Dnox0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/glOgZ/hyOEgyE9Dv/IBNWlfJfQ4e9HUxSgx1df1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/WGJ5T/hyOCD96WNV/7mIWkRoU7Agg0gOGZvetS0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500');&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;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/webpack</category>
      <category>entry</category>
      <category>output</category>
      <category>Webpack</category>
      <author>MG_conny</author>
      <guid isPermaLink="true">https://mugon-devlog.tistory.com/105</guid>
      <comments>https://mugon-devlog.tistory.com/105#entry105comment</comments>
      <pubDate>Sat, 4 Jun 2022 04:31:01 +0900</pubDate>
    </item>
    <item>
      <title>webpack@4 - basic</title>
      <link>https://mugon-devlog.tistory.com/104</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;article id=&quot;bc72988b-a7f5-47e6-8776-f9287359f1d8&quot; class=&quot;page sans&quot;&gt;&lt;header&gt;
&lt;h1 class=&quot;page-title&quot;&gt;webpack-basic&lt;/h1&gt;
&lt;/header&gt;
&lt;div class=&quot;page-body&quot;&gt;&lt;nav id=&quot;49da3152-cdfb-4c07-9b30-39cc2426557d&quot; class=&quot;block-color-gray table_of_contents&quot;&gt;
&lt;div class=&quot;table_of_contents-item table_of_contents-indent-0&quot;&gt;&lt;a class=&quot;table_of_contents-link&quot; href=&quot;#ac6f7a1e-aaae-43d8-95ac-a4522b0f9cb6&quot;&gt;배경&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;table_of_contents-item table_of_contents-indent-1&quot;&gt;&lt;a class=&quot;table_of_contents-link&quot; href=&quot;#f33dadad-aad1-462e-8bfb-1818bba0e552&quot;&gt;import/export 구문이 없었을때&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;table_of_contents-item table_of_contents-indent-2&quot;&gt;&lt;a class=&quot;table_of_contents-link&quot; href=&quot;#a03e5d53-141e-4c01-ba3a-a7ee5aaf2987&quot;&gt;문제점&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;table_of_contents-item table_of_contents-indent-0&quot;&gt;&lt;a class=&quot;table_of_contents-link&quot; href=&quot;#06b075c7-2234-4ffa-ab05-9fc6c347df8a&quot;&gt;IIFE 방식의 모듈&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;table_of_contents-item table_of_contents-indent-0&quot;&gt;&lt;a class=&quot;table_of_contents-link&quot; href=&quot;#ac4703eb-1d75-4955-a725-3a7b113fdf51&quot;&gt;다양한 모듈 스펙&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;table_of_contents-item table_of_contents-indent-1&quot;&gt;&lt;a class=&quot;table_of_contents-link&quot; href=&quot;#19db2207-7287-4310-8a73-f94de59c8fd3&quot;&gt;CommonJS&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;table_of_contents-item table_of_contents-indent-1&quot;&gt;&lt;a href=&quot;https://github.com/amdjs/amdjs-api/wiki/AMD&quot;&gt;&lt;b&gt;AMD&lt;/b&gt;&lt;/a&gt;&lt;a class=&quot;table_of_contents-link&quot; href=&quot;#789a445e-0b82-4fd4-9985-3d4a1c2c5fc6&quot;&gt;(Asynchronous Module Definition)&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;table_of_contents-item table_of_contents-indent-1&quot;&gt;&lt;a href=&quot;https://github.com/umdjs/umd&quot;&gt;&lt;b&gt;UMD&lt;/b&gt;&lt;/a&gt;&lt;a class=&quot;table_of_contents-link&quot; href=&quot;#34e8a656-c6dc-461e-ac26-a5e3ded3306d&quot;&gt;(Universal Module Definition)&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;table_of_contents-item table_of_contents-indent-0&quot;&gt;&lt;a class=&quot;table_of_contents-link&quot; href=&quot;#25582320-a57f-4c09-a06f-b60c81f1d3e3&quot;&gt;ES2015 표준 모듈 시스템&lt;/a&gt;&lt;/div&gt;
&lt;/nav&gt;
&lt;h1 id=&quot;ac6f7a1e-aaae-43d8-95ac-a4522b0f9cb6&quot; class=&quot;&quot;&gt;배경&lt;/h1&gt;
&lt;figure id=&quot;d154ed19-18c9-485a-a753-060fc3278755&quot; class=&quot;block-color-gray_background callout&quot; style=&quot;white-space: pre-wrap; display: flex;&quot;&gt;
&lt;div style=&quot;font-size: 1.5em;&quot;&gt;&lt;span class=&quot;icon&quot;&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;width: 100%;&quot;&gt;문법 수준에서 모듈을 지원하기 시작한 것은 ES2015 부터이다.&lt;/div&gt;
&lt;/figure&gt;
&lt;h2 id=&quot;f33dadad-aad1-462e-8bfb-1818bba0e552&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;import/export 구문이 없었을때&lt;/h2&gt;
&lt;ul id=&quot;d5c40092-5900-4369-9895-7e4ddde828a7&quot; class=&quot;toggle&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;details open=&quot;&quot;&gt;
&lt;summary&gt;math.js&lt;/summary&gt;
&lt;pre id=&quot;e4594a25-2fb1-47c3-88a9-549354e52781&quot; class=&quot;code ada&quot;&gt;&lt;code&gt;function sum(a, b) {
  return a + b;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/details&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;ul id=&quot;a24fa4b3-8621-44ac-b9b2-6f9271b6fcf1&quot; class=&quot;toggle&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;details open=&quot;&quot;&gt;
&lt;summary&gt;app.js&lt;/summary&gt;
&lt;pre id=&quot;75d1dd47-c11b-486a-b1ec-fb34c4e1c3b2&quot; class=&quot;code angelscript&quot;&gt;&lt;code&gt;console.log(sum(1,2))&lt;/code&gt;&lt;/pre&gt;
&lt;/details&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p id=&quot;55363977-35a8-4c15-aea0-b2e0e55bec87&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;아래와 같이 하나의 html 파일 안에서 로딩해야 실행 가능&lt;/p&gt;
&lt;p class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;index.html&lt;/p&gt;
&lt;div class=&quot;indented&quot;&gt;
&lt;pre id=&quot;47aaf22b-e24e-40b6-85e2-1c39aa0ba1ed&quot; class=&quot;code xml&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
    &amp;lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&amp;gt;
    &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&amp;gt;
    &amp;lt;title&amp;gt;Document&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;script src=&quot;src/app.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
		&amp;lt;script src=&quot;src/math.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id=&quot;a03e5d53-141e-4c01-ba3a-a7ee5aaf2987&quot; class=&quot;&quot; data-ke-size=&quot;size23&quot;&gt;문제점&lt;/h3&gt;
&lt;p id=&quot;181382b4-c363-45ae-bfa2-47c99bd80d96&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;math.js에서 선언한 함수가 전역공간에 노출되기에 다른 파일에서 math.js에서 선언한 함수와 동일한 이름으로 다시 선언했을때 충돌이 발생&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxjY5w/btrDWi2WMng/oOHJbFg0pJGCK58ml0tKZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxjY5w/btrDWi2WMng/oOHJbFg0pJGCK58ml0tKZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxjY5w/btrDWi2WMng/oOHJbFg0pJGCK58ml0tKZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxjY5w%2FbtrDWi2WMng%2FoOHJbFg0pJGCK58ml0tKZK%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;325&quot; height=&quot;168&quot; data-filename=&quot;Untitled.png&quot; data-origin-width=&quot;325&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;h1 class=&quot;&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h1 id=&quot;06b075c7-2234-4ffa-ab05-9fc6c347df8a&quot; class=&quot;&quot;&gt;IIFE 방식의 모듈&lt;/h1&gt;
&lt;p id=&quot;1abd99f4-987b-4978-9e19-4cf9a90f8491&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;위의 문제를 예방하기 위해 스코프를 사용&lt;/p&gt;
&lt;ul id=&quot;0057861f-2b6d-4c3f-8fb7-0a6dbb85a88e&quot; class=&quot;bulleted-list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot;&gt;함수 스코프를 만들어 외부에서 안으로 접근하지 못하도록 공간을 격리&lt;/li&gt;
&lt;/ul&gt;
&lt;p id=&quot;f61506b0-cd0a-4661-aa1b-be5ce40c751c&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;math.js&lt;/p&gt;
&lt;pre id=&quot;dc1dbf75-6bff-4c7a-a89c-2a493e27b705&quot; class=&quot;code lua&quot;&gt;&lt;code&gt;var math = math || {} // math 네임스페이스

;(function () {
  function sum(a, b) {
    return a + b
  }
  math.sum = sum // 네이스페이스에 추가
})()&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;58174d96-22b6-4dc6-8eec-9f0e639f5619&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;app.js에서 math.sum으로 호출하여 사용&lt;/p&gt;
&lt;h1 id=&quot;ac4703eb-1d75-4955-a725-3a7b113fdf51&quot; class=&quot;&quot;&gt;다양한 모듈 스펙&lt;/h1&gt;
&lt;h2 id=&quot;19db2207-7287-4310-8a73-f94de59c8fd3&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;CommonJS&lt;/h2&gt;
&lt;figure id=&quot;682bede0-00bb-4ee9-9b9b-3b307733ff04&quot; class=&quot;block-color-gray_background callout&quot; style=&quot;white-space: pre-wrap; display: flex;&quot;&gt;
&lt;div style=&quot;font-size: 1.5em;&quot;&gt;&lt;span class=&quot;icon&quot;&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;width: 100%;&quot;&gt;자바스크립트를 사용하는 모든 환경에서 모듈을 사용하는 것이 목표&lt;/div&gt;
&lt;/figure&gt;
&lt;ul id=&quot;70e03a49-0efe-4997-a6a3-410e1f8bef6a&quot; class=&quot;bulleted-list&quot; style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc;&quot;&gt;exports 키워드로 모듈을 만들고 require()함수로 불러 들이는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;p id=&quot;47e6e9b8-478a-4a1b-a96f-41bf45dcf5a9&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;math.js&lt;/p&gt;
&lt;pre id=&quot;9f2d020b-b6b7-424b-b198-5334bf92c182&quot; class=&quot;code ada&quot;&gt;&lt;code&gt;exports function sum(a, b) { return a + b; }&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;d08251c4-1af8-48a3-9c19-4b9b59306a01&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;app.js&lt;/p&gt;
&lt;pre id=&quot;adb8c803-9a56-46e5-94cb-024fc85b84dc&quot; class=&quot;code angelscript&quot;&gt;&lt;code&gt;const math = require(&quot;./math.js&quot;)
math.sum(1, 2) // 3&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;789a445e-0b82-4fd4-9985-3d4a1c2c5fc6&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;a href=&quot;https://github.com/amdjs/amdjs-api/wiki/AMD&quot;&gt;&lt;b&gt;AMD&lt;/b&gt;&lt;/a&gt;(Asynchronous Module Definition)&lt;/h2&gt;
&lt;p id=&quot;56e49037-834b-46ff-8cd8-b2e4af6dc0f1&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;비동기로 로딩되는 환경에서 모듈을 사용하는 것이 목표다. 주로 브라우져 환경이다.&lt;/p&gt;
&lt;h2 id=&quot;34e8a656-c6dc-461e-ac26-a5e3ded3306d&quot; class=&quot;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;a href=&quot;https://github.com/umdjs/umd&quot;&gt;&lt;b&gt;UMD&lt;/b&gt;&lt;/a&gt;(Universal Module Definition)&lt;/h2&gt;
&lt;p id=&quot;47a5d57c-f857-480d-8294-569de055cc53&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;AMD기반으로 CommonJS 방식까지 지원하는 통합 형태다.&lt;/p&gt;
&lt;figure id=&quot;a3f91c9f-9bba-4d8c-b57f-fd3170bea820&quot; class=&quot;block-color-gray_background callout&quot; style=&quot;white-space: pre-wrap; display: flex;&quot;&gt;
&lt;div style=&quot;font-size: 1.5em;&quot;&gt;&lt;span class=&quot;icon&quot;&gt; &lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;width: 100%;&quot;&gt;이렇게 각 커뮤니티에서 각자의 스펙을 제안하다가&amp;nbsp;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import&quot;&gt;&lt;b&gt;ES2015에서 표준 모듈 시스템&lt;/b&gt;&lt;/a&gt;&amp;nbsp;을 내 놓았다. 지금은 바벨과 웹팩을 이용해 모듈 시스템을 사용하는 것이 일반적이다.&lt;/div&gt;
&lt;/figure&gt;
&lt;h1 id=&quot;25582320-a57f-4c09-a06f-b60c81f1d3e3&quot; class=&quot;&quot;&gt;ES2015 표준 모듈 시스템&lt;/h1&gt;
&lt;p id=&quot;c984cf7f-5e2e-4312-8d6b-9eb403c6c6a9&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;export&lt;/code&gt;구문으로 모듈을 만들고&amp;nbsp;&lt;code&gt;import&lt;/code&gt;&amp;nbsp;구문으로 가져올 수 있다.&lt;/p&gt;
&lt;p id=&quot;3a8925ee-4e5f-41f1-8dd8-bc8c627f506c&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;math.js&lt;/p&gt;
&lt;pre id=&quot;308876b3-667e-4570-982e-b0011d425bd4&quot; class=&quot;code ada&quot;&gt;&lt;code&gt;export function sum(a, b) {
  return a + b
}&lt;/code&gt;&lt;/pre&gt;
&lt;p id=&quot;17e0493d-9616-4070-a7ff-207ca79742ad&quot; class=&quot;&quot; data-ke-size=&quot;size16&quot;&gt;app.js&lt;/p&gt;
&lt;pre id=&quot;6639fddd-ca40-44f1-8b2b-a829d5cf6e0c&quot; class=&quot;code clean&quot;&gt;&lt;code&gt;import * as math from &quot;./math.js&quot;
// or
import {sum} from &quot;./math.js&quot;
math.sum(1, 2) // 3&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/article&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://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1654284931605&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&quot; data-og-description=&quot;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bBw2Yi/hyOEmeyXX8/hmm4KcVT6ufj3zUL1Dnox0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/glOgZ/hyOEgyE9Dv/IBNWlfJfQ4e9HUxSgx1df1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/WGJ5T/hyOCD96WNV/7mIWkRoU7Agg0gOGZvetS0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bBw2Yi/hyOEmeyXX8/hmm4KcVT6ufj3zUL1Dnox0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/glOgZ/hyOEgyE9Dv/IBNWlfJfQ4e9HUxSgx1df1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/WGJ5T/hyOCD96WNV/7mIWkRoU7Agg0gOGZvetS0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500');&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;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/webpack</category>
      <category>module</category>
      <category>Webpack</category>
      <author>MG_conny</author>
      <guid isPermaLink="true">https://mugon-devlog.tistory.com/104</guid>
      <comments>https://mugon-devlog.tistory.com/104#entry104comment</comments>
      <pubDate>Sat, 4 Jun 2022 04:25:42 +0900</pubDate>
    </item>
    <item>
      <title>webpack@4 - 들어가기전 package.json</title>
      <link>https://mugon-devlog.tistory.com/103</link>
      <description>&lt;h1&gt;package.json&lt;/h1&gt;
&lt;aside&gt;  Node.js는 package.json 파일에 프로젝트의 모든 정보를 기록&lt;/aside&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;name: 프로젝트 이름&lt;/li&gt;
&lt;li&gt;version: 프로젝트 버전 정보&lt;/li&gt;
&lt;li&gt;description: 프로젝트 설명&lt;/li&gt;
&lt;li&gt;main: 노드 어플리케이션일 경우 진입점 경로. 프론트엔드 프로젝트일 경우 사용하지 않는다.&lt;/li&gt;
&lt;li&gt;scripts: 프로젝트 명령어를 등록할 수 있다.초기화시 test 명령어가 샘플로 등록되어 있다&lt;/li&gt;
&lt;li&gt;author: 프로그램 작성자&lt;/li&gt;
&lt;li&gt;license: 라이센스&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;프로젝트 명령어&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성한 프로젝트는 package.json에 등록한 스크립트를 이용해 실행&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;주요 명령어&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;start: 어플리케이션 실행&lt;/li&gt;
&lt;li&gt;test: 테스트&lt;/li&gt;
&lt;li&gt;install: 패키지 설치&lt;/li&gt;
&lt;li&gt;uninstall: 패키지 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커스텀으로 등록한 명령어는 &lt;code&gt;run&lt;/code&gt;을 추가해서 실행&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;패키지 설치&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;CDN을 이용한 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CDN(컨텐츠 전송 네트워크)로 제공하는 라이브러리를 직접 가져오는 방식&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;script src=&quot;https://unpkg.com/react@16/umd/react.development.js&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;직접 다운&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;NMP을 이용한 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NMP 저장소에서 찾아 우리 프로젝트로 다운로드 하는 명령어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;package.json에 설치한 패키지 정보 기록&lt;/p&gt;
&lt;pre class=&quot;cmake&quot;&gt;&lt;code&gt;npm install&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;유의적 버전&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트에 사용하는 버전 번호를 관리하기 위한 규칙&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유의적 버전은 주(Major), 부(Minor), 수(Patch) 세 가지 숫자를 조합해서 버전을 관리한다. 위에 설치한 react의 버전은 v16.12.0인데 주 버전이 16, 부 버전이 12, 수 버전이 0인 셈이다.&lt;/p&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;주 버전(Major Version): 기존 버전과 호환되지 않게 변경한 경우&lt;/li&gt;
&lt;li&gt;부 버전(Minor version): 기존 버전과 호환되면서 기능이 추가된 경우&lt;/li&gt;
&lt;li&gt;수 버전(Patch version): 기존 버전과 호환되면서 버그를 수정한 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://docs.npmjs.com/cli/v6/using-npm/semver#tilde-ranges-123-12-1&quot;&gt;틸트(~)&lt;/a&gt;&lt;/b&gt; 는 마이너 버전이 명시되어 있으면 패치버전만 변경한다. 예를 들어 ~1.2.3 표기는 1.2.3 부터 1.3.0 미만 까지를 포함한다. 마이너 버전이 없으면 마이너 버전을 갱신한다. ~0 표기는 0.0.0부터 1.0.0 미만 까지를 포함한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://docs.npmjs.com/cli/v6/using-npm/semver#caret-ranges-123-025-004&quot;&gt;캐럿(^)&lt;/a&gt;&lt;/b&gt; 은 정식버전에서 마이너와 패치 버전을 변경한다. 예를 들어 ^1.2.3 표기는 1.2.3부터 2.0.0 미만 까지를 포함한다. 정식버전 미만인 0.x 버전은 패치만 갱신한다. ^0 표기는 0.0.0부터 0.1.0 미만 까지를 포함한다.&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://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1654284895550&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&quot; data-og-description=&quot;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; data-og-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bBw2Yi/hyOEmeyXX8/hmm4KcVT6ufj3zUL1Dnox0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/glOgZ/hyOEgyE9Dv/IBNWlfJfQ4e9HUxSgx1df1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/WGJ5T/hyOCD96WNV/7mIWkRoU7Agg0gOGZvetS0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD/dashboard&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bBw2Yi/hyOEmeyXX8/hmm4KcVT6ufj3zUL1Dnox0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/glOgZ/hyOEgyE9Dv/IBNWlfJfQ4e9HUxSgx1df1/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/WGJ5T/hyOCD96WNV/7mIWkRoU7Agg0gOGZvetS0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500');&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;프론트엔드 개발환경의 이해와 실습 (webpack, babel, eslint..) - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이미 만들어 놓은 개발 환경을 이해할 수 있어요. 처음부터 직접 개발 환경을 만들 수 있어요., - 강의 소개 | 인프런...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/webpack</category>
      <category>package.json</category>
      <author>MG_conny</author>
      <guid isPermaLink="true">https://mugon-devlog.tistory.com/103</guid>
      <comments>https://mugon-devlog.tistory.com/103#entry103comment</comments>
      <pubDate>Sat, 4 Jun 2022 04:23:45 +0900</pubDate>
    </item>
  </channel>
</rss>