들어가기에 앞서..

가끔 친구와 술을 마실 때면 개발 이야기를 하곤 합니다. (거의 술 마실 때마다 항상 하는 것 같기도 하고;;)
하여튼 대화 도중에 `세미콜론`에 대한 이야기가 나왔습니다.

 

"

파이썬으로 개발을 많이 하다가 자바스크립트를 해야 할 때면 세미콜론 정말 귀찮아.
자꾸 빼먹게 돼서 어디는 들어가 있고 어디는 안들어가 있고...
이거 정말 꼭 붙여야 하는 걸까?
자바스크립트는 세미콜론 없어도 문제 없잖아??
자바같이 엄격한 애들은 에러 나서 넣긴 하는데, 굳이 자바스크립트는..

"

 

여기서 간단히 설명하면, 파이썬은 세미콜론이 아닌 들여쓰기를 통해 구문구분이 됩니다.
따라서 세미콜론이 필요 없습니다.

 

저는 프로그래밍을 배우던…. 새싹일 때부터 많은 강사가,
그리고 만났던 사수들이 예외사항이 생길 수 있다며 세미콜론을 꼭 붙이라고 했습니다.
그래서 의심조차 하지 않고 늘 사용해왔고 심지어 회사 컨벤션에 포함된 경우도 봤습니다.
그리고 플러그인 프로그래밍할 때 타 플러그인과의 충돌을 막기 위해 세미콜론으로 시작하는 예도 종종 봤습니다.

 

근데 이게 정말 필수였을까요?
궁금증을 해결해보기 위해 찾아봤습니다.

 

 

 

 

본문

세미콜론을 사용하지 않고 개발한다고 해서 구문 구분 시 세미콜론이 없는 것이 아닙니다.
인터프리터과정에서 자동으로 구문 구분을 해야 하는 곳에 세미콜론을 붙여주기 때문입니다.
이 과정을 세미콜론 자동삽입(ASI, automatic semicolon insertion)이라고 합니다.
그리고 이 과정이 존재하기에 논쟁은 시작되었을 것 같습니다.
자동으로 붙여주는 것을 왜 우리가 넣어야 하는가.

많은 사람이 혹.시.모.르.는 예외사항을 대비하라고 합니다.
하지만 

반대 견해의 사람들은 자동삽입이 되는 동작을 이해하고 코딩하면 문제가 되지 않을 것이라고 합니다.

 

예시

return
true;

이때 개발자는 return; true; 보겠지만, 인터프리터에서는 return true; 인식합니다.
하지만 이것도 자동삽입되는 부분의 동작을 이해하면 문제가 되지 않을 수도 있습니다.

그렇습니다. 사용하지 말자는 사람의 의견대로 인터프리터에 자동삽입의 코딩스타일을 정립할 수 있다면 세미콜론을 강제하지 않아도 됨을 말합니다.

 

정답이 없기 때문에 빠르게 결론으로 가겠습니다.

 

짧게보는 이야기

1. 자바스크립트는 구문구분 시 세미콜론을 넣어야 한다
2. 세미콜론을 넣지 않을 때 인터프리터가 자동으로 넣어준다.
3. 자동으로 넣어줄 때 오류가 생길 예외사항에 대해 과거에 많은 사람이 세미콜론을 강제했다.
4. 인터프리터의 과정을 이해하여 코딩할 경우 세미콜론이 없어도 충분히 예외사항이 생기지 않는다.
5. 인터프리터의 과정에 따라 코딩스타일이 정립된다면 세미콜론을 강제할 필요가 없다.
6. 하지만 여전히 논쟁거리

 

 

 

 

결론

자바스크립트의 기본 규칙은 세미콜론을 붙이는 것이며

과거에 나온 자바스크립트 교재를 보면 대부분 세미콜론을 넣는 것이 바람직하다고 설명합니다.
자동삽입에 대한 이해가 없어도(할 필요도 없이) 세미콜론을 넣게 되면 문제를 미리 방지할 수 있습니다.
세미콜론을 마지막으로 구문이 구분되니 가독성에도 좋습니다.
그리고 사용해서 문제가 되는 것은 없으나 반대의 경우 문제가 될 경우가 조금이라도 있다면 개발자는 예외사항도 무시하면 안 된다 생각합니다.

