# 9.0 -3 Webpack

이원규·2022년 7월 5일
0

Itube

목록 보기
31/46

-> 이번 9장에서는 frontend를 다뤄볼 것임.(frontend에서 JS를 구현할 것임)
-> pug template를 HTML로 compile하면 그게 프론트엔드임.

-> 백엔드에서는 우리가 원하는대로 코드를 써도 nodeJS가 이해하도록 babel/node가 처리해줌.
프론트엔드JS에서도 이런 기능을 하는 도구가 필요함. 즉, 우리가 프론트엔드에서 JS를 쓰면 어떤
브라우저에서도(크롬, 사파리 등) 작동되도록 하기 위해 이를 도와주는 도구가 필요하다는 것임. Webpack이
바로 그런 역할을 함.우리가 최신의 JS or CSS 코드를 써도 모든 브라우저가 이해할 수 있게 예전의 JS or
CSS 언어로 변화시켜주는 것임.(backend - babel / frontend - webpack)

webpack introduction

-> nico쌤은 webpack을 직접 쓰진 않고, webpack이 내장된 툴들을 사용함. 리액트, 리엑트 네이티브 등 대부분의 프레임워크엔 webpack이 내장되어 있음. 다시 말하지만, react, next, vue등 대부분이 뒤에서 webpack을 사용하지만, 우리가 직접 쓸 일은 없음. 건드릴 필요가 없는거지. 설정할 일도 없음.
-> 그럼에도 Webpack을 배우는 이유: 이건 거의 업계의 표준이고, 적어도 이게 어떻게 작동하는지 그리고 그 뒤에 무슨일이 일어나는지는 알아야 된다고 생각해서 배워야함.
-> 이거에 관한 강의: gulp강의도 있음. gulp가 webpack보다 다루기 쉽겠지만, webpack만큼 유용하진 않을 것임.
-> 이번 section에서는 webpack configuration파일을 작성하는 건데, 굉장히 세련된 JS코드(css도)를 작성하고 그 코드들을 못생기고 지루하지만 호환성있는 코드로 전환하는 법을 배울것임.

1. Webpack

1.1 webpack & webpack cli설치

npm i webpack webpack-cli --save-dev

-> --save-dev: 이 webpack & cli를 devDependencies에 저장하려고
-> webpack cli: webpack을 console에서 불러낼 수 있음.

1.2 Webpack.config.js 생성

-> webpack을 설정하기 위해서는 Webpack.config.js 생성해야함. 참고로 이 파일을 굉장히 오래된 JS코드만 이해할 수 있음.
-> 우리가 webpack에게 할 말: 여기에 소스파일이 있고, 여기가 네가(webpack) 결과물을 보낼 폴더야.

Webpack.config.js의 주의사항 2가지

webpack start

  1. entry(=소스코드):entry는 우리가 처리하고자 하는 파일들임.(내가 쓴 최신의 JS코드).

    -> src폴더에 client라는 폴더를 생성하고(이 client폴더는 backend가 아니라
    브라우저에서 실행될 거라는 걸 알 수 있음) 이 client폴더 안에 js폴더를 만들고 그 안에
    main.js파일을 만들어라. = src/client/js/main.js
    -> 우리가 하고자 하는 것은, 이 main.js파일을 webpack에 전달하는 것임. 이 파일을 전달해주면
    webpack은 모든 브라우저에서 이해할 수 있는 옛 코드로 그걸 뱉어낼 것임. 즉, main.js가
    우리의 entry가 되는 것임.

  2. output : output은 우리가 쓴 js코드를 모든 브라우저가 이해할 수 있는 코드로 뱉어낸 코드를 적은 파일을 의미함.

webpack.config.js에서 entry & output 설정

  • webpack.config.js
const path = require("path");//path 모듈임(nodeJS에서 제공하는).

module.exports = {
    entry: "./src/client/js/main.js",
    output: {
        filename:"main.js", //-> output 파일명.
        path: path.resolve(__dirname, "assets", "js"), // -> output 경로(절대 경로여야함.)
    }
}

