오늘은 스태틱 코드를 번들하는 웹팩 설정 방법에 대해서 적어보려 합니다.
여기서는 제가 사용해 본 기능만 담고 있기 때문에 더 좋은 방법 또는 틀린 부분? 등이 있을 수 있음을 미리 알려드립니다.
STATIC 데이터(html 페이지를 컨트롤하는 javascript, css 코드 등)를 구성하기 위해서, 용도에 맞게 js, css파일을 작성해서 복수의 파일들로 관리하는 것이 일반적일 것이라고 생각됩니다.
여기서 웹팩을 이용하게 되면, 복수로 작성한 다수 파일들을 번들링 해서 하나의 main.js + styles.css 조합 등으로 html 파일에 대입하여 적용할 수 있습니다.(필자는 css코드를 sass코드로 작성하고 static 코드로 변환했다.)
이런 번들링 기능을 사용하기 위해선 웹팩 라이브러리 configure 작업이 필요한데, 너무 어렵게 느껴지는 건 나뿐인가요.
일단 사용한 부분에 한해서만 설명이 가능하기 때문에, 자세한 내용은 웹팩 문서를 참고 부탁드립니다.
1. webpack관련 라이브러리 설치(npm 사용)
사용한 라이브러리📚 :
- 기본 : webpack, webpack-cli
- 각종 loader : babel-loader, css-loader, postcss-loader, sass-loader, node-sass
2. webpack.configure.js 파일 생성(그냥 만들면 됩니다🤣)
프로젝트 최상위 위치에 webpack.configure.js 파일 생성.
3. webpack.configure.js configure 코드 작성
📋 webpack.configure.js
🔗 라이브러리 임포트.
const path = require("path");
const miniCssExtract = require("mini-css-extract-plugin");
const autoprefixer = require("autoprefixer");
기본적으로 복수의 scss, js 파일을 변환해서 하나의 js파일(static) 안에
그대로 하나의 파일로 사용해도 문제는 없지만, 변환된 코드 안에서(css, js코드 다 섞여있는 상태) css코드를 별개 파일로 분리/관리하기 위해 mini-css-extract-plugin 을 함께 사용했다.
해당 플러그인을 configure파일에 적용하는 게 감 잡기가 어려웠습니다. 결국 스택오버플로성님에게 해답을 찾음🙏
🔗 엔트리 파일 아웃풋 파일 셋팅.
// 파일경로 지정.
const ENTRY_FILE = path.resolve(__dirname, "assets", "js", "main.js");
const OUTPUT_FILE = path.resolve(__dirname, "static");
요긴 그냥 엔트리를 어떤 파일로 잡을지랑, 최종 아웃풋 파일 경로를 적당히 셋팅 해줌.
🔗 config Setting(여기가 중요!)
개념적으로 표현하자면, 아래와 같이 구성됩니다.
const config = {
entry: 엔트리파일,
mode: 'development' or 'production',
module: {
rules: [
{
// rule for js file
},
{
// rule for scss file
},
],
},
output: {
path: 아웃풋파일 경로,
filename: 파일이름.확장자,
},
plugins: 필요할 경우 플러그인 셋팅
};
module.exports = config;
전체적인 소감은, 오브젝트 형태로 필요한 부분을 용도에 맞게 설정해서 아웃풋 파일로 변환하는 과정인데, 'rules' 부분을 각 프로젝트 파일 형태에 맞게? 입맛에 맞게 세팅하는 게 진입장벽이 높지 않을까 라는 생각이 들었습니다.
📌 // rule for js file
개발 작업은 babel-js로 코드를 작성했습니다. 그래서 최종적인 html에 js파일을 이식하려면 바벨 형태가 아닌 원시? 형태의 자바스크립트로 변환이 필요합니다. 여기서 변환에 사용할 loader를 정의해 줍니다.
📌 // rule for scss file
js파일 변환과 같은 개념인데요. 개발에는 scss확장자로 css코드를 작성했기 때문에 이 부분도 loader를 삽입해서 변환을 해줍니다. css 같은 경우는, 복수의 loader를 사용해서 변환을 해주더라고요. 그래서 저도 복수의 loader를 적용했습니다.
loader를 세팅할 때 주의할 점은, 일반적으로 코드가 읽히는? 방향이(Top->Bottom) 아니라 반대로 아래에서 위 순서로 loader를 읽어 나간다는 점이 있네요.
🔗 config 부분 완료 👏👏👏
css코드를 별개 파일로 분리하기 위해 miniCssExtract를 적용했다는 점이 주목할 점이라고 생각합니다.
아마, 이미 많이 사용해보신 분들은 새롭진 않을 것 같지만 처음 접한 초보 개발자로선 매우 신선하고 좋은 자극이었습니다.
const config = {
entry: ["@babel/polyfill", ENTRY_FILE],
mode: process.env.NODE_ENV,
module: {
rules: [
{
// rule for js file
test: /\.(js)$/,
use: [
{
loader: "babel-loader",
},
],
},
{
// rule for scss file
test: /\.(scss)$/,
use: [
// miniCssExtract.loader is needed just right here!!
// It Extract Css code from bundled main.js file.
miniCssExtract.loader,
{
loader: "css-loader",
},
{
loader: "postcss-loader",
options: {
plugins: [autoprefixer({ overrideBrowserslist: "cover 99.5%" })],
},
},
{
loader: "sass-loader",
},
],
},
],
},
output: {
path: OUTPUT_FILE,
filename: "[name].js",
},
plugins: [
new miniCssExtract({
path: OUTPUT_FILE,
filename: "styles.css",
}),
],
};
module.exports = config;
4. package.json 스크립트 작성(웹팩을 실행해서 변환하기 위한 작업)
마무리죠😹
웹팩을 실행시키기 위해서는 간단하게 'webpack' 이란 커맨드를 이용할 수 있습니다.
해당 커맨드는 package.json파일의 "scripts"에 넣어놓고 사용하고 있습니다.
📋 package.json
"scripts": {
"start": "nodemon --exec babel-node init.js",
"dev:assets": "webpack --mode development -w"
}
npm을 이용한 실행방법은 아래와 같습니다.
npm run dev:assets (엔터)
요렇게 함으로써, 작업 중이던 js 또는 scss 파일을 변경/저장함에 따라서 웹팩을 끄고 다시 실행하는 수고 없이 계속 모니터링하면서 업데이트를 해줄 수가 있는 거죠.(-w 옵션이 watching 하고 있음👀)
✅ 전체 코드(참고용)
📋 webpack.configure.js
const path = require("path");
const miniCssExtract = require("mini-css-extract-plugin");
const autoprefixer = require("autoprefixer");
// WEBPACK_ENV = development --> define on script line in package.json file.
const ENTRY_FILE = path.resolve(__dirname, "assets", "js", "main.js");
const OUTPUT_FILE = path.resolve(__dirname, "static");
// mode:process.env.NODE_ENV 는 package.json에서 모드를 어떻게 정의하냐에 따라 자동으로 모드를 설정해줌.
const config = {
entry: ["@babel/polyfill", ENTRY_FILE],
mode: process.env.NODE_ENV,
module: {
rules: [
{
// rule for js file
test: /\.(js)$/,
use: [
{
loader: "babel-loader",
},
],
},
{
// rule for scss file
test: /\.(scss)$/,
use: [
// miniCssExtract.loader is needed just right here!!
// It Extract Css code from bundled main.js file.
miniCssExtract.loader,
{
loader: "css-loader",
},
{
loader: "postcss-loader",
options: {
plugins: [autoprefixer({ overrideBrowserslist: "cover 99.5%" })],
},
},
{
loader: "sass-loader",
},
],
},
],
},
output: {
path: OUTPUT_FILE,
filename: "[name].js",
},
plugins: [
new miniCssExtract({
path: OUTPUT_FILE,
filename: "styles.css",
}),
],
};
module.exports = config;
🎬 마치며
검색해보면 이미 많은 개발자 분들이 좋은 내용으로 알기 쉽게 설명해준 글이 많이 있는 것 같습니다. 하지만, 각 프로젝트에 실제로 적용하다 보면 막히는 부분들이 하나둘씩 생기기 마련인 거 같습니다.
그래서 저도 각 프로젝트에 맞게 조금씩 조금씩 공부하면서 이렇게 후기를 적어봤습니다.
더 좋은 효과적인 방법 또는 피드백이 있으시면 가감 없이 남겨주시면 더 좋은 공부가 될 것 같습니다. 감사합니다.
'[ PROJECT ] > [ WEB ]' 카테고리의 다른 글
[웹 개발 개념] 2. node.js환경 서버 생성하기 (0) | 2022.09.19 |
---|---|
웹 개발 요소 하나씩 정리. 기능 별 개념. (0) | 2022.09.16 |