FE 뉴비 절단기라는 웹팩을 배워보자

Webpack 이란?

Webpack :
브라우저에서 우리가 작성한 JavaScript랑 CSS 를 변환시켜주는 것
Babel Node.js 에서 우리가 작성한 JavaScript를 변환시켜주는 것

-> Webpack 이 너무 어렵다면 Gulp 도 있다. 노마드에 무료 강의 있으니 참고하기.

Webpack은 압축, 변형, 최소화등 필요한 작업들을 거치고 정리된 코드를 결과물로 준다.


Webpack 설치하기

npm i webpack webpack-cli -D
//나는 -D가 잘 안돼서 그냥 --save -dev 로 했다


client 폴더를 만들어준다. 이 폴더 안에 있는 코드들은 서버가 아니라 브라우저에서 실행된다.
그 안에 js 폴더를 만들고 그 안에 main.js를 만들어준다.

webpack아 여기는 소스파일들이 있고 여기는 너가 결과물을 보낼 폴더야, 라고 말해주는 것이다.
webpack.config.js 파일에서 webpack 환경설정을 한다.

entry와 output 이 두 가지는 필수이다!

- entry: 우리가 처리하고자 하는 파일들(예쁜 js)
- entry: 이 프로퍼티에 우리가 처리하고자 하는 파일의 경로 입력
- output: 결과물
- filename: 이 프로퍼티에 우리 결과물이 될 파일 이름 입력
- path: 이 프로퍼티에 우리 결과물 파일을 어디에 저장할 지 지정 (이 경로는 절대경로여야 해!)
-> 절대 경로: 전체 경로를 다 적는 것. ->상대경로로 설정되어 있을 때 오류를 resolve(__dirname, 'dist') 가 해결해준다.
ex. ./assets/js (x) /Users/username/harddrives/documents/abcd... (o)


rules
우리가 각각의 파일 종류에 따라 어떤 전환을 할 지 결정하는 것

예시는 아래와 같다.
아래 내용 중
처음(module)부터 test: 까지의 내용(entry, output, rules, 그리고 변형할 파일)은
모든 webpack.config.js 파일에서 보이는 동일한 구조이므로 기억할것!

mode: "development" 는 우리가 아직 개발 중이라고 작성하는 것이다.
이걸 적어주지 않으면 자동으로 production 모드가 되어 코드들을 다 압축하기 때문이다. 개발 중에는 이러지 않아야 한다.
(압축 없이 내가 어떻게 코드를 짜고 있는지 봐야하기 때문)

module.exports = {
    entry: "./src/client/js/main.js",
    mode: "development",
    output: {
        filename: "main.js",
        path: path.resolve(__dirname, "assets", "js"),
    },
    module: {
        rules: [
        {
            test: /\.js$/,
            use: {
            loader: "babel-loader",
            options: {
                presets: [["@babel/preset-env", { targets: "defaults" }]],
            },
            },
        },
        ],
    },
};


정규표현식

/\.js$/ = RegExp

정규표현식에선 .가 분류 커맨드이므로 그냥 .을 쓸려면 \.을 해줘야 된다.
따라서 \.js는 .js이다


Webpack Configuration

client 폴더는 우리가 코딩할 폴더이고, assets 폴더는 브라우저가 접근해서 볼 폴더이다.
그러나 아직 서버는 assets 폴더의 존재를 모르기 때문에,
express에게 assets 안, js 안에 main.js 가 있다고 알려줘야 한다.

upload 폴더를 알려줬던 것처럼 해보자! 같은 방법이다.
server.js 파일을 수정한다.

app.use("/uploads", express.static("uploads"));
// 위에는 전에 했던 방법
app.use("/static", express.static("assets"));
// 아래는 이번에 적은 코드

그리고는 assets/js/main.js 를 base.pug랑 연결시켜야 한다.

// base.pug

include partials/footer
    script(src="/static/js/main.js")


SCSS Loader

npm i sass-loader sass webpack --save-dev
npm i --save-dev css-loader
npm i --save-dev style-loader
  1. webpack의 rules 내부의 'test: /\.scss$/,' 코드에서 모든 scss파일들을 긁어온다
  2. ' use: ["style-loader", "css-loader", "sass-loader"],' 코드에서 순서와 역순으로 작성해주는데,
    sass-loader -> css-loader -> style-loader 이렇게 순서대로 loader가 적용되어 긁어온 scss 파일들을 변환시킨다
    (webpack은 뒤에서부터 시작하기 때문임. 주의하기!)
    작동하는 순서는 아래와 같다.
    1) sass-loader는 scss확장자 파일을 브라우저가 이해할 수 있는 css 파일로 변환시킨다
    2) css-loader는 @import, url()등의 최신형 css 코드를 브라우저가 이해할 수 있는 코드로 변환시켜 동작할 수 있도록 한다
    3) style-loader는 위 과정으로 변환시킨 css 코드를 DOM 내부에 적용시켜준다
  3. 변환된 코드가 output에서 설정된 파일 경로에 설정된 파일명으로 저장된다
  4. 저장된 변환 js 코드를 pug 파일에 적용시키기 위해 'script(src="/static/js/main.js")' 코드를 통해 긁어와 적용시킨다


MiniCssExtractPlugin

이제 style loader를 쓰지 않고, 두 파일을 얻기 위해 webpack plugin을 써보려고 한다.
이 플러그인은 해당 코드를 다른 파일로 분리시키는 기능을 하는데, 여기서는 CSS를 별도의 파일로 추출한다.

npm install --save-dev mini-css-extract-plugin

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
plugins: [new MiniCssExtractPlugin()],


이제 pug에서 css 파일을 연결해보자.
base.pug가 이 파일들(static files (o) client files (x) )을 로딩하는 곳이라는 걸 잊지 말기!
(client files는 webpack에 의해서만 로딩하게 할 거임!)

// base.pug

head	
	link(rel="stylesheet", href="/static/css/styles.css")



Watch and WatchOptions

Webpack은 파일이 변경될 때마다 이를 감지하여 다시 컴파일 할 수 있다.

이때 vsc 터미널에서 두 개의 콘솔을 사용하는 데 익숙해져야 한다.
하나는 npm run dev 를 하는 백엔드 콘솔이고,
하나는 npm run assets 를 하는 프론트엔드 콘솔이다.

watch
-> 매번 npm run assets 할 때마다 assets 폴더를 삭제해야 하는 번거로움을 덜기 위해 watch 를 사용해보려고 한다.
watch 모드를 켜면 초기 빌드 후 webpack은 해석 된 파일의 변경 사항을 계속 감시한다.
(webpack.config.js에 entry에 지정한 파일을 감시한다.)

-> output 안에 clean:true 를 추가하여 output folder 빌드를 시작하기 전에 clean 해주도록 한다

Nodemon
-> 프론트엔드 js 코드가 변경될 때 매번 백엔드가 재시작되는 걸 막기 위해 nodemon을 일부 변경하고자 한다.
nodemon은 디렉토리의 파일 변경이 감지되면 노드 응용 프로그램을 자동으로 다시 시작하여
node.js 기반 응용 프로그램을 개발하는 데 도움이 된다.
Sample nodemon.json
Nodemon Config file