(안전한걸 하지 않을 이유는 없겠죠.)

 

하지만 저와 친구가 한 대화의 현실적인 결론은 아래와 같습니다.
물론 세미콜론을 넣는 스타일로 정립된 저는 사용하자는 편에 서 있지만요.

 

"

회사 컨벤션에 쓰라고 돼 있으면 쓰고 말라면 만다.
그 외 개인적인 코딩은 개인이 책임지기 때문에 알아서 한다.

"

 

 

 

 

논쟁거리

okky 홈페이지에서 논쟁인 부분을 캡처해서 가져왔습니다.

대화의 출처는 ooky이며 저작권 문제가 있다면 삭제하겠습니다.

https://okky.kr/article/448378

 


참고

https://bakyeono.net/post/2018-01-19-javascript-use-semicolon-or-not.html

https://blog.hanaoto.me/semicolon_javascript/

https://weicomes.tistory.com/135

https://medium.com/@deptno/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%BB%A8%EB%B2%A4%EC%85%98-%EC%84%B8%EB%AF%B8%EC%BD%9C%EB%A1%A0-%EC%9D%80-%ED%95%84%EC%9A%94%ED%95%9C%EA%B0%80-e30f31461224

https://okky.kr/article/448378

 

 

 

(ES6에서는 클래스 문법이 생겼다지만. 동작 및 방식에 대해 아직 공부하지 않았으므로 언급하지 않고 다음으로 미루겠습니다.)

 

 

자바(Java)나 파이썬(Python) 등, 보통 객체지향언어들은 클래스(Class) 기반의 언어라고 합니다.
하지만 자바스크립트는 프로토타입 기반(Prototype-based programming)의 객체지향언어입니다.

그래서 자바스크립트로 프로그래밍을 하다 보면 

필수적으로 프로토타입 기반 프로그래밍이라는 말을 접하게 됩니다.


자바스크립트 그 자체로 불릴 만큼 중요한 개념인 프로토타입에 관해서 공부해보겠습니다.

 

 

 

프로토타입(Prototype)

"
원래의 형태 또는 전형적인 예, 기초 또는 표준이다.
시제품이 나오기 전의 제품의 원형으로……. 블라블라….
중요한 기능들이 포함된 시스템의 초기 모델이다.
"

- 위키백과

 

프로토타입에 대한 핵심 단어들을 기억하고 넘어가 보겠습니다.
핵심단어는 [기초, 표준, 제품의 원형, 초기 모델]입니다.

 

 

자바스크립트에서 프로토타입의 개념은 프로토타입 객체(Prototype Object), 프로토타입 링크(Prototype Link)를 통틀어 말합니다.

 

자바스크립트에서 객체가 생성될때, 생성된 객체의 부모가 되는 객체의 원형을 프로토타입 객체(Prototype Object)라고 하며 생성된 객체와 부모 객체와의 참조를 이어주는 링크를 프로토타입 링크(Prototype Link)라고 합니다.

그리고 이 프로토타입 객체를 프로토타입이라고 말하며 객체지향의 상속개념과 같이 부모객체의 속성, 메소드를 상속받아 객체를 재생성하며 프로그래밍하는 기법을 프로토타입 프로그래밍(Prototype-based programming)이라고합니다.

 

 

 

프로토타입 기반 프로그래밍(Prototype-based programming)

다른 명칭으로는 

클래스 리스(class-less) 프로그래밍,

프로토타입 지향(prototype-oriented) 프로그래밍,

인스턴스(instance-based) 프로그래밍이라고 불리기도 합니다.

프로토타입 프로그래밍은 자바 클래스의 상속을 흉내 내는 방식의 프로그래밍인데, 클래스와의 차이점을 간단히 확인하고 넘어가겠습니다.


클래스 기반

