본문 바로가기

프론트엔드/기타

프론트엔드 개발환경의 이해 (상) - npm, 웹팩

 

참고 강좌 - [김정환] 프론트엔드 개발환경 이해

www.youtube.com/playlist?list=PL9mhQYIlKEhcQStzo0dQiBThjwU8TroCt

 

토크ON 68차. 프론트엔드 개발환경 이해 | T아카데미

T아카데미 온라인 강의- [토크ON세미나] 프론트엔드 개발환경 이해 (총8강) ▶ https://tacademy.skplanet.com/live/player/onlineLectureDetail.action?seq=174 [과정 소개] 이번 강의에서는 NPM 프로젝트와 모듈 시스템

www.youtube.com


1. 프론트엔드에서 node.js의 필요성

1) 최신 스펙으로 개발

 - 바벨, 웹팩, npm과 같은 노드 기반 개발환경은 typescript, SASS/SCSS 등의 고수준 프로그래밍 언어에 적합한 트랜스파일러 제공.

 

2) 빌드 자동화

 - 파일 압축, 코드 난독화, 폴리필 추가 등의 빌드 과정을 자동화.

 - 라이브러리 의존성 해결 (npm의 라이브러리 관리)

 

3) 개발환경 커스터마이징

 - 기술을 이해하면 상황에 맞게 웹팩을 뜯어 개발환경 커스터마이징 가능.

 


2. NPM, node package manager

 - node진영의 js 라이브러리 및 프로젝트 관리 툴

1) npm init 

 - 프로젝트 생성 및 초기화 

 - 패키지명, 버전, 설명, git 저장소, licencse 옵션을 등을 설정할 수 있음 

 - npm init -y : 모두 디폴트 값으로 생성

 - 기본 정보가 기록된 package.json 파일이 생성됨

 

2) package.json

 - 프로젝트의 정보 기록 ( 참조 : programmingsummaries.tistory.com/385 )

 - name, version, description, scripts(프로젝트 명령어), devDependencies (개발 단계에서만 필요한 모듈),

   dependencies (프로젝트 운영에 필요한 모듈), author(프로그램 작성자), license 등

 

3) 프로젝트 명령어

 - 프로젝트의 빌드, 테스트, 배포, 실행 등을 수행하는 명령어

 - package.json의 scripts 부분에 등록해서 사용

예약된 npm 명령어들

 - 주로 사용하는 명령어 : start, test, install, uninstall 

 - 커스텀 명령어 등록 및 사용 가능. 이때 커스텀 명령어 실행은 npm run [명령어]

 - 프론트엔드 환경에서 추가 권장 스크립트 build(소스 빌드), lint(코딩 컨벤션 검사)

 

4) 패키지(라이브러리) 관리

 - npm 패키지 홈페이지 www.npmjs.com/

 - CDN 말고!(서버 장애 취약) 직접 코드 다운로드 말고!(버전 관리 불가능) 라이브러리 관리를 용이하게 함

 - 다운로드 : npm install [패키지명] | 삭제 npm uninstall [패키지명]

 

 


3. Webpack(웹팩) 기초

1) 기존의 모듈 사용법

 - 고전적인 모듈 사용법 : 무분별한 글로벌 스코프 오염을 방지하고자 IIFE(즉시실행함수)로 스코프를 만들어 모듈 구현.

 - CommonJS : export와 require

 - ES6 표준 모듈 시스템 : exportimport (익스플로러 미지원, 크롬 브라우저 script태그에 type="module" 명시 필요)

 

2) 웹팩의 등장 (엔트리/아웃풋)

 - 여러 개의 파일을 하나의 파일로 합쳐주는 번들러(bundler)

 - 모듈 시스템을 지원하지 않는 브라우저도 웹팩으로 말아놓은 모듈 사용 가능

 - 엔트리(시작점)를 지정하면 그로부터 모든 의존적인 모듈들(import 해온 애들)을 찾아 하나의 아웃풋(결과물)을 만들어 줌

 

3) 웹팩 사용

 ① 웹팩 패키지(webpack), 웹팩 터미널 도구(webpack-cli) 설치 

npm install -D webpack webpack-cli
// npm install --save-dev webpack webpack-cli

install 옵션 중 -D 또는 --save-dev 를 주면 운영용 dependencies가 아니라 개발용 devDependencies로 들어감

(개발용 라이브러리를 설치한다면 필히 명시해서 운영용 어플을 가볍게 해주자)

 

 ② 웹팩 명령어 보기

겁나 많이 뜬다. --mode, --entry, --output 세 옵션만 기억하자

