gulp ๋น๋ ๋๊ตฌ๋ฅผ ์ฌ์ฉํด ์์ ํ๋ ์ค์ ์ค์ค๋ก ์ธํ ์์ ์ ์์ํด๋ณด๋๊ฒ ์ข์ ๊ฒ ๊ฐ์ ์์ํ๊ฒ ๋์๋ค.
์๊ฐ๋ณด๋ค ์ธํ ํ๋๋ฐ ์๊ฐ์ด ์ข ๊ฑธ๋ ธ๋ค๐ ๊ทธ๋๋ gulp์ ๋ํด์ ๊น๊ฒ ์์๋ณด๋ ์๊ฐ์ด ๋์๋ค.
Gulp ๋
nodejs์ npm ๊ธฐ๋ฐ์ ์น ๊ฐ๋ฐ์ ์ํ ํ๋ก์ธ์ค ์๋ํ ๋๊ตฌ ์ค ํ๋์ด๋ค.
์ฃผ๋ก ํผ๋ธ๋ฆฌ์ฑ ์์ ์ ์ฌ์ฉ๋๋ฉฐ HTML, CSS, JavaScript ํ์ผ์ ์๋์ผ๋ก ์ปดํ์ผํ๊ฑฐ๋ ์ต์ ํํ๊ณ , ํ์ผ ๋ณ๊ฒฝ์ ๊ฐ์งํ์ฌ ๋ธ๋ผ์ฐ์ ๋ฅผ ์๋ก๊ณ ์นจํ๊ฑฐ๋ ๋ผ์ด๋ธ ๋ฆฌ๋ก๋๋ฅผ ์ ๊ณตํ๋ค.
gulp๋ *stream(์คํธ๋ฆผ)๊ธฐ๋ฐ์ build system ์ด๋ค.
๋ํ node.js์ gulp์ ํน์ง์ธ ์ด๋ฒคํธ ๋ฃจํ์ *๋น๋๊ธฐI/O๋ฅผ ๊ธฐ๋ฐ์ผ๋ก gulp๊ฐ ์์ (task)์ ์ฒ๋ฆฌํ๋ค.
*stream์ด๋?
- ๋ฐ์ดํฐ๋ฅผ '์กฐ๊ฐ๋จ์' ๋ก ์ฒ๋ฆฌํ๋ ๋ฐฉ์์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ์ค์ด๊ณ ์๋๋ฅผ ๋์ธ๋ค.
- ํ์ผ์ ์ฝ๊ณ ์ฒ๋ฆฌํ๊ณ , ์ ์ฅํ๋ ๊ณผ์ ์ ์ฐ์์ ์ธ ๋ฐ์ดํฐ ํ๋ฆ(Stream) ์ผ๋ก ์ฒ๋ฆฌํ๋ค.
*๋น๋๊ธฐI/O๋?
- ์์ ์ด ๋๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ค๋ฅธ ์์ ์ ๋ณ๋ ฌ๋ก ์คํ
- Gulp๋ ๋น๋๊ธฐ๋ฅผ ํตํด ์ฌ๋ฌ task๋ฅผ ๋์์ ์คํํ๊ณ ์๋ฃ ์ฌ๋ถ๋ฅผ ์ด๋ฒคํธ๋ก ๊ด๋ฆฌ => non-blocking I/O
=> Gulp๋ ์คํธ๋ฆผ(Stream)๊ณผ ๋น๋๊ธฐ๋ฅผ ๊ฒฐํฉํ์ฌ ๋น ๋ฅด๊ณ ํจ์จ์ ์ธ ๋น๋ ์์คํ ์ ์ ๊ณตํ๋ค.
=> ์ด๋ฅผ ํตํด ๊ฐ๋ฐ์๋ ๋ฐ๋ณต์ ์ธ ์์ (CSS ์ปดํ์ผ, JS ์์ถ ๋ฑ)์ ์๋ํ ํ๊ณ ์์์ ์ ํฅ์์ํจ๋ค.
ํ๋จ๊ณ์ ๋ฐ๋ผํ๋ฉฐ gulp.js ์ตํ๊ธฐ
๋ด๊ฐ ๊ตฌํํ๊ณ ์ ํ๋ ๋ถ๋ถ
- gulp ์ค์น
- gulpfile.js
- ํ์ผ๊ตฌ์กฐ ๋ง๋ค๊ธฐ
- gulp ํ๋ฌ๊ทธ์ธ ์ค์น
1. gulp ์ค์น
โ ๏ธ์ฃผ์ํด์ผ ํ ์
gulp๋ฅผ ์ค์นํ๋ฉด ์ต์ ๋ฒ์ 5.0์ด ์ค์น๋๋๋ฐ gulp๋ ๋ฒ์ ๋ง๋ค ๋ฌธ๋ฒ์ด ๋ค๋ฅด๋ค.
๋๋ ์ ์ผ ๋ง์ด ์ด๋ค๊ณ ํ๋ 4.0 ๊ธฐ์ค์ผ๋ก ์์ ์ ์งํํ ๊ฒ์ด๋ค.
1-1) node์ npm ์ค์น
node์ npm์ ๋ง์ด ์ฌ์ฉํ๋ฏ๋ก ์ ์ญ ์ค์นํ๋๊ฒ ์ข๋ค.
node์ npm์ ๋ค๋ฅธ ๋ธ๋ก๊ทธ์๋ ์ค๋ช ์ด ๋ง์ผ๋ฏ๋ก ํจ์ค.
$ node -v // 20.17.0
$ npm -v // 10.8.2
1-2) gulp ์ค์น
gulp๋ ๋ก์ปฌ์์๋ง ๊ด๋ฆฌํ๊ธฐ ์ํด ์ ์ญ(global)์ค์น๋ ํ์ง ์์ ๊ฒ์ด๋ค.
๋ฒ์ ์ด ์ ๋๋ก ๋์ค๋ฉด gulp ์ค์น ์๋ฃ
$ npm install --save-dev gulp@4.0.2
$ gulp -v
๋ง์ผ ๋ฒ์ ์ ๋ค์ด๊ทธ๋ ์ด๋ ํด์ผ ๋๋ค๋ฉด ์ญ์ ํ ์ฌ์ค์น
$ npm uninstall ํ๋ฌ๊ทธ์ธ์ด๋ฆ
$ npm install --save-dev ํ๋ฌ๊ทธ์ธ์ด๋ฆ@๋ฒ์
2. gulpfile.js
๋จผ์ gulp 3.0 ๋ฌธ๋ฒ์ ์๊ณ ๊ฐ๋ฉด 4.0์ ๊ธ๋ฐฉ ์ดํด๋๋ค.
// Gulp ๋ชจ๋ ํธ์ถ
var gulp = require('gulp');
gulp.task('combine:js', ['first.js', 'second.js'], function() {
retrun gulp.src([
'src/js/**/*.js',
'src/j/slider/*.js',
'!src/js/slider/slider-beta.js'
])
.pipe(gulp.dest('dist/js'))
});
gulp.task('default', ['combine:js;]);
2-1) gulp.task('name', ['deps'], func)
`gulp.task` ๋ฉ์๋๋ Gulp๊ฐ ์ํํ ์ผ์ ์ ์, ์ธ ๊ฐ์ ์ ๋ฌ์ธ์๋ฅผ ๋ฐ๋๋ค.
- `name` : task ์ด๋ฆ ์ง์ , ์ด๋ฆ์๋ ๊ณต๋ฐฑ ์๋จ
- `deps` : ์๋ต ๊ฐ๋ฅ. ํ์ฌ ์ ์ธํ๊ณ ์๋ task ์ํํ๊ธฐ ์ ๋จผ์ ์คํ๋์ด์ผ ํ๋ task๋ค์ ๋ฐฐ์ด ๋ชฉ๋ก
- `func` : ์ค์ ์ฒ๋ฆฌํด์ผํ ์ผ
2-2) gulp.src(file)
- ํด๋น task์ ๋์์ด ๋๋ ํ์ผ๋ค์ ์ง์ ํด์ฃผ๋ ์ญํ
- `js/**/*.js` ๋ ํด๋์ ๋ด๋ถํด๋์ .js ํ์ผ๋ค์ ๋ชจ๋ ์ฐพ์์ ํ์ผ์ ๊ฐ์ ธ์ค๊ฒ ๋๋ค.
- ํน์ ํด๋์์ ํ์ผ๋ง ๋ฏธํฌํจ์ํค๊ณ ์ถ์ ๋ ๋ฐฐ์ด ์ '!' ํ์๋ฅผ ๋ฃ๋๋ค.
2-3) gulp.pipe(...)
- `gulp.src`์์ ๋์์ผ๋ก ์ง์ ๋ ๊ฐ ํ์ผ๋ค์ stream ํํ๋ก ์ฝ์ด๋ค์ฌ ์ฐ๊ฒฐํด์ฃผ๋ ์ญํ
- ์ฒด์ด๋์ผ๋ก ์ฌ๋ฌ๊ฐ์ pipe๋ฅผ ์๋ก ์ฐ๊ฒฐํ ์ ์๋ค.
2-4) gulp.dest()
- ํด๋น task์ ๊ฒฐ๊ณผ๋ฌผ์ด ์ถ๋ ฅ๋ ๋ชฉ์ ์ง(Destination)์ ์ค์ ํ๋ ์ญํ
ํ๋จ ๋ธ๋ก๊ทธ๋ฅผ ์ฐธ๊ณ ํ์ฌ gulp๋ฅผ 4.0์ผ๋ก ์งํํ์๋ค.
Gulp 4.0์์ ์ถ๊ฐ๋๊ณ ๋ณ๊ฒฝ๋ 4๊ฐ์ ๊ธฐ๋ฅ ์ ๋ฆฌ
Gulp 4.0 gulpfile.js ์์ฑํด ๋ณด๊ธฐ
3. ํ์ผ๊ตฌ์กฐ ๋ง๋ค๊ธฐ
- src(source) : ๋ด๊ฐ ์์ ํ ๊ณณ
- dist(distribution) : ์์ ํ ๊ฒ์ gulp์ ์ํด ๋น๋๋ ๊ณณ
๐๏ธ ํ์ผ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ
status.html : ๋ก๋ ์ ์ ์ผ ๋จผ์ ๋จ๋ ํ๋ฉด์ผ๋ก ํํฉํ ์์ ํ ๊ณณ
src/common : status ์ ๊ณตํต ํ์ผ ์ ์ฅ
src/pc : pc ํ์ผ๋ง ์ ์ฉ๋๋ ๊ณณ
dist/pc : src/pc ๋น๋๋ ๊ณณ
src/
|- common/
|- css/
|- fonts/
|- js/
|- pc/
|- css/
|- html/
|- include/
|- js/
|- status.html
dist/
node-modules
gulpfile.js
package.json
package-lock.json
ํ๋ฌ๊ทธ์ธ ์ค์น
$ npm install ํ๋ฌ๊ทธ์ธ --save-dev
// package.json
{
"devDependencies": {
"browser-sync": "^3.0.3",
"gulp": "^5.0.0",
"gulp-concat": "^2.6.1",
"gulp-file-include": "^2.3.0",
"gulp-sass": "^6.0.0",
"gulp-sourcemaps": "^3.0.0",
"gulp-uglify": "^3.0.2",
"gulp-watch": "^4.3.11",
"sass": "^1.84.0"
},
"dependencies": {
"del": "^5.0.0"
}
}
/* gulpfile.js */
// series : task ์์ฐจ์ ์ผ๋ก ์คํ
// parallel : task ๋ณ๋ ฌ๋ก ์คํ
// watch : ํ์ผ ์์ ์ ๋ฐ๋ก ํ์ธ
const { src, dest, series, parallel, watch } = require('gulp');
// dist ํด๋ ์ ๋ฆฌ
const del = require('del');
// HTML ํ
ํ๋ฆฟ ์์คํ
๊ตฌํ
const fileInclude = require('gulp-file-include');
// ์ฌ๋ฌ ํ์ผ ๋ณํฉ
const concat = require('gulp-concat');
// JavaScript ์์ถ
const uglify = require('gulp-uglify');
// ๋ก์ปฌ ์๋ฒ ์์ฑ ๋ฐ ๋ธ๋ผ์ฐ์ ๋๊ธฐํ
const browserSync = require('browser-sync').create();
// SCSSํ์ผ์ CSS๋ก ์ปดํ์ผ
const sass = require('gulp-sass')(require('sass'));
// ์ปดํ์ผ๋ ์ฝ๋์์ ์๋ณธ ์์ค์ฝ๋ ์์น ์ถ์
const soruceMaps = require('gulp-sourcemaps');
// PC ์์
์ฉ ํด๋ ํ์ผ path
const pathPc = {
scss: 'src/pc/css/*.scss',
js: 'src/pc/js/*.js',
html: 'src/pc/html/*.html'
}
// dist ํด๋ ์ ๋ฆฌ
function clean() {
return del(['dist']);
}
function buildStatus() {
return src([
'src/status.html',
])
.pipe(dest('dist'))
.pipe(browserSync.stream())
}
function commonCss() {
return src([
'src/common/css/**/*.css',
])
.pipe(dest('dist/common/css'))
.pipe(browserSync.stream())
}
function commonJs() {
return src([
'src/common/js/**/*.js'
])
.pipe(uglify({
mangle: false,
compress: { drop_console: false },
output: {
comments: 'some',
beautify: false
},
}))
.pipe(dest('dist/common/js'))
.pipe(browserSync.stream())
}
function buildStyle() {
return src([
pathPc.scss,
// 'src/pc/css/**/*.css'
])
.pipe(soruceMaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(concat('pc-common.css'))
.pipe(soruceMaps.write())
.pipe(dest('dist/pc/css'))
.pipe(browserSync.stream())
}
function buildHtml() {
return src([
pathPc.html,
// 'src/pc/html/include/*.html'
])
.pipe(fileInclude({
prefix: '@@',
}))
.pipe(dest('dist/pc/html'))
.pipe(browserSync.stream())
}
function buildScript() {
return src(pathPc.js)
.pipe(uglify({
mangle: false,
compress: { drop_console: false },
output: {
comments: 'some',
beautify: false
},
}))
.pipe(concat('pc-common.js'))
.pipe(dest('dist/pc/js'))
.pipe(browserSync.stream())
}
function setBrowserSync() {
browserSync.init({
server: {
baseDir: './dist', // ์๋ฒ ๋ฃจํธ ๋๋ ํ ๋ฆฌ
index: 'status.html'
},
port: 3000,
open: true,
})
}
function fileWatch() {
watch('src/status.html', buildStatus);
watch('src/common/css/*.css', commonCss);
watch('src/common/js/**/*.js', commonJs);
watch(pathPc.scss, buildStyle);
watch(pathPc.html, buildHtml);
watch(pathPc.js, buildScript);
}
exports.default = series(
clean,
parallel(buildStatus, commonCss, commonJs, buildStyle, buildHtml, buildScript),
parallel(setBrowserSync, fileWatch)
)
โ ๏ธError
`gulp-sass`๊ฐ Dart Sass์ ๋ ๊ฑฐ์ JS API๋ฅผ ์ฌ์ฉํ๊ณ ์์ด ๋ฐ์ํ ๋ฌธ์ ๋ผ๊ณ ํ๋ค.
- ๋ฌธ์ ์์ธ
- Dart Sass 1.45.0 ๋ถํฐ Morden JS API๊ฐ ๋์ ๋์ด ๊ธฐ์กด ๋ ๊ฑฐ์ JS API๋ ๋ ์ด์ ๊ถ์ฅ๋์ง ์๋๋ค.
- `gulp-sass` ๊ฐ Dart Sass์ Mordern API๋ฅผ ์ง์ํ์ง ์๊ฑฐ๋ ์ค์ ์ด ์ฌ๋ฐ๋ฅด์ง ์์ ๊ฒฝ์ฐ ๊ฒฝ๊ณ ๋ฐ์ - ํด๊ฒฐ๋ฐฉ๋ฒ
- `gulp-sass` ๋ฅผ ์ต์ ๋ฒ์ ์ผ๋ก ์ ๋ฐ์ดํธํ๊ณ , Dart Sass๋ฅผ ๋ช ์์ ์ผ๋ก ์ฌ์ฉํ๋๋ก ์ค์ .
$ npm install gulp-sass@latest sass@latest --save-dev
- `gulp-sass` : Gulp ์์ Sass๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ํ๋ฌ๊ทธ์ธ.
- `sass` : Dart Sass ์ปดํ์ผ๋ฌ(Mordern API ์ง์)