클래스라는 추상화된 개념을 선언한 뒤, 이 클래스를 기반으로 객체에 상속을 지원합니다.
여기서 주목해야 할 점은 객체의 형식이 정의된 클래스는 객체가 아닌 개념이라는 점입니다.

// 1. 클래스 정의
public class Person{
	public string country = "korea";
    public string name;
    public int age;

    // 2. 클래스 생성자 정의
    public Person(string name, int age){
        this.name = name;
        this.age = age;
    }
}

// 3. 객체 생성
Person boy = new Person("yoonhee", "12");

 

프로토타입 기반

프로토타입 원형 객체를 생성한 뒤, 이 객체를 이용해서 클래스의 상속을 흉내 냅니다.

여기서 주목해야 할 점은 프로토타입은 객체입니다.

// 1. 프로토타입 객체 정의
var  base = function(){
    this.country = "korea"
}

// 2. 프로토타입 객체 생성자 정의
var Person = function(name, age){
    this.name = name;
    this.age = age;
}

// 3. 생성자에 프로토타입 상속
Person.prototype = base;

// 4. 객체 생성
var boy = new Person("yoonhee", "12");

 

매우 유사해 보이지만 프로토타입에서는 생성자에 프로토타입을 상속받는 절차가 필요한 것을 확인할 수 있습니다.

 

 

자바의 클래스를 흉내낸다고 하는 이유는,

클래스는 개념이며 이 개념을 통해 객체를 생성하여 인스턴스로 만듭니다.

하지만 프로토타입은 클래스와 같은 개발 방식을 흉내내지만, 인스턴스입니다.

 

클래스는 객체의 형식이 정의된 개념

프로토타입은 객체

 

인스턴스란(Instance)?

더보기

객체 지향 프로그래밍에서 인스턴스는 해당 클래스의 구조로 컴퓨터 저장공간에서 할당된 실체를 의미한다.

 

 

 

프로토타입 객체(Prototype Object)

자바스크립트는 함수(Function) 자료형으로 객체를 선언할 때 생성자(Constructor)를 부여받습니다. 

 

함수 자료형

var func = new Function();
var protoFunc = new func();

var func2 = function(){};
var protoFunc2 = new func();

console.log(func.prototype); // { constructor : f(), __proto__ : Object }
console.log(func2.prototype); // { constructor : f(), __proto__ : Object }

function(){}는 new Function()으로 선언한것과 같습니다.

 

함수 자료형 외의 다른 자료형에서는 프로토타입 객체를 생성할 수 없습니다.

var obj = {};
var protoObj = new obj(); // obj is not a constructor

var num = 123;
var protoNum = new num(); // num is not a constructor

var boolean = true;
protoBoolean = new boolean() // boolean is not a constructor

 

그리고 이 생성자(Constructor)가 있는 객체만이 자바스크립트의 new 키워드를 통해 객체를 생성할 수 있습니다.

new 키워드를 통해 객체를 선언하면 함수의 생성과 함께 프로토타입 객체(Prototype Object)도 같이 생성됩니다.

 

Person 함수를 선언해보겠습니다.

function Person(){}

 

Person 함수 객체

Person 함수의 프로토타입 객체가 생성되며

각 객체는 서로를 참조할 수 있게 연결되는 속성을 가지고 있습니다.

 

출처 https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67

 

1. 

Person 객체의 prototype을 통한 프로토타입 객체확인

 

2.

Person 객체의 constructor 는 Person 객체에 접근할 수 있다.

Person 객체의 __proto__는 Person 객체의 원형에 접근할 수 있습니다.

이때 Person 객체의 원형은 new Function이므로 자바스크립트 네이티브 코드가 반환됩니다.

__ proto __ 속성은(비표준) 모든 객체가 가지고 있다.

 

그리고 객체와 객체 사이에 참조하는 속성들을 퍼런스 변수라고 합니다.
또한, 이 참조는 동적으로 추가된 사항에 대해서도 접근할 수 있습니다.

 

 

 

레퍼런스 변수 예제

1.생성자를 부여받은 객체만이 new 키워드를 통한 객체 생성이 가능하다고 한 것을 기억해야 합니다.

