Categories
通風報信

Grunt──網站開發的自動化任務執行工具

GRUNT
GRUNT

隨著網頁前端的技術發展,原始碼編譯、圖片最佳化、壓縮合併、內容代換、語法檢查、程式測試等等工作不斷地在我們的開發流程中出現,但是一樣一樣執行又要搭配不同的狀況來組合,實在讓人感到麻煩,幸好前端的工具也發展得很快,已經有成熟的解決方案可以來處理這些過程,Grunt就是這樣的一個方便的任務執行框架,讓你可以自動化執行這些繁瑣的開發工作。

Grunt的使用方式,看網站上的教學示範就很容易理解了。
這裡大略提及一些地方,首先要特別注意的是安裝,在系統上安裝的套件是grunt-cli,使用npm來安裝:

npm install -g grunt-cli

而開發專案裡面,用npm init準備好package.json後則是安裝grunt,這才是實際負責任務執行的程式:

npm install grunt --save-dev

如此一來,grunt跟grunt-cli分開,當使用grunt指令時,其實是呼叫系統裡的grunt-cli,它再使用專案裡安裝的grunt程式來執行Gruntfile裡的任務,達到不同的專案可以使用不同版本的grunt來執行任務的目的。

由於 Grunt 的 Plugin 實在五花八門難以盡數,在 nodeJS 的 npm 底下長成了繁盛的生態系,光是Grunt自行維護的就有二十多種,其中常用的介紹如下:

grunt-contrib-sass:把SASS編譯成CSS
當然,系統裡面要先裝好Ruby的Sass,不然就改用node版本的grunt-sass,然後Gruntfile的規則也十分簡單。

module.exports = function(grunt) {
	grunt.initConfig({
	  sass: {
		dist: {
		  files: {
			'style.css': 'style.scss'
		  }
		}
	  }
	});
	grunt.loadNpmTasks('grunt-contrib-sass');
	grunt.registerTask('default', ['sass']);
};

指定要轉換的來源跟目的檔名即可。

grunt-contrib-coffee:把CoffeeScript編譯成Javascript

module.exports = function(grunt) {
	grunt.initConfig({
	  coffee: {
            compile: {
                files: {
                    'script.js': 'script.coffee'
                }
            }
          }
	});
	grunt.loadNpmTasks('grunt-contrib-coffee');
	grunt.registerTask('default', ['coffee']);
};

除了直接列舉各個要處理的檔名外,也可以動態指定處理的套用範圍

grunt-contrib-imagemin:減少PNG與JPG圖片大小

module.exports = function(grunt) {
	grunt.initConfig({
	  imagemin: {
            dist: {
                options: {
                    optimizationLevel: 3
                },
                files: {
                    'texture.png': 'texture.png'
                }
            }
          }
	});
	grunt.loadNpmTasks('grunt-contrib-imagemin');
	grunt.registerTask('build', ['imagemin']);
};

如果要處理 SVG 檔案的話,也有 grunt-svgmin 可以用。

grunt-contrib-cssmin:減少CSS文件大小

module.exports = function(grunt) {
	grunt.initConfig({
	  cssmin: {
            minify: {
                files: {
                    'style.css': 'style.css'
                }
            }
          }
	});
	grunt.loadNpmTasks('grunt-contrib-cssmin');
	grunt.registerTask('build', ['cssmin']);
};

另外要壓縮Javascript的話,也有 grunt-contrib-uglify 可以使用。

grunt-contrib-connect:使用connect建立Web Server

module.exports = function(grunt) {
	grunt.initConfig({
	  connect: {
            server: {
                options: {
                    hostname: '*'
                }
            }
          }
	});
	grunt.loadNpmTasks('grunt-contrib-connect');
	grunt.registerTask('default', ['connect']);
};

預設的port是8000,hostname是localhost,改成這樣是為了讓其他機器也能連上。

grunt-contrib-watch:監控檔案在更動時執行任務,已經內建livereload支援

module.exports = function(grunt) {
	grunt.initConfig({
	  watch: {
            sass: {
                files: ['*.scss'],
                tasks: ['sass'],
                options: {
                    livereload: true
                }
            },
            livereload: {
                files: ['*.html'],
                options: {
                    livereload: true
                }
            }
          }
	});
	grunt.loadNpmTasks('grunt-contrib-watch');
	grunt.registerTask('default', ['watch']);
};

如果想要同時執行SCSS與CoffeeScript的編譯工作,還有 grunt-concurrent 可以用上。

將以上的任務通通加在一起,執行grunt會先讓connect跑起來,再watch檔案更動來livereload,打完收工再grunt build就搞定啦。

grunt.registerTask('default', ['connect', 'watch']);
grunt.registerTask('build', ['imagemin', 'cssmin', 'uglify']);

除了這些用法外,值得一提的是,可以搭配Travis CI等服務來執行grunt的測試任務,在.travis.yml裡面加上:

language: node_js
node_js:
  - "0.10"

然後package.json裡面加上node test的設定:

"scripts": {
  "test": "grunt test"
},

很簡單地就完成了。

至於 grunt-init 這個指令就可以不必深究了,因為開發者們預計將把 Project Scaffolding 交給 Yeoman 取代,Yeoman 在初始化專案時更會內建不少常用的Grunt任務,可以省下更多功夫。

最後要說的是,其實以上介紹的用法,根據開發團隊的計畫,很可能在 Grunt 0.5 出現之後會再大改過,期待 node-task 推出的那時能再次革新整個網站開發工具鍊。

2 replies on “Grunt──網站開發的自動化任務執行工具”