참고 강좌 - [김정환] 프론트엔드 개발환경 이해
www.youtube.com/playlist?list=PL9mhQYIlKEhcQStzo0dQiBThjwU8TroCt
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 부분에 등록해서 사용
- 주로 사용하는 명령어 : 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 표준 모듈 시스템 : export와 import (익스플로러 미지원, 크롬 브라우저 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 배열에서 생성
번들된 결과 코드 가져오기 : 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 파일에 커스텀 플러그인 파일 대신 웹팩을 가져와 사용
① 텍스트 전달
② 함수형 전달
③ 커스텀 배너 파일 전달
3) DefinePlugin
- 프로젝트는 개발환경, 운영환경을 분리해서 관리함
- API 주소는 환경에 따라 다를 수 있음.
- 이런 빌드 타임 의존적인 정보를 소스 대신 플러그인에서 관리하면 배포할 때마다 코드를 수정하지 않아도 됨
- webpack이 기본적으로 제공하는 플러그인. webpack.config.js 파일에 커스텀 플러그인 파일 대신 웹팩을 가져와 사용
- 다음과 같이 디파인 플러그인에서 api 도메인 주소를 전달하고 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
④ 결과 확인
※ 에러 관련 추가 내용
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 파일도 길어지면 안에서 분기처리를 하는 것 보다 아예 개발용, 배표용 파일로 분리하는걸 권장
'프론트엔드 > 기타' 카테고리의 다른 글
[git] 브랜치 네이밍, 웹호스팅 (0) | 2020.12.22 |
---|---|
vscode에 git 연동해 사용하기 (0) | 2020.11.20 |
프론트엔드 개발환경의 이해 (중) - 바벨, 린트 (0) | 2020.11.16 |
[javascript] 객체지향 - 함수&프로토타입과 클래스 (0) | 2020.11.09 |
[javascript] 저장용 (0) | 2020.09.17 |