function Person(x) {
    this.x = x;
}; // 프로토타입 객체 생성자 정의

var A = new Person('hello'); // 객체 생성

console.log(A.x); // hello 
// Person.x와 동일한 결과

console.log(A.prototype.x) // syntax error 
// A는 생성자의 권한이 없는 단일객체이기에 문법오류를 일으킨다.


 

 

2.프로토타입 원형 객체의 내부 스코프에 선언한 변수 x와 prototype으로 선언한 x의 위치를 확인합니다.

function Person(){
    this.x = 'Person x';
}; // 프로토타입 객체 생성자 정의

Person.prototype.x = 'prototype x'; // 프로토타입 선언

var newPerson = new Person(); // 객체 생성

console.log(newPerson.x); // Person x
console.log(newPerson.__proto__.x); // prototype x 

console.log(newPerson); 
/*
  { 
      x : 'Person x', 
      __proto__ :
           x : 'prototype x', 
          constructor : f Person(),
          __proto__ : Object 
  } 
*/

new 키워드를 통해 생성한 객체 newPerson은 원형 객체 Person을 참조하고 있기 때문에 

Person.x = newPerson.x이 됩니다. 

prototype으로 선언한 x는 __proto__ 레퍼런스 변수를 통해 원형 객체 Person의 x를 참조할 수 있습니다.

 

 

 

프로토타입 링크(Prototype Link)

__proto__ 속성은 프로토타입 링크라고 불리며 모든 객체에 존재하는 레퍼런스 속성이자 객체의 원형을 참조합니다. 객체가 생성될 때 프로토타입이 결정되며 사용자가 임의로 변경할수도 있습니다.

사용자가 임의로 동적으로 변경하는 특징을 사용해 상속을 구현할 수도 있습니다.

 

이 프로토타입 링크를 통해 상위 __proto__를 접근할 수 있으며 이것을 프로토타입 체인(Prototype chain)이라고 합니다. __proto__ 속성의 동작은 내부적으로 Object.getPrototypeOf가 호출되며 프로토타입객체를 반환합니다.

 

__proto__와 prototype는 둘다 프로토타입객체를 가리키고 있지만 두 속성의 관점은 차이가 있다고합니다.

__proto__ prototype

모든 객체가 가지고 있다.

함수 객체만 가지고 있다.

부모 프로토타입 객체를 가리킨다.

(함수의 경우 Function.prototype을 가리킨다.)

생성자를 가진 원형으로 생성할 수 있다.

참고 : https://poiemaweb.com/js-prototype

 

 

{}나 new Object로 선언한 객체는 자바스크립트에서 제공하는 네이티브 코드를 원형으로 두고 있어서 __proto__는 네이티브 코드를 contstuctor로 가지고 있습니다.

 

var object = {};
var object2 = new Object();

 

 

예제

원형 객체 Person의 prototype을 상속받습니다.

function Person(){}

Person.prototype.getType = function(){  
    return "사람입니다";
};

var yoon = new Person();  
var jun = new Person();

console.log(yoon.getType());   // 사람입니다
console.log(jun.getType());  // 사람입니다

 

1. __proto__와 prototype의 위치

function Person(){
    this.x = 'Person x';
};

Person.prototype.x = 'prototype x';

var newPerson = new Person();

console.log(newPerson.x); // Person x
console.log(newPerson.__proto__.x);  // prototype x'

- Person 함수 내부 스코프에 this.x를 선언

- Person의 prototype에 x를 선언

 

newPerson 객체의 x에 접근할 때 Person 내부 스코프에 선언한 대로 반환합니다.

__proto__.x로 참조 시 newPerson의 prototype에 접근하여 x를 반환합니다.

 

그렇다면 프로토타입 객체 원형의 내부 스코프에 this.x를 선언하지 않고 진행했을때에는 어떤 결과가 나오는지 확인해봅니다.

 

 

 

2. 프로토타입체인, 내부에 선언된 값이 없다면 상위를 참조

function Person(){};

Person.prototype.x = 'prototype x';

var newPerson = new Person();

