์ด ํต ์คํํธ ๊ฐ์ด๋๋ gulp๋ก TypeScript๋ฅผ ๋น๋ํ ๋ค์ Browserify, uglify ๋๋ Watchify๋ฅผ gulp ํ์ดํ ๋ผ์ธ์ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ์๋ ค์ค๋๋ค. ๋ํ Babelify๋ฅผ ์ฌ์ฉํ์ฌ Babel ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ์๋ ค์ค๋๋ค.
npm๊ณผ Node.js๋ ์ด๋ฏธ ์ฌ์ฉํ๊ณ ์๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
์๋ก์ด ๋๋ ํฐ๋ฆฌ๋ก ์์ํฉ์๋ค.
๋น์ฅ์ proj
๋ผ๊ณ ์ด๋ฆ์ ๋ถ์ด๊ฒ ์ง๋ง ์ํ๋ ๋๋ก ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
mkdir proj
cd proj
์์ํ๊ธฐ ์ํด, ๋ค์๊ณผ ๊ฐ์ด ํ๋ก์ ํธ๋ฅผ ๊ตฌ์กฐํํด์ผ ํฉ๋๋ค:
proj/
โโ src/
โโ dist/
TypeScript ํ์ผ์ src
ํด๋์์ ์์ํ์ฌ TypeScript ์ปดํ์ผ๋ฌ๋ฅผ ํตํด ์คํ๋๊ณ dist
์์ ๋๋ฉ๋๋ค.
์ด๊ฒ์ ๊ณจ๊ฒฉ์ผ๋ก ํฉ๋๋ค:
mkdir src
mkdir dist
์ด์ ์ด ํด๋๋ฅผ npm ํจํค์ง๋ก ๋ฐ๊ฟ ๊ฒ์ ๋๋ค.
npm init
์ผ๋ จ์ ์๋ฆผ์ ๋ฐ๊ฒ ๋ ๊ฒ์
๋๋ค.
entry point๋ฅผ ์ ์ธํ๊ณ ๋ ๊ธฐ๋ณธ๊ฐ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
entry point๋ก ./dist/main.js
๋ฅผ ์ฌ์ฉํฉ๋๋ค.
package.json
ํ์ผ๋ก ๋์๊ฐ์ ์ธ์ ๋ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
์ด์ ๋ npm install
์ ์ฌ์ฉํ์ฌ ํจํค์ง๋ฅผ ์ค์นํ ์ ์์ต๋๋ค.
๋จผ์ gulp-cli
๋ฅผ ์ ์ญ์ผ๋ก ์ค์นํ์ญ์์ค (Unix ์์คํ
์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ npm install
๋ช
๋ น ์์ sudo
๋ฅผ ๋ถ์ฌ์ผ ํ ์๋ ์์ต๋๋ค).
npm install -g gulp-cli
๊ทธ๋ฐ ๋ค์ ํ๋ก์ ํธ์ ๊ฐ๋ฐ ์์กด์ฑ์ typescript
, gulp
๋ฐ gulp-typescript
๋ฅผ ์ค์นํ์ญ์์ค.
Gulp-typescript๋ TypeScript์ gulp ํ๋ฌ๊ทธ์ธ์
๋๋ค.
npm install --save-dev typescript gulp gulp-typescript
Hello World ํ๋ก๊ทธ๋จ์ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
src
์ main.ts
ํ์ผ์ ๋ง๋ญ๋๋ค :
function hello(compiler: string) {
console.log(`Hello from ${compiler}`);
}
hello("TypeScript");
proj
์ด๋ผ๋ ํ๋ก์ ํธ ๋ฃจํธ์ tsconfig.json
ํ์ผ์ ์์ฑํฉ๋๋ค:
{
"files": [
"src/main.ts"
],
"compilerOptions": {
"noImplicitAny": true,
"target": "es5"
}
}
ํ๋ก์ ํธ ๋ฃจํธ์ gulpfile.js
ํ์ผ์ ๋ง๋ญ๋๋ค:
var gulp = require("gulp");
var ts = require("gulp-typescript");
var tsProject = ts.createProject("tsconfig.json");
gulp.task("default", function () {
return tsProject.src()
.pipe(tsProject())
.js.pipe(gulp.dest("dist"));
});
gulp
node dist/main.js
ํ๋ก๊ทธ๋จ์ "Hello from TypeScript!"๋ฅผ ์ถ๋ ฅํด์ผ ํฉ๋๋ค.
Browserify๋ฅผ ์์ํ๊ธฐ ์ ์ ์ฝ๋๋ฅผ ๋ง๋ค๊ณ ๋ฏน์ค์ ๋ชจ๋์ ์ถ๊ฐํด ๋ณด๊ฒ ์ต๋๋ค.
์ด๊ฒ์ ์ค์ ์ฑ์์ ์ฌ์ฉํ๊ธฐ ์ฌ์ด ๊ตฌ์กฐ์
๋๋ค.
src/greet.ts
ํ์ผ์ ๋ง๋ญ๋๋ค :
export function sayHello(name: string) {
return `Hello from ${name}`;
}
์ด์ src/main.ts
์ sayHello
๋ฅผ greet.ts
์์ import ํ๋๋ก ๋ณ๊ฒฝํฉ๋๋ค:
import { sayHello } from "./greet";
console.log(sayHello("TypeScript"));
๋ง์ง๋ง์ผ๋ก src/greet.ts
๋ฅผ tsconfig.json
์ ์ถ๊ฐํ์ญ์์ค:
{
"files": [
"src/main.ts",
"src/greet.ts"
],
"compilerOptions": {
"noImplicitAny": true,
"target": "es5"
}
}
gulp
์ ์คํํ๊ณ Node์์ ํ
์คํธํ์ฌ ๋ชจ๋์ด ์๋ํ๋์ง ํ์ธํ์ญ์์ค:
gulp
node dist/main.js
ES2015 ๋ชจ๋ ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ง๋ง TypeScript๋ Node๊ฐ ์ฌ์ฉํ๋ CommonJS ๋ชจ๋์ ๋ฐฉ์ถํ์ต๋๋ค.
์ด ํํ ๋ฆฌ์ผ์์๋ CommonJS๋ฅผ ๊ณ์ ์ฌ์ฉํ๊ฒ ์ง๋ง options ๊ฐ์ฒด์ module
์ ์ค์ ํ์ฌ ์ด๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
์ด์ ์ด ํ๋ก์ ํธ๋ฅผ Node์์ ๋ธ๋ผ์ฐ์ ๋ก ์ด๋ํ๊ฒ ์ต๋๋ค.
์ด๋ฅผ ์ํด ๋ชจ๋ ๋ชจ๋์ ํ๋์ JavaScript ํ์ผ๋ก ๋ฒ๋ค๋ง ํ๊ณ ์ ํฉ๋๋ค.
๋คํํ๋ ์ ํํ Browserify๊ฐ ํ๋ ์ผ์
๋๋ค.
๋ ์ข์ ๊ฒ์ ๋
ธ๋์์ ์ฌ์ฉํ๋ CommonJS ๋ชจ๋ ์์คํ
์ TypeScript์์ ์ฌ์ฉํ ์ ์๋ค๋ ๊ฒ์
๋๋ค.
์ฆ TypeScript์ Node ์ค์ ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ณ๊ฒฝ๋์ง ์์ ๋ธ๋ผ์ฐ์ ๋ก ์ ์ก๋๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๋จผ์ browserify, tsify ๋ฐ vinyl-source-stream์ ์ค์นํ์ญ์์ค.
tsify๋ gulp-typescript์ฒ๋ผ TypeScript ์ปดํ์ผ๋ฌ์ ์ ๊ทผํ ์ ์๋ Browserify ํ๋ฌ๊ทธ์ธ์
๋๋ค.
vinyl-source-stream์ ์ฌ์ฉํ๋ฉด Browserify์ ํ์ผ ์ถ๋ ฅ์ gulp์์ vinyl์ผ๋ก ์ธ์ํ๋ ํ์์ผ๋ก ๋ค์ ๋ณํํ ์ ์์ต๋๋ค.
npm install --save-dev browserify tsify vinyl-source-stream
src
์ index.html
ํ์ผ์ ์์ฑํฉ๋๋ค :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World!</title>
</head>
<body>
<p id="greeting">Loading ...</p>
<script src="bundle.js"></script>
</body>
</html>
์ด์ ํ์ด์ง๋ฅผ ์
๋ฐ์ดํธํ๊ธฐ ์ํด main.ts
๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค:
import { sayHello } from "./greet";
function showHello(divName: string, name: string) {
const elt = document.getElementById(divName);
elt.innerText = sayHello(name);
}
showHello("greeting", "TypeScript");
showHello
ํธ์ถ์ sayHello
๋ฅผ ํธ์ถํ์ฌ paragraph ํ
์คํธ๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค.
์ด์ gulpfile์ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๊ฒฝํ์ญ์์ค :
var gulp = require('gulp');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var tsify = require('tsify');
var paths = {
pages: ['src/*.html']
};
gulp.task('copy-html', function () {
return gulp.src(paths.pages)
.pipe(gulp.dest('dist'));
});
gulp.task('default', gulp.series(gulp.parallel('copy-html'), function () {
return browserify({
basedir: '.',
debug: true,
entries: ['src/main.ts'],
cache: {},
packageCache: {}
})
.plugin(tsify)
.bundle()
.pipe(source('bundle.js'))
.pipe(gulp.dest('dist'));
}));
copy-html
ํ์คํฌ๋ฅผ ์ถ๊ฐํ๊ณ default
์ ์์กด์ฑ์ผ๋ก ์ถ๊ฐํฉ๋๋ค.
default
๊ฐ ์คํ๋ ๋๋ง๋ค copy-html
์ด ๋จผ์ ์คํ๋์ด์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
๋ํ default
๋ฅผ gulp-typescript ๋์ tsify ํ๋ฌ๊ทธ์ธ์ผ๋ก Browserify๋ฅผ ํธ์ถํ๋๋ก ๋ณ๊ฒฝํ์ต๋๋ค.
ํธ๋ฆฌํ๊ฒ๋ ๋ ๋ชจ๋ TypeScript ์ปดํ์ผ๋ฌ์ ๋์ผํ options ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค.
bundle
์ ํธ์ถํ ํ source
(vinil-source-stream์ ๋ํ ๋ณ์นญ)๋ฅผ ์ฌ์ฉํ์ฌ ์ถ๋ ฅ ๋ฒ๋ค bundle.js
์ ์ด๋ฆ์ ์ง์ ํฉ๋๋ค.
gulp๋ฅผ ์คํํ๊ณ ๋ธ๋ผ์ฐ์ ์์ dist/index.html
์ ์ด์ด ํ์ด์ง๋ฅผ ํ์ธํ์ธ์.
ํ์ด์ง์ "Hello from TypeScript"๊ฐ ํ์๋์ด์ผ ํฉ๋๋ค.
Browserify์ debug : true
๋ฅผ ์ง์ ํ ๊ฒ์ ์ฃผ๋ชฉํ์ญ์์ค.
์ด๋ก ์ธํด tsify๋ ๋ฒ๋ค๋ JavaScript ํ์ผ ์์ ์์ค ๋งต์ ๋ด๋ณด๋
๋๋ค.
์์ค ๋งต์ ์ฌ์ฉํ๋ฉด ๋ฒ๋ค๋ก ์ ๊ณต๋ JavaScript ๋์ ๋ธ๋ผ์ฐ์ ์์ ์๋ณธ TypeScript ์ฝ๋๋ฅผ ๋๋ฒ๊น
ํ ์ ์์ต๋๋ค.
๋ธ๋ผ์ฐ์ ์ ๋๋ฒ๊ฑฐ๋ฅผ ์ด๊ณ main.ts
์์ ๋ธ๋ ์ดํฌ ํฌ์ธํธ์ ๋ฃ์ผ๋ฉด ์์ค ๋งต์ด ์๋ํ๋์ง ํ
์คํธํ ์ ์์ต๋๋ค.
ํ์ด์ง๋ฅผ ์๋ก ๊ณ ์นจ ํ๋ฉด ๋ธ๋ ์ดํฌ ํฌ์ธํธ๊ฐ ํ์ด์ง๋ฅผ ์ผ์ ์ค์งํ๊ณ greet.ts
๋ฅผ ๋๋ฒ๊น
ํ ์ ์์ด์ผ ํฉ๋๋ค.
์ด์ ์ฝ๋๋ฅผ Browserify์ ๋ฌถ์ด์ tsify ํ์ผ๋ฏ๋ก browserify ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํ์ฌ ๋น๋์ ๋ค์ํ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
-
Watchify๊ฐ gulp๋ฅผ ๊ณ์ ์คํํ๋ฉฐ ํ์ผ์ ์ ์ฅํ ๋๋ง๋ค ์ ์ฐจ์ ์ผ๋ก ์ปดํ์ผํฉ๋๋ค.
์ด๋ฅผ ํตํด ๋ธ๋ผ์ฐ์ ์์ ํธ์ง-์ ์ฅ-์๋ก๊ณ ์นจ ์ฌ์ดํด์ ๊ณ์ ์งํํ ์ ์์ต๋๋ค. -
Babel์ ES2015 ์ด์์ ES5 ๋ฐ ES3์ผ๋ก ๋ณํํ๋ ๋งค์ฐ ์ ์ฐํ ์ปดํ์ผ๋ฌ์ ๋๋ค.
๋ฐ๋ผ์ TypeScript์์ ์ง์ํ์ง ์๋ ๊ด๋ฒ์ํ ๋ง์ถคํ ๋ณํ์ ์ถ๊ฐํ ์ ์์ต๋๋ค. -
Uglify๋ ๋ค์ด๋ก๋ ์๊ฐ์ ์ค์ด๋๋ก ์ฝ๋๋ฅผ ์์ถํฉ๋๋ค.
Watchify๋ก ๋ฐฑ๊ทธ๋ผ์ด๋ ์ปดํ์ผ์ ์์ํ๊ฒ ์ต๋๋ค :
npm install --save-dev watchify fancy-log
์ด์ gulpfile์ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๊ฒฝํ์ญ์์ค :
var gulp = require('gulp');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var watchify = require('watchify');
var tsify = require('tsify');
var fancy_log = require('fancy-log');
var paths = {
pages: ['src/*.html']
};
var watchedBrowserify = watchify(browserify({
basedir: '.',
debug: true,
entries: ['src/main.ts'],
cache: {},
packageCache: {}
}).plugin(tsify));
gulp.task('copy-html', function () {
return gulp.src(paths.pages)
.pipe(gulp.dest('dist'));
});
function bundle() {
return watchedBrowserify
.bundle()
.on('error', fancy_log)
.pipe(source('bundle.js'))
.pipe(gulp.dest('dist'));
}
gulp.task('default', gulp.series(gulp.parallel('copy-html'), bundle));
watchedBrowserify.on('update', bundle);
watchedBrowserify.on('log', fancy_log);
์ฌ๊ธฐ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ธ ๊ฐ์ง ๋ณ๊ฒฝ ์ฌํญ์ด ์์ง๋ง ์ฝ๋๋ฅผ ์ฝ๊ฐ ๋ฆฌํฉํ ๋งํด์ผํฉ๋๋ค.
watchify
์ ๋ํ ํธ์ถ์์browserify
์ธ์คํด์ค๋ฅผ ๊ฐ์ธ๊ณ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์ ์งํ์ต๋๋ค.watchedBrowserify.on('update', bundle);
์ ํธ์ถํ์ฌ Browserify ๊ฐ TypeScript ํ์ผ ์ค ํ๋๊ฐ ๋ณ๊ฒฝ๋ ๋๋ง๋คbundle
ํจ์๋ฅผ ์คํํ๋๋ก ํ์ต๋๋ค.watchedBrowserify.on('log', fancy_log);
์ ํธ์ถํ์ฌ ์ฝ์์ ๊ธฐ๋กํ์ต๋๋ค.
(1)๊ณผ (2)๋ default
์์
์์ browserify
๋ฅผ ํธ์ถํด์ผ ํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค.
Watchify์ Gulp ๋ชจ๋ ํธ์ถํด์ผ ํ๊ธฐ ๋๋ฌธ์ default
ํจ์์ ์ด๋ฆ์ ์ฃผ์ด์ผ ํฉ๋๋ค.
(3)์ ์ฌ์ฉํ ๋ก๊น
์ ์ถ๊ฐํ๋ ๊ฒ์ ์ ํ ์ฌํญ์ด์ง๋ง ์ค์ ์ ๋๋ฒ๊น
ํ๋ ๋ฐ ๋งค์ฐ ์ ์ฉํฉ๋๋ค.
์ด์ Gulp๋ฅผ ์คํํ๋ฉด ์์ํด์ผ ํ๊ณ ๊ณ์ ์คํ๋ฉ๋๋ค.
main.ts
์์ showHello
์ ๋ํ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ๊ณ ์ ์ฅํ์ญ์์ค.
๋ค์๊ณผ ๊ฐ์ ์ถ๋ ฅ์ด ํ์๋์ด์ผ ํฉ๋๋ค:
proj$ gulp
[10:34:20] Using gulpfile ~/src/proj/gulpfile.js
[10:34:20] Starting 'copy-html'...
[10:34:20] Finished 'copy-html' after 26 ms
[10:34:20] Starting 'default'...
[10:34:21] 2824 bytes written (0.13 seconds)
[10:34:21] Finished 'default' after 1.36 s
[10:35:22] 2261 bytes written (0.02 seconds)
[10:35:24] 2808 bytes written (0.05 seconds)
๋จผ์ Uglify๋ฅผ ์ค์นํ์ญ์์ค.
Uglify์ ์์ ์ ์ฝ๋๋ฅผ ์์ถํ๊ธฐ ์ํ ๊ฒ์ด๋ฏ๋ก ์์ค ๋งต์ ์ ์งํ๋ ค๋ฉด vinyl-buffer์ gulp-sourcemaps๋ ์ค์นํด์ผ ํฉ๋๋ค.
npm install --save-dev gulp-uglify vinyl-buffer gulp-sourcemaps
์ด์ gulpfile์ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๊ฒฝํ์ญ์์ค :
var gulp = require('gulp');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var tsify = require('tsify');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var buffer = require('vinyl-buffer');
var paths = {
pages: ['src/*.html']
};
gulp.task('copy-html', function () {
return gulp.src(paths.pages)
.pipe(gulp.dest('dist'));
});
gulp.task('default', gulp.series(gulp.parallel('copy-html'), function () {
return browserify({
basedir: '.',
debug: true,
entries: ['src/main.ts'],
cache: {},
packageCache: {}
})
.plugin(tsify)
.bundle()
.pipe(source('bundle.js'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('dist'));
}));
uglify
์์ฒด์๋ ํ๋์ ํธ์ถ๋ง ์์ต๋๋ค โ buffer
์ sourcemaps
์ ๋ํ ํธ์ถ์ sourcemaps์ด ๊ณ์ ์๋ํ๋์ง ํ์ธํ๊ธฐ ์ํด ์กด์ฌํฉ๋๋ค.
์ด๋ฌํ ํธ์ถ์ ํตํด ์ด์ ๊ณผ ๊ฐ์ด ์ธ๋ผ์ธ ์์ค ๋งต์ ์ฌ์ฉํ๋ ๋์ ๋ณ๋์ ์์ค ๋งต ํ์ผ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ด์ Gulp๋ฅผ ์คํํ๊ณ bundle.js
๊ฐ ๋๋
ํ๋ก ์์ถ๋๋์ง ํ์ธํ์ญ์์ค :
gulp
cat dist/bundle.js
๋จผ์ ES2015 ์ ์ฉ Babelify ๋ฐ Babel preset์ ์ค์นํ์ญ์์ค.
Uglify์ฒ๋ผ Babelify๋ ์ฝ๋๋ฅผ ์๋ง์ผ๋ก ๋ง๋ค๊ธฐ ๋๋ฌธ์ vinyl-buffer์ gulp-sourcemaps์ด ํ์ํฉ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก Babelify๋ ํ์ฅ์๊ฐ .js
, .es
, .es6
๋ฐ .jsx
์ธ ํ์ผ๋ง ์ฒ๋ฆฌํ๋ฏ๋ก Babelify์ ์ต์
์ผ๋ก .ts
ํ์ฅ์๋ฅผ ์ถ๊ฐํด์ผ ํฉ๋๋ค.
npm install --save-dev babelify@8 babel-core babel-preset-es2015 vinyl-buffer gulp-sourcemaps
์ด์ gulpfile์ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๊ฒฝํ์ญ์์ค :
var gulp = require('gulp');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var tsify = require('tsify');
var sourcemaps = require('gulp-sourcemaps');
var buffer = require('vinyl-buffer');
var paths = {
pages: ['src/*.html']
};
gulp.task('copy-html', function () {
return gulp.src(paths.pages)
.pipe(gulp.dest('dist'));
});
gulp.task('default', gulp.series(gulp.parallel('copy-html'), function () {
return browserify({
basedir: '.',
debug: true,
entries: ['src/main.ts'],
cache: {},
packageCache: {}
})
.plugin(tsify)
.transform('babelify', {
presets: ['es2015'],
extensions: ['.ts']
})
.bundle()
.pipe(source('bundle.js'))
.pipe(buffer())
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('dist'));
}));
TypeScript ๋์ ES2015๋ ํ์ํฉ๋๋ค.
Babel์ TypeScript์์ ๋ด๋ณด๋ด๋ ES2015 ์ฝ๋์์ ES5๋ฅผ ์์ฑํฉ๋๋ค.
tsconfig.json
์ ์์ ํฉ์๋ค:
{
"files": [
"src/main.ts"
],
"compilerOptions": {
"noImplicitAny": true,
"target": "es2015"
}
}
๊ฐ๋จํ ์คํฌ๋ฆฝํธ์ ๊ฒฝ์ฐ Babel์ ES5 ๊ฒฐ๊ณผ๋ฌผ์ TypeScript์ ๊ฒฐ๊ณผ๋ฌผ๊ณผ ๊ฑฐ์ ๊ฐ์์ผ ํฉ๋๋ค.