개발/node.js

[npm] webpack 셋팅

smile-haha 2023. 1. 20. 13:43
반응형

webpack은 여러 파일(js,css,html 등)을 하나의 파일로 묶어주는 모듈이다.

 

webpack을 이용하기 위해서는 일단 터미널에서 webpack을 이용할 프로젝트 폴더로 이동해서,

npm이나 yarn 을이용해 webpack 모듈을 설치한다.

(npm은 nodeJS를 설치하면서 같이 설치되며, yarn은 npm 설치후,  "npm install -g yarn" 명령어로 설치한다.)

※ -g는 global 옵션으로 설치할 모듈을 프로젝트가 아닌 시스템의 node_modules 폴더에 설치한다.

   터미널을 통해 명령어를 날리기 위해서는 -g 옵션이 필요하다.

$npm insatll -g webpack webpack-cli
$yarn global add webpack webpack-cli

설치 후 webpack 명령어를 날리면 아래와 같이 뭔가 동작합니다. 저는 빈 프로젝트 폴더에서 해당 명령어를 날려서 src 폴더도 없고 webpack.config.js 파일도 없는 상태에서 webpack 명령어를 날리니 아래와 같이 파일들이 없다고 에러가 나네요ㅎㅎ

이렇게 설치하면 이제 root 폴더에 webpack.config.js 파일을 만듭니다.

 

기본 구조는 다음과 같습니다.

/*webpack.config.js*/
module.exports = {
  entry: './src/index.js'
};

위와같이 module.exports에 webpack에 필요한 설정들을 정의하는 것입니다.

 

🎃entry

entry는 파일을 묶을때 첫 시작점입니다. entry 파일에서부터 시작해서 거기서 import한 파일들을 타고 들어가 모두 묶어 내보냅니다.

 

root 폴더에 src 폴더를 만들고 index.js 파일을 추가합니다. 

저는 index.js에서 아래와 같이 ColorPickerContrloller js를 임포트 해서 거기 안에 있는 ColorPickerController 클래스를 export합니다. 그리고 alert을 하나 추가했습니다.

/*index.js*/
import ColorPickerController from './controllers/ColorPickerController';

alert("헤헷");

export { ColorPickerController };

 controllers폴더에 ColockPickerController.js도 생성해서 빈 클래스를 만들었습니다.

/*ColorPickerController.js*/
class ColorPickerController {
    constructor(target,color){
        /*리액트로 컬러피커를 target element에 생성하는 소스 */
    }
}

export default ColorPickerController;

여기까지만 만들고 webpack 명령어를 날려봅니다.

$webpack

 

일단 mode 값을 설정하지 않았다고 워닝이 뜨네요!

 

🎃 mode

mode 값은 개발 모드(development)로 소스를 말 것인지, 배포용(production)으로 소스를 말 것인지에 대한 옵션입니다. 선택한 옵션에 따라 webpack이 내장의 최적화를 사용하도록 합니다.

mode
'production' 배포모드(기본값) 번들링된(묶인) 용량이 적음
'development' 개발모드  
'none' 기본 최적화 옵션 설정 해제  

저는 일단 'development'로 설정했습니다.

/*webpack.config.js*/
module.exports = {
  entry: './src/index.js'
  mode: 'development'
};

그리고 터미널에 webpack 명령어 실행을 하니, 아래처럼 webpack module를 찾지 못했다고 에러가 뜹니다.

분명히 -g 옵션을 줘서 webpack 모듈을 설치했는데 말이죠... 그래서 이번에는 -D옵션을 줘서 해당 프로젝트 내 node_modules 폴더에 webpack 모듈을 설치합니다.

$npm install -D webpack

그리고 webpack 명령어를 다시 날리면, webpack 명령어가 실행됨을 확인 할 수 있습니다.

그럼 이제 root 폴더 아래 dist 폴더가 생기고, 그 안에 main.js라는 파일이 생깁니다.  export 되는 파일의 파일명 기본값이 main.js인가 봅니다. 아래에서 다룰 output.filename 속성을 주면 export할 파일의 파일명을 설정할 수 있습니다.

해당 파일을 html에서 불러와서 한번 확인해 보았습니다.

 

정상적으로 import 되었으니 alert 창은 실행됩니다. 하지만 index.js에서 export 했던 ColorPickerController에는 어떻게 접근할까요? 현재는 접근 불가능하고, 이것은 output.libary 속성에서 설정할 수 있습니다. 이것은 아래에서 더 살펴보겠습니다.

 

🎃 output

output 속성은 번들(export 파일)이 어떤 방식으로, 어디에 export 될지에 대한 정보를 정의를 합니다.

output 속성으로는 정말 다양한 것들이 있는데, 저는 제가 필요한 정보만 정의하겠습니다. 나머지는 webpack 사이트에 들어가서 확인하세요.

 

Output | webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

/*webpack.config.js*/
const path = require('path');

module.exports = {
  ...
  output : {
    path : path.resolve(__dirname, 'dist'),//export 경로
    filename: 'bundle.js',//export 파일명
    library : {
      name : "haModule",// 라이브러리 객체 이름
      type : 'window' ,//window.hjModule로 접근가능
    },
    auxiliaryComment : "made by ha",// 라이브러리 주석(선택)
  },
};