console.log(newPerson.x); //prototype x
console.log(newPerson.__proto__.x);  // prototype x'

- Person 내부에 선언된 x의 값을 찾고 x의 값이 없으면 __proto__를 통해 상위 객체에서 x의 값을 찾는다. 

위의 예제에서는 prototype.x가 있기 때문에 prototype.x의 값을 반환한다.

 

 

프로토타입객체 내부에 변수가 없으면 해당 변수의 값을 찾기 위해 상위 프로토타입을 이어 참조하면서 해당 변수가 있을때까지 반복하여 값을 찾습니다. 끝까지 값이 없으면 undefined를 반환합니다.

 

 

 

렇게 

객체와 객체의 단방향 공유관계를 프로토타입 체인(Prototype Chain)이라고 합니다.

프로토타입체인은 동적으로 상속된 내용을 참조하기 때문에 실행할 때 값이 변경될 수 있으며 동적으로 변경되는 객체의 메서드나 속성을 찾아가는 과정을 프로토타입 룩업이라고 합니다.

 

__proto__를 통한 직접적인 접근은 참조에 대한 확인일 뿐 개발 시에는 지양해야 하며 Object.getPrototypeOf() 메서드를 사용하여 프로그래밍해야 합니다.

 

상위 객체를 참조하는 예제는 아래와 같습니다.

var obj = function(){}

console.log(obj.__proto__); // f(){[native code]};
console.log(obj.__proto__.__proto__); // { constructor : f, __defineGetter : f, ..... }
console.log(obj.__proto__.__proto__.__proto__); // null

 

 


 

출처 및 참고

- https://meetup.toast.com/posts/104

- https://velog.io/@yhe228/prototype%EC%9D%B4%EB%9E%80-6dk3v32r55

- https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67

*가 적혀있는 단어에 대한 뜻은 최하단에 있습니다.

 

 

TypeScript를 공부해볼까하면서 찾아본 튜토리얼 사이트에서 gulp를 마주했습니다. 

 https://typescript-kr.github.io/pages/tutorials/Gulp.html 

 

그리고 튜토리얼 따라하는도중 에러가 뜨게되었는데,

gulp에 대한 지식이 1도 없었기 때문에 찾고 공부한 내용을 작성해둡니다.

 

에러사항

AssertionError [ERR_ASSERTION]: Task function must be specified 

검색하면 첫번째로 나오는 감사한 블로그에서 정보를 얻었습니다.

gulp의 버전이 4가 되면서 작성 규칙이 조금 바뀌었다고 합니다. 

https://forgiveall.tistory.com/521

 

task룰에 series | parallel 옵션이 추가되었다고 합니다.

series는 직렬방식*이고 parallel는 병렬방식*이라고 하네요.

 

작성할 때 아래와 같이 씁니다.

gulp.task('default', gulp.series('uglify', 'watch'));

gulp.task('default', gulp.parallel('uglify', 'watch'));

 

 


저는 gulp에 대해 1도 모르는 쪼랩이라서 예제를 따로 진행해보고나서야 이해가되었습니다.

 

기존 방식으로 작성

gulpfile.js 

const gulp = require('gulp');
const uglify = require('gulp-uglify'); 
const concat = require('gulp-concat');

const paths = {
    js : ['src/js/*.js']
}

// minify
gulp.task('uglify', function () {
    return gulp.src(paths.js)
          .pipe(concat('main.min.js')) // marge
          .pipe(uglify()) // minify
          .pipe(gulp.dest('dist')); 
});

// watch
gulp.task('watch', function(){
    gulp.watch(paths.js, ['uglify']);
});

gulp.task('default', ['uglify', 'watch']);


수정된 방식으로 작성

gulpfile.js

const gulp = require('gulp');
const uglify = require('gulp-uglify');
const concat = require('gulp-concat');

const paths = {
    js : ['src/js/*.js']
}

// minify
gulp.task('uglify', function () {
    return gulp.src(paths.js)
       	  .pipe(concat('main.min.js')) // merge
          .pipe(uglify()) // minify
          .pipe(gulp.dest('dist'));
});