-> webpack이 하는 일: entry의 최신 JS코드를 모든 브라우저가 이해할 수 있는 코드로 변환하여 output파일 디렉토리에 저장하는 일을 함.

-> path.resolve(a, b, c ,..): resolve내의 인수들을 묶어서 JS가 이해할 수 있는 경로로 만들어줌.
위의 path.resolve(~~) = /Users/iwongyu/Desktop/nomadcoder/nomad-wetube/assets/js 경
로가 됨.

-> path 모듈: Path 모듈은 파일과 Directory 경로 작업을 위한 Utility를 제공한다.

1.3 webpack 실행

package.json에 스크립트 만들기

-> assets: webpack을 실행시킴.

//추가
"assets": "webpack --config webpack.config.js"

//최종
"scripts": {
    "dev": "nodemon --exec babel-node src/init.js",
    "assets": "webpack --config webpack.config.js"
  },

webpack 실행

npm run assets

-> 이렇게 실행하면 output의 파일(assets파일)이 생성될 것임. 이 파일(main.js)내에서는 entry에서 작성한 최신 코드를, 옛 방식으로 변환한 코드가 들어있을 것임.

1.4 어떤 코드들은 여전히 브라우저가 이해할 수 없는 것들이 있기 때문에 호환성을 추가해줘야함.(babel in frontend)

-> babel을 이용할 것임. babel을 프론트엔드에서 사용. 이건 package.json이 아니라 webpack.congig.js에서 해줘야함.

rules

rules: 우리가 각각의 파일 종류에 따라 어떤 전환을 할 건지 결정하는 거.
loader: 변환시 변환하는 담당부분을 loader라 부름. js를 변환할 우리의 경우에는 babel-loader가 필요함. webpack의 경우 loader를 이용해 변환을 하는 것임.

babel-loader

  • 설치:
npm install -D babel-loader @babel/core @babel/preset-env webpack 
//-> 다른건 이미 다 설치해서, npm install -D babel-loader 만 해주ㅠ면 됨.
  • 사용: 이제부터 우리는 프론트/백엔드에서 babel/core와 babel/preset-env를 사용할 것임.
  • webpack.config.js
//추가
module :{
        rules:[
            {
                test: /\.js$/,//모든 js파일을
                use: {
                    loader: "babel-loader",//babel-loader를 이용해 가공해줘라.
                    options: {
                        presets:[
                            ["@babel/preset-env", {targets: "defaults"}]
                        ]
                    }
                }
            }
        ]
    }
//촤종
const path = require("path");

module.exports = {
    entry: "./src/client/js/main.js",
    output: {
        filename:"main.js",
        path: path.resolve(__dirname, "assets", "js"),
    },
    module :{
        rules:[
            {
                test: /\.js$/,//모든 js파일을
                use: {
                    loader: "babel-loader",//babel-loader를 이용해 변형시킴
                    options: {
                        presets:[
                            ["@babel/preset-env", {targets: "defaults"}]
                        ]
                    }
                }
            }
        ]
    }
}

-> JS코드를 babel-loader라는 loader로 가공하는 과정임.
-> webpack은 node-module에서 babel-loader를 찾을 거고 거기에 몇가지 옵션을 전달해준 것뿐임.

mode 설정 (완성품 or 개발중)

-> webpack에 mode를 알려줘야함. 기본 default값은 완성품 모드인데, 이 모드일 경우에는 바로 코드를 변환시켜서 어디가 문제인지 알 수 없음. 그래서 mode는 완성되기 전까지는 개발중 모드로 해줘야함.

  • webpack.congig.js
//추가
mode: "development",
  
// 최종 코드
const path = require("path");

module.exports = {
    entry: "./src/client/js/main.js",
    mode: "development",//mode설정
    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"}]
                        ]
                    }
                }
            }
        ]
    }
}

우리가 배운 것

  1. 우리 main.js라는 entry파일이 있었고, 그 결과물이 assets/js/main.js에 있었음.
  2. rules를 통해 특정 종류의 파일들에게 변형을 적용시키는 법을 알았음.
  3. 우리가 꼭 기억해야 할 부분
  • webpack.config.js
