[Youtube 클론코딩] Webpack 알아보기

2022. 11. 26. 19:42공부/Javascript

이제 Front-end를 만들 차례다.

 

그러기 위해서는 Webpack이라는 것을 먼저 알아보자.

webpack

 

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

우리는 백엔드를 개발하기 위해 Node JS를 선택했다.

거기서 JS의 최신 문법들을 어느 브라우저에서도 호환이 될 수 있는 보편적인 문법으로 바꿔주기 위해 Babel을 사용했다.

 

프론트엔드도 마찬가지로 최신 문법들로 작성된 CSS와 JS 등을 구형의 문법과 파일로 변환해주어야 호환성이 좋은데

이를 Webpack이 해주는 셈이다.

 

보통은 이를 바탕으로 사용하는 프레임워크(Vue, React) 등을 사용하기에 별도로 웹팩을 직접 설정하지는 않지만

알아두어야 할 몇가지 사항들이 있다.

 

/webpack.config.js

webpack은 4.0.0 버전에 들어서면서 굳이 config.js 파일이 필요하지 않아졌지만, 만들어서 커스터마이징이 가능하다.

Asset Management | webpack

 

Asset Management | 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를 만들어 주고 다음처럼 작성한다.

entry : webpack에서 변환할 소스 파일

watch: entry 파일의 변화를 감지하여 변동 시 webpack 다시 실행

output: 변환된 파일을 저장하는 방식

- filename: 변환된 파일의 이름. 앞에 js/ 같은 문구를 삽입하여 특정 폴더 안에 저장되게 할 수 있다.

- path: 변환된 파일이 저장 될 경로. (절대 경로)

- clean: 이전에 생성된 파일들을 삭제하고 새롭게 만든다.

 

즉, src/client/js/main.js 를 webpack으로 변환하여 /assets/js/main.js에 저장한다는 의미다.

여기서 중요한 점은 path는 절대경로로 넣어주어야 하는데 이를 쉽게 넣어주기 위해서는

path.resolve()와 __dirname을 이용하면 된다.

path.resolve(string1, string2, string3...)

node JS의 기본 패키지로, 넣어준 문자열들을 /로 구분지어 하나의 문자열로 반환한다.

__dirname 은 현재 파일이 위치한 절대 경로를 반환한다.

 

이후 package.json에서 다음의 명령어를 지정해주자

그러고 npm run dev:assets 를 실행하면

변환 전
변환 후

이렇듯 공백 등을 제거해서 변환해주는 것을 볼 수 있다.

 

webpack은 기본적으로 Production 모드로 되어있어서 배포용 파일로 변환해주느라 이렇게 되는데

개발할 때는 우리가 잘 볼 수 있도록 압축하지 않는 옵션도 제공한다.

loaders

Loaders | webpack

 

Loaders | 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

웹팩은 그냥 실행만 한다고 해서 구형 문법으로 변환을 해주는 것이 아니다.

그런 기능을 담당하는 것은 loader 들로

JS를 변환하려면 babel-loader, SCSS를 변형하려면 sass-loader 등이 필요하다.

JavaScript: babel-loader

babel-loader | webpack

 

babel-loader | 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

babel-loader를 사용하려면 babel/core와 babel/preset-env, babel-loader, webpack이 필요하다.

이미 babel-loader를 제외한 나머지 패키지들은 설치돼있으니 babel-loader를 devDependencies로 설치한다.

이후 webpack.config.js에 위의 내용을 그대로 복사 붙여넣기 하면 된다.

test는 정규식으로, 끝이 .js나 .mjs 인 것들을 대상으로 한다는 것이다.

 

변경 전
변경 후(한눈에 보기 쉽게 하기 위해 dev모드를 해제했다)

이제 브라우저에서 async await 구문을 처리할 수 있기 때문에 변환은 굳이 필요없어서 안한 모습.

이를 웹페이지에 적용하려면 pug 파일에서 script 태그로 넣어주면 된다.

CSS: sass-loader

css는 보통 편의를 위해 scss를 많이 사용하는데, 이를 적용하려면 세가지의 loader가 필요하다.

1. sass-loader :sass/scss 파일을 css 파일로 변환.

2. css-loader : @import 나 url() 을 처리.

3. style-loader : 변환된 css 파일을 JS에 삽입

 

세가지 loader는 각각 하는 일이 다르며 서순이 중요하기 때문에 반드시 1 2 3의 순서대로 적용돼야 한다.

sass-loader | webpack

 

sass-loader | 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

guide 문서에 따르면 다음과 같은 방식으로 삽입하라고 되어있는데 보면 use의 순서가 거꾸로 되어있다.

이는, webpack은 뒤에서부터 적용하기 때문이다.

 

그런데 이렇게 넣고 돌려보면 결과물에 css는 없고 JS 하나만 나오게 된다.

그 이유는 style-loader가 css를 JS 내부에 코드로 삽입시키기 때문이다.

그러나 이는 유지 보수 측면에서 그다지 바람직하지 못하다.

 

따라서 css파일과 js파일을 분리해서 사용하기 위해 플러그인을 사용한다.

MiniCssExtractPlugin | webpack

 

MiniCssExtractPlugin | 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

사용법은 위와 같이 style-loader 자리에 저 플러그인을 대신 넣어준다.

이 때, MiniCssExtractPlugin()에서 매개변수로 몇가지 설정을 넣어줄 수 있다.

이처럼 객체 형태로 옵션들을 넘겨줄 수 있다.

filename을 css/style.css 로 만들어서 js와는 다른 폴더에 저장되게 만들어주었다.

 

/src/client/scss 에 다음과 같은 두 파일을 만든 뒤 반드시 main.js에 import해 주어야 webpack이 이를 변환한다.

이후 변경된 결과가 저장된 경로인 /assets/css/styles.css를 base.pug에 연결시켜주면

다음처럼 결과가 나온다

nodemon.json 만들기

이제 우리는 프론트 엔드 측을 컴파일하는 webpack 설정을 했고 이를 감시하는 watch 속성을 통해

하나는 백엔드를 감시하는 nodemon이 돌아가고 하나는 프론트엔드를 감시하는 webpack이 돌아간다.

따라서 프론트엔드 측에서의 변화를 굳이 nodemon이 감지해서 다시 서버를 재실행 할 필요가 없어졌다.

 

그러므로 이를 제외하는 설정을 해주어야 하는데, 기존 명령어에 뒤에 붙이기는 너무 코드가 길어진다.

다행히 따로 설정파일로 빼서 관리할 수 있는 옵션이 존재한다.

nodemon - npm (npmjs.com)

 

nodemon

Simple monitor script for use during development of a Node.js app.. Latest version: 2.0.20, last published: 2 months ago. Start using nodemon in your project by running `npm i nodemon`. There are 4074 other projects in the npm registry using nodemon.

www.npmjs.com

webpack.config.js와 FE 측 소스 폴더, 컴파일 결과 폴더를 ignore에 넣어준다.

기존에 --exec 로 넣어주었던 속성도 nodemon.json에 넣어서 관리하면 명령어를 그냥 nodemon으로 만들 수 있다.

 

nodemon은 기본적으로 같은 위치에서 nodemon.json을 찾아서 실행하고

webpack은 같은 위치에서 webpack.config.js를 찾아서 실행하므로 두 명령어를 단축시키면 다음과 같다.