// watch
gulp.task('watch', function(){
    gulp.watch(paths.js, gulp.series('uglify'));
});

//gulp를 실행하면 default 로 uglify task를 실행
gulp.task('default', gulp.parallel('uglify', 'watch'));

 

gulp 실행 시 gulp.task('default',)가 실행되고

gulp.parallel에 의해 병렬로 uglify와 watch가 실행됩니다.

 

watch가 실행될 때 gulp.watch(경로) 메서드에 의해서 (경로)의 파일에 변화가 있을 때

gulp.series('uglify')를 통해 직렬로 uglify가 실행됩니다.

 

 

 

직렬과 병렬로 실행하면 뭐가 달라? 라고 생각할 수 있기 때문에

실행 후 차이가 나는 부분을 보여드리겠습니다.

 

parallel 병렬로 실행

startExpress와 watch가 둘다 실행되는 것을 확인할 수 있습니다.

(startExpress 함수는 done을 시켜주지 않고 있습니다.)

 

series 직렬로 실행

startExpress만 실행되고 watch는 실행되지 않습니다.

series와 parallel에 따라서 원하던 조건대로 되지않는 경우가 생길수도 있으니 유의하고 써야합니다.

 

 

 

 


*

직렬방식 : 순차적으로 실행

병렬방식 : 나란히 실행

 

참고

 

 

 

gulp 이해를 돕는데 가장 많이 도움을 받은 블로그입니다.

단계씩 작성해주신 글만 따라가도 잘 할 수 있습니다.

다만, 예제를 따라하면서 자세하지 않았거나 몰랐던 부분 같은 것을 기억하기 위해 글을 씁니다.

(도움을 받은 블로그에서는 약간의 지식이 깔려있어야한 듯 싶습니다.) 

https://valuefactory.tistory.com/314  = https://programmingsummaries.tistory.com/393  

 

gulp란? gulp시작하기

gulp 시작하기 gulp.js을 시작하기 위해 필요한 가장 기본적인 사용 방법들을 정리했습니다. gulp 개념 gulp 는 node.js 기반의 task runner 입니다. 반복적인 귀찮은 작업들이나 프론트엔드 빌드에 필요한 작업들..

valuefactory.tistory.com

 

먼저 프로젝트 폴더 생성합니다.

[cmd]

mkdir testFolder

 

생성한 폴더로 들어간 후

[cmd]

cd ./testFolder

 

gulp를 install 해줍니다.

gulp 버전 4 이상부터는 gulp모듈에서 cli가 분리되어서 둘 다 install 해줘야한답니다.

따라서 gulp cli는 전역설치하고 gulp는  프로젝트에 설치해줍니다.

[cmd]

npm install --global gulp-cli

npm install --save-dev gulp

gulp 앞에 --save-dev가 붙는 이유는 개발에서만 쓰이기 때문에 devDependencies에 넣기 위함입니다. 

개발시에만 쓰이는 경우가 많아서 그렇다고합니다.

 

gulp install이 완료되었는지 확인하고싶다면 버전 정보를 출력해볼 수 있습니다.

[cmd]

gulp-v

 

현재 폴더구조는 이렇습니다.

node_modules와 package-lock.json이 생겼다.

 

그 다음 minify와 merge를 진행하기 위해 각각의 모듈을 install해줍니다.

한번에 받기

[cmd]

npm install --save-dev gulp-uglify gulp-concat

 

minify 모듈은 gulp-uglify

[cmd]

npm install --save-dev gulp-uglify 

 

merge 모듈은 gulp-concat

[cmd]

npm install --save-dev gulp-concat

 

merge, minify 시킬 파일이 있어야 하므로 예제에 필요한 폴더와 파일들을 생성해보겠습니다.

 

src 폴더를 생성하고 그 폴더 하위에 js 폴더를 생성해줍니다. 

그 후에 index.js와 sayHello.js 파일을 생성하겠습니다.

 

현재 폴더구조입니다.

src > js > index.js / sayHello.js

 

예제를 작성해보겠습니다.

내용은 중요하지 않습니다. 그냥 minify, merge 기능을 확인해볼거니깐요.

 

