Javascript 빌드도구, Grunt 시작하기
Grunt
Grunt 0.4 부터는 grunt-cli 를 전역으로 설치하고, 프로젝트마다 grunt를 설치해야한다.
1. Installation
npm install -g grunt-cli
npm install -g grunt-init
npm install grunt // in project folder
grunt --version
> grunt-cli v0.1.12
> grunt v0.4.2
grunt-init --version
> grunt-init v0.2.1
> grunt v0.4.2
npm install grunt --save-dev // in project folder
npm install grunt-contrib --save-dev // in project folder
*참고 `npm install -production` 을 실행하면 `--save-dev` 로 저장된 패키지는 설치되지 않는다.
2. grunt-init
grunt-init 을 사용하기 위해선 템플릿을 다운받아야 한다. ~/.grunt-init/ 에 템플릿을 저장하면 된다. 아래는 공식적으로 유지되는 몇가지 grunt-init templates
– grunt-init-commonjs : for CommonJS module
– grunt-init-gruntfile : Create a basic Gruntfile
– grunt-init-gruntplugin : for Grunt plugin
– grunt-init-jquery : for jQuery plugin
– grunt-init-node : for Node.js module
gruntfile 템플릿을 설치해 보자. 기본으로 package.json 과 Gruntfile.js 를 생성해준다.
git clone https://github.com/gruntjs/grunt-init-gruntfile.git ~/.grunt-init/gruntfile
grunt-init gruntfile // 모두 엔터
3. Gruntfile.js 분석
module.exports = function(grunt) {
grunt.initConfig({
meta: {
version: '0.1.0'
},
banner: '/*! PROJECT_NAME - v<%= meta.version %> - ' +
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
'* http://PROJECT_WEBSITE/\n' +
'* Copyright (c) <%= grunt.template.today("yyyy") %> ' +
'YOUR_NAME; Licensed MIT */\n',
// Task configuration.
concat: {
options: {
banner: '<%= banner %>',
stripBanners: true,
},
dist: {
src: ['test/config.js', 'test/server.js'],
dest: 'test/result.js'
}
},
uglify: {
options: {
banner: '<%= banner %>'
},
dist: {
src: '<%= concat.dist.dest %>',
// src: ['public/javascripts/**/*.js']
dest: 'test/result.min.js'
}
}
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
// Default task.
grunt.registerTask('ugly', ['uglify']);
grunt.registerTask('con', ['concat']);
grunt.registerTask('make', ['concat', 'uglify']);
};
grunt.initConfig 하위에 있는 Task들, uglify나 concat 등은 ‘할일’ 이다. 이것들은 npm install 을 통해 위에서 설치되었으므로, grunt.loadNpmTasks를 통해 등록 된 후에야 사용할 수 있다. option은 각 Github 페이지에 가서 Documentation 을 보면 된다. 중요한 부분은, dist 필드다. src(원본) 을 작업해서 dest (결과) 로 만들어 버린다. 파일의 이름은 [] 배열로서 여러게 지정하거나 아니면 <%= %> 등의 템플릿 기능을 이용해 다른 작업의 결과물을 뽑아 올 수도 있다. 폴더 내에 모든 파일을 대상으로 하고싶다면 uglify.dist.src 부분의 주석처럼 src: ['public/javascripts/**/*.js'] 이렇게 사용하면 된다. 그러면 public 폴더 내에 javascripts 폴더 내에 있는 모든 파일(하위폴더포함)을 대상으로 한다.
마지막으로 이런 세부 Task 들을 모아 밖에서 grunt로 실행할 사용자-실행 Task 를 등록한다. 예를들어
grunt.registerTask('make', ['concat', 'uglify']);
의 경우에는 사용자가 grunt make 를 입력했을때 세부 Task인 concat과 uglify를 순서대로 실행한다.
4. Grunt : Maximum call stack size exceeded
Grunt 를 실행 시켰을때 Maximum call stack size exceeded Use --force to continue 따위의 메세지가 뜰 수 있는데, 이건 registerTask 로 등록된 이름과 내부 Task 이름이 같아서 그렇다.(아마 파싱 잘못되서 For문 무한으로 돌다가 스택 풀차서 에러나는 것처럼 보임.) 해결방법은, 아래의 코드를 그 아래처럼 변경하자.
grunt.registerTask('concat', ['concat']); // 둘 다 이름이 같으면 안된다.
grunt.registerTask('concate', ['concat']); // 다르게 만들어주자.