본문 바로가기

WEB/Javascript

[JS] webpack - npm - node 다 다른거야? 예$쓰

node.js 은 크롬 V8 자바스크립트 엔진으로 생성된 자바스크립트 런타임이다.

npm은 node.js을 기반으로 JS으로 개발된 오픈소스를 모듈로 공유하는 곳이다. (파이썬의 pip과 비슷하다)

 

node.js의 Denpendency 을 살펴보면

도구(npm, gyp, gtest)와 라이브러리(V8,libuv,llhttp,c-ares,OpenSSL,zlib)이 있다.

node.js을 설치하면 npm 도 함께 설치된다.

 

webpack 은 자바스크립트 모듈들을 컴파일하는데 사용된다.

한번 설치하면 CLI또는 다른 API로 상호작용할 수 있다.

 

webpack으로 알아보기

(Node.js가 설치됨을 가정)

1.기본설치

우선 폴더하나를 만들고 그안에 npm을 초기화하여 로컬에 webpack과 webpack-cli을 설치해보자

mkdir folder-name
cd folder-name
npm init -y
npm install webpack webpack-cli --save-dev

npm init -y : npm init 만 명령하면 다른 많은 질문들이 따라오는데 -y사용함으로써 질문들을 생략해준다.

- 이후 아래와 같은 내용의 package.json 파일을 생성한다. 

package.json은 프로젝트 이름, 사용하는 모듈 , 버전 등을 나타내며 모듈의 의존성도 관리할 수 있다.

{
  "name": "folder-name",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

npm install webpack webpack-cli --save-dev :

npm install --save-dev : 패키지는 devDependencies에서 나타난다. 

devDependencies에 저장된 모듈은 설치되지 않는다. 만일 설치하고 싶으면 NODE_ENV 환경변수를 production으로  --production=false을 사용해 변경해야한다.

 

npm이 webpack과 webpack-cli 설치 후 아래와 같은 메세지를 남겼다.

added 117 packages, and audited 118 packages in 4s

15 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

4초안에 117개의 패키지가 추가되었고 118개의 패키지를 검사했다.

 

그중 15개의 패키지는 funding을 해야한다. 자세한 것은 npm fund으로 알아봐라

 

0개의 취약성

 

이렇게 기본 webpack과 webpck-cli의 설치를 마쳤다.

 

내가 만든 폴더안에 아래와 같은 파일들이 만들어졌다.

 

2. html과 js 추가하기

index.html을 폴더안에 만들고 index.js을 폴더안에 src 폴더 만든 후 src안에 만든다.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Getting Started</title>
    <script src="https://unpkg.com/lodash@4.17.20"></script>
  </head>
  <body>
    <script src="./src/index.js"></script>
  </body>
</html>

 

주목해야할 것은 script 이다. 라이브러리 lodash가 아직 로컬패키지에 없기 때문에 링크로 불러왔다.

 

index.html 안에 <script>태그를 살펴보면 index.js가 lodash 안에 종속된다.

그러면 아래 index.js 은 실행되기전에 lodash에 의존(종속)되어서 글로벌 변수 _ 가 존재하므로 lodash을 명시적으로 선언할 수 없게된다.

function component() {
  const element = document.createElement('div');

  // Lodash, currently included via a script, is required for this line to work
  element.innerHTML = _.join(['Hello', 'webpack'], ' ');

  return element;
}

document.body.appendChild(component());

이렇게 되면 여러가지 문제가 발생할 수 있다.

 

1) 스크립트가 외부의 라이브러리에 의존한다는 사실을 바로 알지 못한다.

2) dependency의존성(종족성)이 사라지거나 잘못된 명령어가 포함된 경우 애플리케이션은 제대로 작동하지 않는다.

3) dependency가 포함되었으나 사용되지 않는다면 브라우저는 불필요한 코드를 다운받게 된다.

 

Webpack을 이용하여 관리해보자

 

* pacakge.json 에서 "main" :"index.js" 을 지우고 "private":true 을 작성하자

 

3. Bundle 생성하기

 

우리의 디렉토리를 숯치기위해서는 "source" (./src) 와 "distribution" (./dist)을 찢어두는 것이 좋다.

"soucre"은 우리가 쓰고 수정하는 코드들이고  "distribution"은 최종적으로 우리가 브라우저에 로드할 output으로 최적화되는 코드이다.

 

디렉토리에 dist폴더를 만들어서 index.html파일을 옯겨둔다.

 

index.js에서 lodash을 사용하기 위해서 번들로 묶어두기 위해 npm을 이용해 설치한다.

added 1 package, and audited 119 packages in 396ms

15 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

위의 메세지와 함께  lodash가 추가되었다.

 

이제는 index.js에서 호출하고 html에서 종족성을 지우자

import _ from 'lodash'

function component() {
  const element = document.createElement('div');

  // Lodash, currently included via a script, is required for this line to work
  element.innerHTML = _.join(['Hello', 'webpack'], ' ');

  return element;
}

document.body.appendChild(component());

다음으로 스크립트를 번들링할 것이기 때문에 우리의 html을 수정한다.

lodash을 불러오는 스크립트를 삭제하고

./src파일 아래있는 스크립트가 아닌 다른 스크립트로 번들링한다.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Getting Started</title>
    <!-- <script src="https://unpkg.com/lodash@4.17.20"></script>-->
  </head>
  <body>
   <!-- <script src="./src/index.js"></script>-->
   <script src="main.js"></script>
  </body>
</html>

 

이렇게 마치면 index.js은 lodash을 명시적으로 선언할 수 있고 글로벌변수_에 사용할 수 있다.

모듈이 어떤 dependency가 필요한지 명시함으로써 webpack은 dependency graph을 만드는데 사용한다.

만들어진 그래프는 후에 스크립트가 정확한 순서로 실행되는 최적화된 번들이 만들어지는데 사용된다.

 

이제는 npx webpack을 사용하자. npx을 사용하는 것은 우리의 index.js을 entry point로써 사용하고 output로써 main.js을 dist폴더 안에 생성한다. npx은 webpack 초기에  설치한 웹팩 케키지의 바이너리를 실행한다. 

npx webpack 이후 생성된 entry point /output

위처럼 로컬 주소를 보면 html파일이 dist안에 생성되었다.

 

4. configuration을 사용하기 

버전 4 이상부터는 더이상 configuration을 요구 하지만 대게 프로젝트는 복잡한 설정을 요구한다. 그래서 webpack이  configuration을 지원한다.

한번 해보자

우선 build을 실행해보자 

 

하지만 나는 오류가 발생한다. 

'webpack.config.js'파일이 없기 때문이다. 

 

-해결

아래와 같은 파일을 만들어준다. 파일이 없으면 만들면 되지!

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist'),
  },
};

webpack.config.js

이후

npx webpack --config webpack.config.js

을 실행하면 아래와 같은 메세지를 받는다.

loader rules 나 plugins나 resolve의 옵션등 다양한 것을 여기서 향상 시킬 수 있다.

 

5.npm scirpts

package.json에서 "build" :"webpack"으로 설정하고 

npm run build 을 실행해보자

아래와 같은 메세지와 함께 완료되었다.