[sayHello.js]

module.export = {
    sayHelloFunc : function sayHelloFunc(name){
        var name = name || 'Lee';
        return 'Hello~' + name;
    }
};

 

간단히 설명하면, 호출할 때 네임값을 넣어주면 Hello~ [name]이 나오는 코드입니다.

이것을 export하고 있습니다.

 

[index.js]

var sayHelloFunc = require('./sayHello');
console.log(sayHelloFunc('J.K!'));

 

sayHello.js에서 export한것을 require로 가져와서 호출해줍니다.

자 그럼 중요하지 않은 js 예제를 지나서 gulp설정을 해주겠습니다.

 

gulp를 설정하기 위해서는 루트에 gulpfile.js 파일을 생성해야합니다.

 

현재 폴더구조입니다.

gulpfile.js 생성

 

먼저 merge 설정을 하겠습니다.

[gulpfile.js]

const gulp = require('gulp');
const concat = require('gulp-concat');

// 자바스크립트 파일을 병합
gulp.task('concat', function() {
    return gulp.src('src/js/*.js')
        .pipe(concat('main.js')) // main.js로 파일이름을 짓고 병합
        .pipe(gulp.dest('dist')); // dist 폴더에 병합한 파일 생성 
});

// gulp를 실행하면 default 로 concat task를 실행
gulp.task('default', gulp.series('concat'));

[코드설명입니다.]

1.사용자가 gulp를 실행하면 gulp.task('default')가 가장먼저 실행됩니다.

2.실행시키는 task는 바로 뒤에 오는 gulp.series('concat')를 실행 시킵니다. 

.pipe()는 실행 순서를 담는다고 보면 될 것 같습니다.

 

gulp.task('concat')가 실행되면

gulp.src(경로)에 있는 파일을 찾아서 concat 모듈을 통해 main.js 파일명으로 병합합니다.

이 때 gulp.dest('dist')를 통해 dist 폴더에 병합한 파일을 생성해줍니다. 

dist라는 폴더가 있을 때에는 그곳에 생성하고 없다면 dist 폴더와 함께 생성합니다.

 

gulp.src('src'/js/*.js')라고 src > js > .js확장자의 모든 파일이라는 것인데, 특정한 파일로만 설정도 가능합니다.

 

여기까지 진행했다고하면 cmd 창을 열고 gulp를 입력하여 실행시킬 수 있습니다.

[cmd]

gulp

gulp 실핼 시 폴더구조

dist가 생성된 것이 확인됩니다.

 

concat으로 merge시킨 main.js파일

이번에는 minify를 먼저한 후에 merge를 시켜보도록 하겠습니다.

 

[gulpfile.js]

const gulp = require('gulp');
const concat = require('gulp-concat');
const uglify = require('gulp-uglify');

// 자바스크립트 파일을 병합
gulp.task('concat', function () {
    return gulp.src('src/js/*.js')
        .pipe(uglify())
        .pipe(concat('main.min.js')) // main.min.js 로 이름 변경
        .pipe(gulp.dest('dist'));
});

gulp.task('default', gulp.series('concat'));

 

1.모듈을 require하는 부분과

2..pipe()로 uglify()를 실행시킨 부분이 추가되었습니다.

3.또한 minify한 파일임을 알기 쉽게 main.js로 merge 시키던 부분을 main.min.js로 수정해줬습니다.

 

사용자가 gulp를 실행하면

1.gulp.task('default')를 호출해서 gulp.series('concat')이 호출되고 gulp.task('concat')이 실행됩니다

2.gulp.src(경로)의 파일을 찾아 .pipe()의 순서에 따라 uglify()가 먼저 호출되므로 minify가 먼저 진행되고 

3.그 이후 concat 모듈에 의해 merge 후 dist 폴더에 main.min.js 이름의 파일이 생성됩니다.

 

merge와 minify가 끝난 폴더구조

 

main.min.js

 

 

그럼 다음 포스팅에서 이 작업을 자동화해보도록 하겠습니다.

다음포스팅바로가기

 

+ Recent posts