node_modules/.bin/webpack --help

 

 ③ 웹팩으로 번들링 하기 (아웃풋 만들기)

node_modules/.bin/webpack --mode development --entry ./src/app.js --output dist/main.js
//node_modules/.bin/webpack --mode development --entry ./src/app.js --output-path dist/main.js

mode : 웹팩 실행 모드 설정 (개발 버전은 development, 운영 버전은 production)

entry : 시작점이 될 파일 지정. 이 파일에서부터 import를 따라간다.

output : 번들링 된 파일이 생성될 위치와 이름. 보통 dist 폴더 안에 넣어줌.

※ 에러 관련 추가 내용

더보기

1. webpack 버전에 따라 [webpack-cli] Unknown argument: --output 에러 발생. 이때는 --output-path 사용.

 

2. node_modules 커맨드 입력 시 권한 문제로 다음과 같은 에러가 발생하면

관리자 권한으로 vscode를 실행한 뒤 터미널에 Set-ExecutionPolicy RemoteSigned 입력. 권한을 바꾸면 해결됨.
( Get-ExecutionPolicy : 현재 권한 확인)

 

 ④ 또는 webpack.config.js 파일을 사용해 번들링 하고 스크립트 명령어 등록하기

 프로젝트 최상단에 webpack.config.js 파일을 생성하고 다음의 내용을 입력

const path = require("path");

module.exports = {
    mode: "development",
    entry: {
        main: "./src/app.js"
    },
    output: {
        filename: "[name].js",
        path: path.resolve("./dist")
    }
}

 package.json의 scripts 부분에 웹팩을 빌드하는 커스텀 명령어 추가

(명령어는 꼭 build를 쓰지 않아도 됨. hellhello같은거 등록해도 되긴 된다...)

※ build : "webpack --progress" 옵션을 주면 빌드 과정을 보여줌

 


4. 웹팩과 로더

 - 웹팩을 사용한다는 건 곧 모든 파일을 모듈로 본다는 것. 이때 js, 스타일시트, 이미지, 폰트 등 모든 파일이 로더를 거쳐 모듈화

 

1) 로더의 기본 동작 원리

  로더 파일을 생성, 원하는 패턴을 지정 후 webpack.config.js의 module 객체에 rule 추가

  test : 로더를 거쳐갈 파일을 지정. (정규표현식 사용)

  use : 생성한 로더 파일(들)을 매핑

로더에 옵션을 지정해야 하면 use 대신 loader로 단일 지정

 

2) css 파일 로딩하기

 css-loader(js코드로 변경), style-loader(DOM에 적용) 함께 사용해야 함.

npm install -D css-loader
npm install -D style-loader

웹팩 config 파일에 module 설정 추가

배열로 설정하는 로더는 뒤에서부터 동작함. css-loader가 적용된 뒤 style-loader가 실행되도록 배치

 

3) file 로딩하기

이미지 파일 등을 가져오기 위해 file-loader 필요

npm install -D file-loader

 

[name] 파일명 [ext] 확장자명 [hash] 쿼리스트링 해시값

 

4) url-loader

이미지 파일의 개수가 증가하면 네트워크 리소스와 성능 문제 발생.

페이지 안에서 작은 이미지 파일을 여러 개 사용할 경우 이미지를 Base64로 인코딩해 문자열 형태로 넣어주는 Data URI Scheme를 이용하는 것을 권장하며 url-loader를 이용해 이를 자동화할 수 있음. 

npm install -D url-loader

 

url-loader는 file-loader를 내장하고 있으며 limit값에 따라 file-loader나 url-loader가 동작하게 됨

 


5. 웹팩과 플러그인

 - 번들링 된 아웃풋 난독화, 공백 삭제 등 후처리를 담당. 

 

1) 플러그인의 기본 동작 원리

  플러그인 파일을 생성, 원하는 클래스를 정의한 뒤 webpack.config.js에서 require해와 plugins 배열에서 생성

좌 : myplugins.js / 우 : webpack.config.js 

번들된 결과 코드 가져오기 : apply 메서드의 compiler 인자의 plugin 함수의 emit 이벤트의 complication 인자에 접근

apply(compiler){
	compiler.plugin("emit", (complication, callback)=>{
		const source = compilation.assets['main.js'].source();
		console.log(source);
		callback();
    }
}

 

 

2) BannerPlugin

 - 번들된 결과물에 배너 추가 (빌드 정보, 커밋 버전 등).

 - webpack이 기본적으로 제공하는 플러그인. webpack.config.js 파일에 커스텀 플러그인 파일 대신 웹팩을 가져와 사용

 

