https://jeonghwan-kim.github.io/series/2019/12/10/frontend-dev-env-webpack-basic.html
을 읽고 정리하였습니다.
등장배경
import/export 모듈 개념이 없었던 이전 상황을 살펴보자.
문제발생
숫자 두개를 받아, 더하고 리턴하는 sum 함수를 만들어 쓴다고 생각해보자.
그 함수는 math.js 에 만들어놓고, app.js에서 호출해서 실행한다.
math.js
function sum(a, b) {
return a + b
} // 전역 공간에 sum이 노출
app.js
sum(1, 2) // 3
위의 코드는 모두 하나의 HTML안에서 로딩되어야 만 실행된다. (math.js 와 app.js 가 하나의 html에 같이 불러와져야 한다)
math.js 가 로딩되면, app.js는 `sum` 을 찾은 뒤, 함수를 실행한다.
이때 문제는 `sum` 이라는 함수의 이름이, 전역공간에 노출된다는 것. 혹여나, 다른 js 파일에서 `sum` 이라는 이름을 사용하고, 같은 HTML에서 로딩을 한다면.. 충돌날 것이다.
문제해결?
이러한 경우를 방지하기 위해 스코프라는 것을 이용해 공간을 격리해서 사용하고자 했다.
이렇게 격리하는 방식을 각각의 커뮤니티에서 여기저기서 만들어낸다. (격리하는 방식을 모듈 시스템이라 부른다 보면 된다.)
이때, ES2015에서 표준 격리 시스템을 내놓는다.
해당 표준 격리 시스템은 아래와 같다.
math.js
export function sum(a, b) {
return a + b
}
app.js
import * as math from "./math.js"
math.sum(1, 2) // 3
export 구문으로 모듈(격리공간)을 만들어서, import 구문으로 사용할 수 있다.
하지만..
슬프게도, 모든 브라우저가 해당 모듈시스템을 지원하는 것은 아니다.
모듈시스템을 사용하려면 어떤 작업을 해주어야 하는 브라우저도 존재한다. 예를들어, 크롬브라우저가 있는데,
<script type="module" src="app.js"></script>
위처럼, 모듈시스템을 사용하려면 type="module"
을 사용해야 만 한다.
이런 작업없이 모든 브라우저에서 편하게 모듈시스템을 쓰고 싶은데.. 이때 웹팩이 등장한다.
웹팩 등장
웹팩은 여러개의 파일을 하나로 합쳐주는 번들러 이다. 하나의 시작점 entry point 로부터 의존적인 모듈들을 모두 찾아내서 하나의 결과물로 합쳐낸다. app.js 부터 시작해 math.js 를 찾아 하나의 파일로 합치는 형식이다.
아래와 같이 설정할 수 있다.
webpack.config.js
module.exports = {
mode: "development", // 웹팩 실행모드: development , production , none
entry: {
main: "./src/app.js", // 어플리케이션 진입점
},
output: {
filename: "[name].js",
path: path.resolve("./dist"),
},
}
로더
로더의 역할
웹팩은 모든 파일을 모듈로 바라본다. 자바스크립트로 만든 파일 뿐만 아니라, css 스타일시트, 이미지, 폰트까지 모두 모듈로 보기때문에, import 구문을 사용하면 자바스크립트 코드 안으로 가져올 수 있다.
이런 것들이 가능한 이유는 웹팩의 로더 덕분이다. 로더는 타입스크립트와 같은 다른 언어를 자바스크립트 문법으로 변환해주거나 이미지를 data URL 형식의 문자열로 변환해준다. 이뿐만 아니라, CSS 파일을 자바스크립트에서 직접 로딩할 수 있도록 해준다.
즉, 로더는 웹팩이 웹을 해석할 때 자바스크립트 파일뿐만 아니라 웹자원(HMTL, CSS, Images, font..) 등 들을 변환작업을 할 수 있도록 도와주는 것이라 보면 된다. 웹자원들을 모듈로 해석할 수 있게 도와준다.
로더를 만들어보자
myloader.js
module.exports = function myloader(content) {
console.log("myloader가 동작함")
return content
}
커스텀으로 만든 myloader.js 를 웹팩 설정파일에 추가해준다
webpack.config.js
module: {
rules: [{
test: /\.js$/, // .js 확장자로 끝나는 모든 파일
use: [path.resolve('./myloader.js')] // 방금 만든 로더를 적용한다
}],
}
module.rules 에 모듈을 추가한다.
test는 로딩에 적용할 파일
use 는 해당 test pattern 에 해당하는 파일에 적용할 로더를 설정한다.
아래와같이, console.log 함수를 alert 함수로 변경한다는 작업으로 바꿀 수 있다.
module.exports = function myloader(content) {
console.log("myloader가 동작함")
return content.replace("console.log(", "alert(") // console.log( -> alert( 로 치환
}
자주 사용하는 로더
css-loader
CSS 파일을 자바스크립트에서 불러와 사용하려면 CSS 를 모듈로 변환하는 작업이 필요하다.
module.exports = {
module: {
rules: [
{
test: /\.css$/, // .css 확장자로 끝나는 모든 파일
use: ["css-loader"], // css-loader를 적용한다
},
],
},
}
app.js
import "./style.css"
style-loader
스타일 시트는 사실상 DOM에 추가되어야 브라우저가 해석할 수 있다. css-loader 로만 처리하면 모듈로만 변경되고 DOM 에는 적용되지 않았기 때문에 스타일이 적용되지 않는다 !
style loader 는 모듈로 변경된 스타일을 동적으로 DOM 에 추가하는 로더이다.
즉, CSS 를 번들링(모듈화) 하기 위해서는 css-loader 와 style-loader 를 함께 쓴다.
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ["style-loader", "css-loader"], // style-loader를 앞에 추가한다
},
],
},
}
배열로 쓰면, 뒤에서부터 앞 순서대로 로더가 적용되기 때문에 style-loader 를 앞에 설정하자.
file-loader
css뿐만 아니라 소스코드에서 사용하는 모든 파일을 모듈로 사용할 수 있게끔 해준다.
가령 CSS 에서 url 함수에 이미지 파일 경로를 지정할 수 있는데, 웹팩은 file-loader 를 이용해서 처리할 수 있다.
module.exports = {
module: {
rules: [
{
test: /\.png$/, // .png 확장자로 마치는 모든 파일
loader: "file-loader",
options: {
publicPath: "./dist/", // prefix를 아웃풋 경로로 지정
name: "[name].[ext]?[hash]", // 파일명 형식
},
},
],
},
}
웹팩이 .png 파일을 발견하면 file-loader 가 실행될 것이다. 로더가 동작하고 나면 output 에 설정한 경로(./dist/) 에 이미지 파일이 복사된다.
이미지의 위치는 아웃풋 위치로 이동됬을 것이니, 브라우저가 실행시 해당 아웃풋 위치로 이미지를 찾을 수 있도록 경로를 적용해준다.
'🌳Frontend > etc' 카테고리의 다른 글
자바스크립트 메모리 누수 관리 및 개선 (0) | 2023.04.11 |
---|---|
익명함수의 메모리 누수 (0) | 2023.04.10 |
[JS 문제] Array Sort Comparison / 배열의 동등비교 (0) | 2023.03.26 |
프론트엔드 개발자라면 알아야할 : Webpack 심화 (0) | 2023.03.24 |
[Jest] it/test/describe 키워드 (0) | 2023.03.21 |