entry: "./src/client/js/main.js",// entry파일 위치
    output: {//output파일
        filename:"main.js",
        path: path.resolve(__dirname, "assets", "js"),
    },
    module :{
        rules:[
            {
                test: /\.js$/,//변형할 파일
              	use: {//사용할 lodaer
  1. mode를 통해 개발중인지 완성품인지 알려주기.

기억하기

  1. entry & output
  2. module-rules: test,use
  3. mode: 우리가 개발중인지 아닌지 알려줘야함.

client: webpack이 처리하기 전 파일. 우리가 코딩할 곳.
assets: webpack이 처리하고 난 파일. 브라우저가 직접적으로 맞딱드리는 곳. 브라우저에게 적용될 곳.

1.5 express에게 assets폴더가 있다고 알리기 -> 이래야 assets폴더에 접근 가능.

-> 정적파일: 한 마디로 express에게 사람들이 이 폴더 안에 있는 파일을 볼 수 있도록 요청하기. 왜냐면 기본적으로 폴더는 비공개임. 서버가 어떤 폴더를 공개할지 정하는 것임.

static을 이용해 정적파일 제공

  • server.js
//추가 
app.use("/assets", express.static("assets"));
//app.use(접근할 url(임의 설정 ㄱㄴ), express.static(접근할 폴더명))

-> 이렇게 되면 'http://localhost:4000/assets/js/main.js' 이렇게 url을 쳐서 브라우저가 assets폴더의 main.js파일에 접근할 수 있음.

1.6 assets/js/main.js파일을 base.pug와 연결시키기

  • base.pug
//추가 -> body와 같은 위치
script(src="/assets/js/main.js") // script파일을 url에서 불러오는 것임.(1.5에서 이래서 assets파일을 url로 접근가능하도록 한 것임.)

시험 해보기

  1. client/js/main.js 파일에다가 alert("hi") 작성하고
  2. npm run assets 고고 (
  3. npm run dev ㄱ ㄱ
  4. localhost:4000 가서 hi alert뜨면 연결된 것임.

원리(순서)

=> client폴더에 작성한 코드를 webpack이 babel-loader를 이용해 코드를 변환하여 assets폴더에 저장함. 그리고 이 assets폴더를 express.static을 이용해 브라우저가 폴더에 접근할 수 있도록 해주고 이를 이용해 base.pug(프론트엔드)와 연결시켜서 웹사이트에 코드가 적용되도록함.

client코드 작성(최신 코드) -> webpack의 변환(babel-loader이용) -> assets저장(모든 브라우저가 읽을 수 있는 코드) -> express.static으로 assets접근 ㄱㄴ -> assets과 base.pug의 연결 -> 웹사이트가 assets의 코드를 읽고 적용

추가 꿀팁들

  • 강의 계속 듣다보니까 마지막에 나오네요😅
    #9.6 Better Developer Experience (10:18) 여기까지 들어보시면
    저절로 해결됩니다 :)

매번 폴더를 지우고 싶으신 분들은 scripts를
"assets": "rimraf assets && webpack --config webpack.config.js"로 설정하시면 됩니다

webpack이 계속 코드를 주시하고 변경시 자동으로 compile되기를 원한다면
watch: true,
watchOptions: {
ignored: /node_modules/,
aggregateTimeout: 5000,
poll: 1000,
},
를 webpack.config.js의 module.exprots안에 넣어주세요

aggregateTimeout은 리빌딩할 때의 딜레이 타임이고 (ms단위)
poll은 변화를 감지하는 시간입니다(ms단위)

위의 경우에는 1000ms(매초)마다 변화를 감지하고 변화를 감지하고 이를 1000ms(5초)뒤에 리빌딩하게 됩니다

저는 npm run dev, npm run assets을 각각 다른 터미널에 입력하고 사용하고 있습니다
(프론트엔드 코드를 짜면 알아서 웹팩이 리빌딩해주고 새로고침만하면 바로 적용됩니다)

더 나은 방법이 있다면 댓글로 공유 부탁드립니다👍
참고: webpack watch

profile
github: https://github.com/WKlee0607

0개의 댓글