미완성 | 입맛대로 공부하며 정리중(공부가 목적이므로 환경설정 가이드 라인이 아님) |
<작성순서>
<들어가기 전> 번들링의 필요성
0. npm init 으로 package.json 파일 생성하기
1. webpack 설치 "의존성 패키지들을 하나의 코드로 압축해주는 유명 번들러 중의 하나"
2. webpack.config.js "웹팩의 부수적인 기능 설정을 위한 파일"
3. entry , output "의존성의 시작점과 번들 파일이 생성될 경로"
4. package.json 의 script 속성에 웹팩 실행 빌드 명령어 만들기
5. [터미널] - npm run build 입력해서 웹팩 실행하기
6. HTMLWebpackPlugin 설치 후 설정 "자동으로 번들 파일이 스크립트로 첨부된 html 파일 생성해준다"
7. webpack-dev-server "개발 환경에서만 사용하는 임시 서버 "
8. Loader "css , 이미지 등의 파일을 자바스크립트 코드로 변환시켜 주는 옵션"
9. MiniCssExtractPlugin(css 파일 별도 분리) 과 CleanWebpackPlugin(이전 빌드 자료 모두 제거)
<들어가기 전>번들링의 필요성
개발을 하다보면 하나의 js 파일에서 다른 여러 js 파일로 특정한 변수나 함수를 전달하여 사용해야 하는 경우가 많다. 또한 화면을 구성하는데 필요로 하는 다양한 이미지 파일이나 영상과, css 파일 또한 넘쳐난다.
코드의 재사용성이 높은 경우에도 각 js 파일 간의 코드를 모듈화하여 전달하기도 하는데 ,이렇게 활용되는 모든 파일을 모듈이라 한다. 그래서 모듈이라 하면 html, css, img, font, js 등의 모든 파일이 해당한다고 볼 수 있다.
이러한 모듈의 존재는 코드의 재사용성을 높일 수 있다는 점에서는 큰 장점이고, 규모가 작아서 적은 모듈을 생성하는 프로젝트라면 상관이 없지만, 프로젝트의 규모가 커지게 되면 모듈의 규모 또한 무시못할 정도로 커지게 된다.
일반적으로 웹 페이지에 사용자가 접속하면, 웹 페이지 구성에 필요한 모든 파일을 브라우저에 전달하게 되고, 이것이 화면에 그려지면서 사용자는 웹 화면을 볼 수 있게 된다. 하지만, 앞서 무시못할 정도의 모듈이 화면에 그려지기 위해서는 무수히 많은 네트워크 요청이 있을 것이고, 그 요청과 응답이 이루어지는 사이에 사용자는 웹 페이지에서 로딩바만 주구장창 보고 있게 된다. 즉, 사용자의 경험에 부정적인 영향을 주게 된다는 것이다.
사용자는 웹 페이지에 접속하고 단 5초 이내에 모든 것을 평가한다(5초도 많이 준거라 하더라). 그래서 그 이상의 시간을 초과하면 욕하고 나가버리는 경우가 많다. 그래서 이러한 네트워크 요청과 시간을 줄여서 웹 페이지 구현에 필요한 데이터를 전달하기 위해서 이 많은 모듈들을 하나의 파일로 압축할 필요성이 생겼고,
이를 위해 사용하게 된 것이 웹펙(webpack) 과 같은 모듈 번들러이다.
그리고 이러한 작업을 통해서 사용자는 적은 시간을 소요하여 필요로 하는 웹 페이지 정보를 볼 수 있게 된다.
webpack
" 의존성 패키지들의 코드를 하나로 묶어주는 유명한 번들러 중의 하나 "
0. npm init 으로 package.json 파일 생성하기 (설치 안 해도 웹팩 설치 시 딸려오긴 한다.)
npm init // 하나씩 설정가능
npm init -y // 기본 셋팅으로 일괄 설정
1. webpack 설치
웹펙은 npm install 하여 가져올 수 있다.
npm install -D webpack webpack-cli
// cli 은 프로젝트 구성에 필요로 하는 여러 CLI 명령어를 제공해준다.
// -D 는 package.json 에 비의존성 속성에 저장되어 프로젝트 배포 시 제외되도록 한다.
// 즉 -D는 개발시에만 활용하기 위한 목적으로 패키지를 설치하겠다는 것이다.
/*혹은 */
npm install --save-dev webpack webpack-cli // --save-dev 와 -D는 같은 의미이다.
위 설치를 통해서 가져오는 웹펙은 기본 셋팅이 되어 있는 상태인데, 이 외에도 별도의 필요한 기능을 사용하기 위해서 추가적인 설정이 필요하다. 그리고 이 설정을 위해 사용하는 파일이 webpack.config.js 이다.
2. webpack.config.js " 웹팩에서 이외 부수적으로 필요한 기능을 설정하기 위한 파일"
앞서 말했듯 이 파일은 웹펙의 기본설정 이외에 부수적인 기능을 추가하는 데 사용하는 파일이다.
webpack 은 모든 것을 모듈(js, css, png, jpg, sass 등등)로 다룬다. 그리고 그 모듈 간에는 의존성이 존재하며, 이러한 의존성에는 시작점이 존재한다. 그리고 시작점을 entry 라 한다.
3. entry , output
1) entry
앞서 entry는 모든 모듈의 의존성이 시작되는 시작점이라 하였다. 즉, entry 에 정의된 파일을 기준으로 여러 모듈(파일)을 분석하고 이들 간의 의존성 그래프를 작성하고, 이 그래프를 바탕으로 파일들을 모듈형태로 엮어서 공통되거나 관련된 파일들은 하나의 파일로 만들어 주는 번들링 작업을 수행한다.
module.exports = {
entry: ".src/index.js" //entry : 모듈 간 의존성의 시작점이 되는 진입점(이를 기준으로 의존성 그래프가 만들어진다.)
//entry 의 경우 객체 리터럴 형식으로 여러 모듈.js를 진입점으로 설정할 수 있다.
/*entry : {
파일이름 : '/js 파일 경로'
파일이름 : '/js 파일 경로} */
}
의존성의 시작점이 있다면 나가는 출구도 있을 것이다. 이 출구를 output 이라 한다.
2) output
ouput 옵션을 설정하게 되면 번들링된 파일을 저장할 파일의 이름과 경로를 지정할 수 있다.
// output 에 path를 추가하려면 require로 우선 path 노드를 불러와야 한다.
const path = require('path')
module.exports = {
entry: ".src/index.js", //entry : 모듈 간 의존성의 시작점이 되는 진입점(이를 기준으로 의존성 그래프가 만들어진다.)
output : {
filename: 'main.js' // 번들링 후 생성될 파일의 이름을 main.js 로 명명하였다.
path : path.resolve(process.cwd(), 'dist' //생성된 파일이 저장될 경로로 현재 프로세스가 실행 중인 경로의 dist 폴더로 설정했다.
}
}
※ path.resolve() 와 process.cwd() , dist
------------------------------------------------
path. resolve() : ( ) 내 인자로 넘겨 받은 경로 정보를 취합해준다.
process.cwd() : 현재 프로세스 가 실행중인 경로를 의미한다. 이 외에도 현재 경로를 뜻하는 __dirname 을 사용할 수 있다.
dist : 해당 경로에 생성할 폴더이름을 의미한다. ( 이 폴더 안에 번들링된 파일 데이터가 저장된다.)
-----------------------------------------------------------
4. package.json 의 script 속성에 웹팩 실행 빌드 명령어 만들기
5. [터미널] - npm run build 입력해서 웹팩 실행하기
- 앞서 명명한 빌드 명령어를 입력하여 실행하면 webpack.config.js 의 output 속성에 지정한 path 경로의 dist 폴더가 생성된 것을 확인할 수 있다.
module.exports = {
entry: "./app.js", //entry : 모듈 간 의존성의 시작점이 되는 진입점(이를 기준으로 의존성 그래프가 만들어진다.)
output : {
filename: 'bundle.js' // 번들링 후 생성될 파일의 이름을 bundle.js 로 명명하였다.
path : path.resolve(process.cwd(), 'dist' //생성된 파일이 저장될 경로로 현재 프로세스가 실행 중인 경로에 위치한 dist로 설정했다.
}
}
6. HTMLWebpackPlugin 설치 후 설정 "자동으로 번들 파일이 스크립트로 첨부된 html 파일 생성해준다"
※ htmlwebpackplugin?
----------------------------------------------------
HTML 파일에서 번들링 결과로 생성된 번들 파일을 사용하려면 html 에서 일일이 <scirpt src = ""> 태그를 추가해야 한다. 하지만 번들링 하는 파일명이 hash 값(매번 바뀜)을 포함하거나 , 자주 파일명이 변경되는 경우 매번 스크립트 태그의 속성을 수정해야 하는 번거로움이 있다.
여기서 이러한 문제를 해결하기 위해 사용하는 플로그인이 바로 HTMLWebpacakPlugin 이다. 이 플로그인의 역할은 간단하다. 번들링 하는 파일(예시에서는 main.js )의 경로를 자동으로 스크립트에 추가 해주는 html 파일을 생성해주는 것이다.----------------------------------------------------
- 앞서 단계 까지만 한다면 js 파일만 dist 폴더에 추가된다. 실제 배포 시에는 html 파일이 같이 있어야 하므로 이를 자동으로 추가해주는 html webpack plugin 을 [터미널] 을 통해 설치한다.
npm i html-webpack-plugin
그 후 weapack.config.js 로 가서 설치한 플로그인을 require 매서드를 사용하여 가져온다. 그 후 속성으로 plugins 을 추가하고 값으로 [new HtmlWebpackPlugin()] 을 입력한다.
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry : './src/index.js', //모듈 간 의존성의 시작점
output : {
filename : 'main.js',
path : path.resolve(__dirname,'dist') //현재 경로 하위의 dist 폴더를 의미한다.
},
plugins : [new HtmlWebpackPlugin()]
}
다시 [터미널] 에 npm run build 하여 웹팩을 실행하면 dist 폴더에 main.js 가 스크립트된 index.html 파일이 생성된 것을 볼 수 있다.
Q. 그런데, 제가 작성한 html 파일이 아닌데요?
그렇다. 이대로만 한다면 기존에 작성한 html 파일이 아니라 새로 생성된 html 이 설정된다. 따라서 이러한 문제를 해결하기 위해 webpack.config.js 의 plugins : [new HTMLWebpackPlugin( 인자 )] 에서 ( ) 요 안에 인자 값으로 { template : 'index.html' } 을 넣어주면, 우리가 작성해온 html 파일의 내용을 참조하여 번들된 파일과 이어주는 HTML 파일을 생성해준다.
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry : './src/index.js', //모듈 간 의존성의 시작점
output : {
filename : 'main.js',
path : path.resolve(__dirname,'dist') //현재 경로 하위의 dist 폴더를 의미한다.
},
//template 으로 설정된 기본 html 파일의 내용을 참조하여 만든 새로운 HTML 파일을 생성하여 dist 폴더에 저장한다.
plugins : [new HtmlWebpackPlugin({'template':'index.html'})]
}
Q. 이렇게 하면 수정은 되는데, 수정할 때 마다 일일이 webpack 을 실행하고 새로고침해야 하나요??
그렇다. 이대로만 한다면 수정된 파일을 반영하기 위해서는 매번 webpack를 실행 후, 새로고침 까지 해줘야 수정한 내용을 볼 수 있다. 이러한 불편함 때문에 개발 시 필수불가결 하게 사용되는 것이 weapack-dev-server 이다 .
7. webpack-dev-server "개발 환경에서만 사용하는 임시 서버 "
앞서 언급 했듯이 webpack을 사용한 번들링된 결과를 확인하기 위해서는 매번 번들링 후 새로고침을 반복해야 한다. 이러한 문제는 개발 생산성에도 좋지 않기 때문에 webpack 에서는 개발 환경에서 사용할 수 있는 간단한 서버를 제공한다.
1) 설치하기
npm install -D webpack-dev-server
2) 실행하기
개발 서버를 CLI로 구동하기 위해서는 명령어 패키지가 설치된 node_module/.bin/webpack 을 기준으로 해서 명령어를 실행해야 한다. 매번 설치한 경로를 기준으로 서버를 실행하는 것은 까다롭기 떄문에, package.json의 script 속성에 새로운 커스텀 명령어를 추가해서 사용하는 것이 좋다.
또한 이 서버는 개발환경에서만 사용할 수 있기 때문에 서버 오픈 시 mode 옵션을 development 로 설정해야 경고 및 에러가 뜨지 않는다. 물론 설정하지 않아도 서버는 작동한다. 그리고 기본 옵션은 프로덕션으로 기본 설정된다.
또한 현재 build 옵션을 보면 webpack 만 적혀 있는 것을 볼 수 있는데, 아무런 설정 없이 서버를 연 상태에서 웹팩을 실행하게 되면 다음 경고 문구를 볼 수 있다.
WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' f
or this value.
Set 'mode' option to 'development' or 'production' to enable defaults for e
ach environment.
이 문구을 파파고에게 의뢰하면 'Mode' 옵션이 설정되지 않았습니다. 웹 팩이 'production'으로 되돌아갑니다. 또는 이 갑의 'mode' 옵션을 'development' 또는 'production'으로 설정하라고 전달 받을 수 있다.
즉, 모드 옵션을 설정하지 않으면 기본 옵션으로 프로덕션이 된다는 말이다.
따라서, 이 경고 문구를 보고 싶지 않다면 웹팩 실행 전에 기본 옵션으로 mode 를 production 이나 development 로 설정하면 된다. 보통 웹팩을 빌드할 때는 production 을 기본 값으로 설정하므로 production 을 설정 하였다.
"scripts": {
"build": "webpack --mode=production",
"test": "echo \"Error: no test specified\" && exit 1",
"serve" : "webpack serve --open --mode=development"
},
3) devServer 옵션
앞서 설치한 개발 서버에 대한 옵션은 webpack.config.js 의 devServer 라는 옵션을 추가하여 지정가능하다.
devServer :{
static:false, //디렉터리(기본적으로 'public' 디렉터리)에서 정적 파일을 제공하기 위한 옵션을 구성할 때 지정한다. 안 쓰면 false
port : 8001, //지정한 포트번호로 변경할 수 있다(설정 안 할 시 기본 옵션은 8080이다.),
host : '0.0.0.0' , //개발 환경에서 쿠키 사용 및 인증 필요 시 동일한 도메인이 필요하므로 이를 맞출 때 사용한다.
open : true // 서버 오픈 시 브라우저 창을 열도록 설정할 수 있다.
}
https://webpack.kr/configuration/dev-server/#devserverstatic
웹펙은 일반적으로 자바스크립트 파일과 JSON 파일만 이해한다. 따라서 css 파일이나 기타 이미지 파일 등은 자바스크립트 코드나 JSON이 아니기 때문에 모듈로 이해하지 못한다. 그러므로 따로 자바스크립트 코드로 변환시켜주는 옵션을 설정해주어야 하는데, 그 역할을 하는 것이 Loader 이다.
8. Loader "css , 이미지 등의 파일을 자바스크립트 코드로 변환시켜 주는 옵션"
Loader는 이미지나 css 파일을 모듈 형태로 작성하여 가져올 수 있게 한다. 앞서 언급 했듯이 Loader 가 이 파일들을 자바스크립트 코드로 변환시켜 주기 때문이다. 이러한 변환 과정을 거치면 웹펙이 이들 모듈을 이해할 수 있게 되어 압축이 가능해진다.
(만일 위 파일들이 있는 상태에서 로더를 적용하지 않고 webpack 를 실행하면 에러가 뜬다.
Loader 옵션은 use와 test 프로퍼티로 이루어진 객체인 module.rules에 나열하여 설정한다. use는 사용할 Loader 를 설정하고
test 는 로딩할 파일을 지정하는 데 사용된다.
1) 설치하기
npm install -D css-loader style-loader file-loader
//css-loader : css 파일의 코드를 자바스크립트 코드로 변환해준다.
//style-loader : 앞서 변환된 css 파일의 코드를 html 파일 내의 style 태그 내에 옮겨준다.
// file-loader : 첨부한 파일들을 자바스크립트 코드로 변환해준다.
이렇게 작성하면 로더 중에서도 css 파일, html 파일 내의 style 그리고 png, img, jpg 등과 같은 파일을 자바스크립트 코드로 변환해주는 로더를 설치할 수 있다.
2) 옵션 설정하기(webpack.config.js)
설치가 완료되면 다시 웹팩 옵션을 설정하는 파일로 돌아와서 다음과 같이 옵션을 설정해준다.
module : {
rules: [ //module : { rules : [ {test:, use: } ] } 형태로 작성한다.
{
// 문자열이 .css로 끝나는 파일을 대상으로 css, style 로더를 사용한다는 의미
test : /\.css$/, //test 는 정규식으로 표현한다.
use: ['style-loader', 'css-loader'], //좌 <-- 우 순으로 실행
{
//문자열이 .png, .jpg, .gif 중에서 하나 이상으로 끝나는 파일을 대상으로 file 로더를 사용
test : /\.(png|jpg|gif)$/i,
use : ['file-loader'],
},
],
}
// 정규표현식 간략 정리
ㅇ '/ 정규표현 / ' : 양 끝의 / 은 정규표현식의 시작과 끝은 표시하는 것이다. html의 <> </>와 역할이 같다.
ㅇ ' \. ' : 문자열 "." 을 의미한다. 따라서 '\.css'는 문자열 ".css" 를 의미한다.
ㅇ $ : 문자열 혹은 행이 끝나는 지점을 의미한다.
→ 따라서 '\.css$' 은 ".css"로 끝나는 문자열 이라고 해석할 수 있다.
3) CSS 파일을 index.js(엔트리지점)에 import 하기
4) npm run bulid 실행
성공적으로 적용된 것을 볼 수 있다.
하지만 , 이대로만 완료한다면, css 파일은 별도의 파일로 분리되는 것이 아니라, html 파일 내에서 head 내 style 태그로 추가되어 반영된다. 만약에 하나의 html 파일 내에 css 코드를 포함시키는 것이 아니라, 별도의 css 파일로 분리하여 번들링 하고자 한다면, MiniCssExtractPlugin 을 설치하여 HtmlWebpackPlugin 과 같은 방식으로 설정해주면 된다.
또한, 계속 빌드를 반복하다보면 이전 빌드의 불필요한 자료까지도 남아 있어서 일일이 삭제하는게 까다롭고 귀찮은 경우가 생긴다. 이 때 이전 빌드에서 사용하지 않는 파일을 삭제하고자 한다면, CleanWebpackPlugin 을 앞서 설치한 플로그인과 마찬가지로 설치 후 동일한 방식으로 설정하면 된다.
9. MiniCssExtractPlugin 과 CleanWebpackPlugin
1) 설치하기
npm install -D mini-css-extract-plugin //css 파일을 따로 빼서 코드를 합쳐준다.
npm install -D clean-webpack-plugin //빌드 시 이전 빌드 자료를 자동으로 삭제해준다.
https://www.npmjs.com/package/clean-webpack-plugin
https://www.npmjs.com/package/mini-css-extract-plugin
2) webpack.config.js 의 plugins 속성에 추가하기
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = {
//HtmlWebpackPlugin 하고 같은 방식으로 넣는다.
plugins : [
new HtmlWebpackPlugin({'template':'index.html'}),
//요것도 옵션이 있는데 그중 filename 지정하면 그 파일명으로 만들어준다.
new MiniCssExtractPlugin('filename':'public.css'),
new CleanWebpackPlugin()
],
//css는 모듈로 작성한다.
module : {
rules: [ //module : { rules : [ {test:, use: } ] } 형태로 작성한다.
{
test : /\.css$/,
//css 파일을 외부 파일로 바꿀 것이므로 style 로더 대신에 플로그인 넣기
use: [MiniCssExtractPlugin.loader, 'css-loader'], //우->좌 순으로 실행
},
{
test : /\.(png|jpg|gif)$/i,
use : ['file-loader'],
},
],
}
}
이렇게 설정하고 다시 webpack 을 실행하면 지정한 이름으로 css 파일이 dist 폴더에 생성되었다.
'자바스크립트' 카테고리의 다른 글
[javascript] webpack dev server 오픈 시 이미 열린 포트가 있다면, (0) | 2022.12.27 |
---|---|
[javascript] 프로토타입과 상속, 그리고 프로토타입 체인, 최상위 프로토타입 (0) | 2022.12.24 |
[javascript] 모바일에서 터치 이벤트 구현 (0) | 2022.12.23 |
[javascript] 드래그 이벤트로 형제 태그 끼리 위치 교환 하기 (0) | 2022.12.22 |
[javascript] npm 과 package, package.json (1) | 2022.12.22 |