#1 Webpack이란?
여러 프론트엔드를 이루는 파일들을 모아 컴파일해서 js, css 등등으로 변환하여 프로젝트에 적용해주는 프로그램.
압축, 최소화, 최적화 등의 처리를 해준다.
#2 Webpack 설정
보통은 React 등 대부분 Frontend 라이브리러에 이미 적용되어 있어 직접 사용할 필요는 없지만, 이번에는 공부겸 강좌를 보며 직접 프로젝트에 적용해보려고 한다.
npm i webpack --save-dev
npm i webpack-cli --save-dev
개발자에게 도움을 주는 라이브러리이므로 devDependencies에 설치
이후 프로젝트 폴더에 webpack.config.js 파일을 만든다. 여기서 설정을 해주는데, 최신 자바스크립트 문법은 사용할 수 없음.
따라서 module.export = {} 구조를 통해서 프론트엔드 파일을 받아오는데, 이는 인자로 entry와 output이라는 두가지 인자를 가지고 있다.
entry에는 소스코드(소스 코드 저장 경로),
output에서는 webpack이 코드를 컴파일하고 나온 결과물을 저장할 경로 + 저장할 파일명을 넣어준다.
이때 경로는 절대경로가 되어야 하며, 따라서 아래와 같은 코드가 나온다.
const path = require("path");
module.exports = {
entry: "./src/client/js/main.js",
output:{
filename: "main.js",
path: path.resolve( __dirname, "assets", "js" )
}
}
경로에 대한 코드들을 짧게 정리하자면,
JS 에서 __dirname 은 현재 프로젝트까지의 절대 경로가 저장되어 있다.
const path = require("path"); 를 통해 import 받은 path의 경우 경로에 대한 메소드를 가지고 있고,
이 중 path.resolve( __dirname, ~~ );은 경로명을 연결해서 특정 경로명을 반환해준다.
따라서 path.resolve( __dirname, "assets", "js" ); 의 반환값은 (프로젝트 경로)/assets/js 가 된다.
위와 같은 방식으로 파일을 타켓팅하여 변환하는 방법을 알았으나, 파일마다 어떤 변환이 필요한지도 설정을 해주어야한다. css는 style-loader 나 js는 babel을 적용해주는 등의 기능을 결정하는 역할을 한다.
그게 rules를 미리 설정하는 것인데, 위에서 썼던 object에 module항목을 추가 작성해준다.
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"}]]
}
}
}
]
}
}
백엔드에서 설치했던 babel 라이브러리 외에 babel-loader의 설치도 필요하다.
추가로 mode도 설정해주었는데, 개발중일때의 'development'모드와 운영중일 때의 'prodcution'모드가 있다.
운영모드로 설정하면 컴파일한 코드가 줄바꿈 없이 압축되어 개발이 힘들게 되므로 잘 설정해두도록하자.
위에 만든 설정들을 기반해서 컴파일하기 위한 콘솔 명령어도 있으니 이를 script에 미리 저장해두자.
"scripts":{
"assets": "webpack --config webpack.config.js"
}
#3 express와 연동하기
webpack의 결과물로 생성된 파일들을 express에 정적인 파일로서 추가해주는 과정이 필요하다.
이는 server.js(이름은 자유. 그냥 express가 설정되는 파일)에서 설정하는데, 아래와 같은 문법으로 사용한다.
//첫번째 인자-브라우저에서 실행할 때 URL, 두번째 인자-읽어올 폴더 경로
app.use("/static", express.static("assets"));
이후 아래와 같이 scirpt 파일을 문법대로 추가해주기만 하면 된다.
이때, 경로명을 위에서 설정해둔 경로명으로 잘 맞춰주도록 하자. 위에서 설정한 경로명이 사용자 지정 경로명 같은 것이다. 따라서 실제 폴더명은 asstes이겠지만, static으로 설정해줄 것.
//pug
script(src="/static/js/main.js")
//ejs
<script src="../static/js/main.js"></script>
이후 CSS를 추가할 때, JS에다가 CSS파일을 import하는 방식을 사용하는데, 이는 js가 css를 적용하는 어떠한 역할을 하도록 webpack이 파일을 변환한다.
webpack설정은 다음과 같다.
const path = require("path");
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"}]]
}
}
},
{
test: /\.css$/,
use:['style-loader', 'css-loader'],
}
]
}
}
특이한 걸 꼽자면, use에 배열로 넣을 때, 파일을 컴파일 하는 순서의 역순으로 넣어줘야한다.
따라서 위 코드에 따르면 css-loader 이후에 style-loader가 동작하는 방식이다.
#4 JS와 CSS파일 분리하기
위에서는 JS에서 CSS를 import하게 했지만 코드를 조금 수정해서 CSS파일이 따로 import하게 만들어주려고 한다.
그렇지 않으면 JS가 로딩되기 전에는 사이트에 HTML 밖에 없기 때문.
npm install --save-dev mini-css-extract-plugin
위 플러그인을 사용한다.
webpack.config도 아래와 같이 변경
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const path = require("path");
module.exports = {
entry: "./src/client/js/main.js",
mode: "development",
plugins: [new MiniCssExtractPlugin({
filename:"css/styles.css"
})]
,
output:{
filename: "js/main.js",
path: path.resolve( __dirname, "assets")
},
module:{
rules: [
{
test: /\.js$/,
use:{
loader: "babel-loader",
options: {
presets:[["@babel/preset-env", {targets: "defaults"}]]
}
}
},
{
test: /\.css$/,
use:[MiniCssExtractPlugin.loader, 'css-loader'],
}
]
}
}
++ 개발환경 개선하기
1. module.export에 watch:"true" 입력해주기. 프론트엔드 코드의 변경점이 있으면 파일 refresh와 compile을 다시 진행해준다. 다만 콘솔에서 실행중이기 때문에 다른 콘솔에서 추가로 서버를 열어줘야한다.
2. output파일을 지웠다가 새로 만들어주도록 설정하기는 아래와 같다,
output:{
filename: "js/main.js",
path: path.resolve( __dirname, "assets"),
clean:true,
},
clean:true를 추가해줌.
3. frontend 코드를 수정했을 때, 백엔드의 nodemon이 이를 인식해서 백엔드를 재실행하지 않도록 설정한다.
nodemon.json 파일 생성후 아래와 같이 입력해주고
{
"ignore" : ["webpack.config.js", "src/client/*"],
"exec" : "babel-node src/server.js"
}
기존 package.json에 저장된 npm run dev 명령어는 단순히 nodemon만 실행하도록 바꿔주면, 실행과 무시할 파일들이 잘 설정되어 동작한다.
"scripts": {
"dev": "nodemon",
"assets": "webpack --config webpack.config.js"
},
'프로젝트 기록 > 러시아어 사전 및 검색 웹' 카테고리의 다른 글
개발 과정 리뷰 -10- 형태소 추출 API 만들기(NestJS) (1) (0) | 2023.12.27 |
---|---|
개발 과정 리뷰 -7- ejs와 html escape 개념 (0) | 2023.12.14 |
개발 과정 리뷰 -4- MongoDB 연동 (0) | 2023.12.09 |
개발 과정 리뷰 -3- (0) | 2023.12.07 |
개발 과정 리뷰 -2- 라우터와 정규표현식 (0) | 2023.12.04 |