① 텍스트 전달

좌 : webpack.config.js 플러그인에 텍스트 배너 등록 / 우: 번들된 결과

 

② 함수형 전달

좌 : webpack.config.js 플러그인에 함수형 배너 등록 / 우: 번들된 결과

 

 

③ 커스텀 배너 파일 전달

좌 : 커스텀 배너파일 생성 / 중 : webpack.config.js 플러그인에 배너파일 require 후 등록   / 우 : 번들된 결과 

 

3) DefinePlugin

 - 프로젝트는 개발환경, 운영환경을 분리해서 관리함

 - API 주소는 환경에 따라 다를 수 있음.

 - 이런 빌드 타임 의존적인 정보를 소스 대신 플러그인에서 관리하면 배포할 때마다 코드를 수정하지 않아도 됨

 - webpack이 기본적으로 제공하는 플러그인. webpack.config.js 파일에 커스텀 플러그인 파일 대신 웹팩을 가져와 사용

 - 다음과 같이 디파인 플러그인에서 api 도메인 주소를 전달하고 app.js에서 받을 수 있다.

webpack.config.js 플러그인에 디파인 플러그인 등록 
좌 : app.js 에서 디파인 플러그인으로부터 전달받은 값을 출력 / 우 : 결과

디파인 플러그인에 빈 객체를 전달해도 new webpack.DefinePlugin({})

노드 환경정보인 process.env.NODE_ENV기본적으로 넣어줌

 

 

4) HtmlWebpackPlugin

 - html 파일도 웹팩으로 번들링 해버릴 때 후처리 하는 플러그인

 - webpack 내장이 아닌 서드파티 플러그인이라 설치 필요

npm install -D html-webpack-plugin

 

① index.html 파일을 src 폴더 밑으로 옮긴 후 내용 수정. 

 기존에 번들된 main.js 파일을 하드코딩으로 가져오던 script 태그를 주석처리하고, ejs 문법으로 탬플릿에 인자 추가.

 

 webpack.config.js에 html 플러그인을 가져와 내용 정의.

index.html 파일에서 인자로 받은 env 파라미터를 여기서 넣어줌.

minify : 파일의 용량을 줄이기 위한 설정들 (공백, 주석 제거 등)

 

 NODE_ENV를 지정해 빌드

NODE_ENV=production npm run build

 

④ 결과 확인

dist에 생성된 index.html 아웃풋 파일. <%= env %>가 production으로 바뀌고, minify가 적용되어 공백과 주석이 모두 사라짐
index.html을 띄운 모습

 

※ 에러 관련 추가 내용

더보기

NODE_ENV=~~ 옵션은 맥 전용 터미널 명령어라 윈도우환경에서 다음과 같은 에러를 발생

 

해결방안

1) cross-env 설치 후 cross-env를 이용해 빌드

npm install -D cross-env

 

cross-env NODE_ENV=production npm run build

 

그러나 이번에는 cross-env가 말썽. package.json을 확인하면 제대로 설치도 되었는데 왜 이러는지 모르겠음;

환경변수 관련 문제인 듯한데 해결책을 찾다 다른 방안을 찾음.

 

2) $env:NODE_ENV="production" 으로 세팅 후 빌드

 $env:NODE_ENV="production" 
 npm run build

 

문제 해결

 

 

5) CleanWebpackPlugin

 - 빌드 이전 결과물을 제거. 덮어쓰이지 않아서 남아있는 불필요한 파일을 모두 삭제해줌.

 - webpack 내장이 아닌 서드파티 플러그인이라 설치 필요.

npm install -D clean-webpack-plugin

webpack.config.js에서 가져와 플러그인에 추가

 

 

6) MiniCssExtractPlugin

 - css내용이 많아지면 하나의 js 결과물에 포함시키기에 부적합.

 - 스타일 시트 코드만 뽑아 별도의 css 파일 아웃풋을 만들어 분리.

 - 개발환경보다 운영용으로 배포할 때 사용.

 - webpack 내장이 아닌 서드파티 플러그인이라 설치 필요.

npm install -D mini-css-extract-plugin

 

webpack.config.js에서 가져와 플러그인에 추가

이 때 css파일에 대한 로더를 적용했던 부분도 (rules 영역)

환경에 따라 개발용, 운영용 로더를 다르게 적용시킬 수 있도록 함께 수정

 

config 파일도 길어지면 안에서 분기처리를 하는 것 보다 아예 개발용, 배표용 파일로 분리하는걸 권장