※ 여기서 __dirname 은 현재 실행 중인 폴더 경로를 의미하며, path는 node.js에서 제공하는 경로 관련 모듈입니다. 

    path.resolve(_dirname,'dist')는 그럼 현재 실행중인 파일(webpack.config.js)의 폴더 root에 있는 dist 폴더에 exprot 파일을 만든다는 거죠.

여기서 library는 entry에서 export한 객체를 노출하는 형태로 만들겠다는 것입니다.

library.name은 노출될 라이브러리 객체 이름, library.type은 라이브러리를 어떻게 노출시킬 것인지 정의합니다.

library.type에는 var, module, assign, assign-properties, this, window, self, global, commonjs, commonjs2, commonjs-module,commonjs-static, amd, amd-require, umd, umd2, jsonp, system 과같은 값을 설정할 수 있으나, 저는 window에서 바로 접근해 사용하길 바래서 window를 값으로 설정했습니다. 다른 속성이 궁금하다면 webpack 사이트를 참고하세요.

 

Output | webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

이제 다시 webpack 명령어로 프로젝트를 번들링하고, html에서 불러와 보았습니다. 아래와 같이 console에서 바로 접근 가능합니다.

 

 

🎃 devtool

devtool은 개발시 디버깅 편의를 위해 설정하면 좋은 속성이다. 보통 번들링시 변수명을 알아보기 어렵게 바꾸고 공백을 제거하고 주석을 제거하는 등 작업을 하는데, 여기서 sourcemap을 설정하면, 디버깅 할 때는 개발했던 변수명대로, 공백 넣어진 채로 볼 수 있어 디버깅이 편해진다. 보통 개발 모드에서는 eval 옵션을 사용한다.

 

🎃 devServer

devServer는 개발시에 아주 유용하다. 이 속성을 이용해서 개발서버를 실행시킨다. 프로젝트 소스를 수정하면 곧바로 개발서버에 반영된다. devServer를 사용하기 위해서는 webpack-dev-server를 설치해야한다.

$npm install webpack-dev-server
/*webpack.config.js*/
const path = require('path');

module.exports = {
  ...
  devServer: {
    static: {//공용 디렉토리에서 정적 파일을 제공하기 위한 옵션, 비활성화시 false
      directory: path.join(__dirname, 'public'),//콘텐츠를 제공할 위치
    },
    port: 9090,// devServer에 연결된 클라이언트에게 제공된 포트를 사용하도록 지시
    client: {
      logging: 'info',//로그 기록 수준('log' | 'info' | 'warn' | 'error' | 'none' | 'verbose')
    },
  },
};

상세한 설정은 webpack 홈페이지에서 보자.

 

DevServer | webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

그리고 수정 즉시 적용되는 개발서버를 키는 것은 아래 명령어를 통해 가능하다.

$webpack serve

정상적으로 실행된다면 위와같이 맨 마지막 줄에 successfully in ~ms 라고 뜬다.

그럼 브라우저에서 locallhost:9090에 접근하면 아래와 같이 canot get이라고 뜬다.

저는 root 폴더에 index.html을 추가해서 해당 html에 제가 만든 라이브러리를 import 해서 테스트 하고자 합니다.

그래서 html을 빌드 결과물에 추가하기 위해서 html-webpack-plugin을 설치하고 설정값을 입력합니다. root 폴더에 index.html을 생성하여 다음과 같이 기본 틀만 넣어 놓습니다. 

$npm install -D html-webpack-plugin
/*webpack.config.js*/
const path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
	entry : './src/index.js',
    ...
    plugins: [
        new HtmlWebpackPlugin({
          template: 'index.html',
        }),
    ],
}
<!--index.html-->
<!DOCTYPE html>
<html>
<head>
  <title>HJ WEBSERVER</title>
  <meta charset="utf-8" />
</head>
<body>
  <h1>Hello</h1>
  <div>
    <p>WELCOME!</p>
  </div>
</body>
</html>

이렇게 하고 다시 webpack serve 명령어로 개발서버를 재가동시킵니다. (dev server는 html이나 css, js가 변경될때는 자동으로 수정된 내용이 적용되지만, webpack.config.js 내용이 수정되면 재기동 해야 적용됩니다.)

 

다시 localhost:9090에 접속하면 아래와 같이 개발한 라이브러리가 자동으로 임포트된 index.html페이지가 열립니다.

 

이렇게 하면 js 라이브러리를 개발할 기본 준비가 되었습니다.

 

최종적으로 작성된 webpack.config.js 는 아래와 같습니다.

/*webpack.config.js*/
const path = require('path');
const webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/index.js',
    devServer: {
        static: {
            directory: path.join(__dirname, 'public'),
        },
    port: 9090,
    client: {
        logging: 'info',//'log' | 'info' | 'warn' | 'error' | 'none' | 'verbose'
        },
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js',
        library : {
            name : "haModule",
            type : 'window' ,
        },
        auxiliaryComment : "made by ha",
    },
    mode: 'development',//'production','development'
    devtool:'eval',
    plugins: [
        new HtmlWebpackPlugin({
            template: 'index.html',
        }),
    ],
};

 

반응형