Grunt คืออะไร ? + สอนวิธีใช้

Suranart Niamcome
SiamHTML
Published in
3 min readAug 12, 2014
Grunt

หลังจากที่ได้อ่านบทความเกี่ยวกับ gulp.js ไปแล้ว เราก็จะเห็นว่ามันช่วยทำงานหลายๆ อย่างแทนเราได้เป็นอย่างดี แต่จริงๆ แล้ว ยังมี tool อีกตัวหนึ่ง ที่ทำหน้าที่คล้ายๆ กับ gulp.js เลย แถมยังเกิดขึ้นมาก่อนเสียอีก tool ที่ว่านี้มีชื่อว่า Grunt

Grunt คืออะไร

อย่างที่เกริ่นไปแล้วว่า Grunt กับ gulp.js นั้น ทำหน้าที่เหมือนๆ กันเลย คือเป็นเหมือน “คนใช้” ที่จะคอยช่วยเราทำงานต่างๆ ที่เราต้องทำอยู่เป็นประจำ อย่างไรก็ตาม tool ทั้ง 2 ตัวนี้ ก็ยังพอจะมีความแตกต่างอยู่บ้าง ดังนี้

  • รูปแบบการเขียนโค้ดของ gulp.js นั้นจะสั้นและอ่านง่ายกว่า ถึงแม้ว่าเราจะไม่ค่อยถนัด JavaScript มากนัก แต่ก็ยังพอจะทำความเข้าใจได้ไม่ยาก
  • ความเร็วgulp.js ทำงานได้เร็วกว่า Grunt เพราะว่ามันใช้ stream ของ Node.js ซึ่งจะเป็นการทำงานบน memory
  • จำนวน Pluginเนื่องจาก Grunt นั้นออกมาก่อน จึงมีคนใช้เยอะกว่า ในส่วนของ plugin ก็มีให้เลือกใช้เยอะกว่า gulp.js มาก

วิธีใช้ Grunt

เนื่องจาก Grunt นั้นเป็นส่วนเสริมของ Node.js และการใช้งานก็ยังมีความคล้ายคลึงกับ gulp.js มาก เราจึงควรมีพื้นฐานเกี่ยวกับ Node.js และ gulp.js มาบ้าง

  • Node.jsอ่านพื้นฐานการใช้ Node.js
  • gulp.jsอ่านพื้นฐานการใช้ gulp.js

1. สร้างไฟล์ package.json

ให้เราสร้างไฟล์ชื่อ package.json เอาไว้ที่ระดับแรกสุดของโฟลเดอร์งานของเราก่อน โดยไฟล์นี้จะทำหน้าที่บอกข้อมูลต่างๆ ให้กับ npm ไม่ว่าจะเป็น ชื่อโมดูล, เวอร์ชัน, ผู้พัฒนา รวมไปถึง dependency ต่างๆ ที่โมดูลนี้ใช้อีกด้วย ในเบื้องต้นให้เราใส่โค้ดด้านล่างนี้เอาไว้ที่ไฟล์ package.json ได้เลย

{
"name": "grunt-tutorial",
"version": "0.0.1",
"description": "A Grunt Tutorial by SiamHTML",
"author": "Me"
}

2. ติดตั้ง Grunt

ต่อมาให้เราติดตั้ง Grunt โดยการติดตั้งนั้น เราจะต้องทำอยู่ 2 ที่ด้วยกัน ดังนี้

2.1 Global

การติดตั้งที่ global จะเป็นการทำให้เราสามารถใช้คำสั่งของ Grunt ใน command-line ได้ โดยเราจะทำเพียงแค่ครั้งแรกครั้งเดียวเท่านั้น ให้เราพิมพ์คำสั่งด้านล่างนี้

npm install -g grunt-cli

แต่ถ้าใครใช้ Mac อยู่ ก็ให้ใส่ sudo เข้าไปข้างหน้าด้วย แบบนี้

sudo npm install -g grunt-cli

เพียงเท่านี้ เราก็จะสามารถใช้คำสั่งของ Grunt ใน command-line ได้แล้ว

2.2 Local

ต่อมาเราจะต้องติดตั้ง Grunt แบบ local ด้วย ซึ่งก็คือการติดตั้ง Grunt เอาไว้ที่โฟลเดอร์งานของเรานั่นเอง ให้เรา cd เข้าไปที่โฟลเดอร์งานของเราก่อน

cd myProject

จากนั้นก็ให้เรารันคำสั่งตามด้านล่างนี้

npm install grunt --save-dev

หมายเหตุ: หากเราจะใช้ Grunt กับงานไหน เราก็จะต้องติดตั้ง Grunt แบบ local เอาไว้ที่โฟลเดอร์งานนั้นๆ เสมอ

3. กำหนด Task ต่างๆ ลงในไฟล์ Gruntfile.js

ต่อมาเราจะต้องระบุว่าเราต้องการจะให้ Grunt ช่วยทำอะไรบ้าง ให้เราสร้างไฟล์ที่มีชื่อว่า Gruntfile.js ขึ้นมา แล้ววางเอาไว้ที่เดียวกับไฟล์ package.json จากนั้นก็ให้เราใส่ task ต่างๆ ลงไปในไฟล์ โดยใช้รูปแบบนี้

module.exports = function(grunt) {grunt.initConfig({
// กำหนด config ของ task ต่างๆ ในส่วนนี้ (มีบอกในเว็บหลักของแต่ละ plugin)
});
// โหลด plugin ต่างๆ ที่จะใช้เป็น task
grunt.loadNpmTasks('ชื่อ Plugin');
// กำหนด default task
grunt.registerTask('default', ['ชื่อ Task1', 'ชื่อ Task2', 'ชื่อ Task3']);
};
ในการใช้งานจริง ส่วนใหญ่เราจะไม่ได้เขียน task ขึ้นมาใช้เอง แต่เราจะโหลด plugin ที่ตรงกับความต้องการของเรามาใช้เลย เรามีหน้าที่แค่คอย config ค่าต่างๆ ให้กับ plugin เท่านั้นเอง ซึ่งวิธีการ config ของ plugin ต่างๆ มักจะมีอธิบายไว้อย่างละเอียดแล้วในหน้าเว็บหลักของ plugin นั้นๆ
4. รัน Gruntเมื่อเรากำหนด config ให้กับ task ต่างๆ เรียบร้อยแล้ว สุดท้ายก็ให้เราลองสั่งให้ task เหล่านั้นทำงาน ให้เราใช้คำสั่งในรูปแบบนี้grunt

Workshop — ลองใช้ UnCSS กับ Grunt

ในการใช้ framework ต่างๆ เรามักจะพบว่ามี CSS Rule เป็นจำนวนมากที่ถูกใส่เข้ามาทั้งๆ ที่เราไม่ได้ใช้ ซึ่งมันไม่เป็นผลดีในแง่ของ performance เลย ทั้งในส่วนของการประมวลผล และในส่วนของขนาดไฟล์ที่มากเกินความจำเป็นเพื่อเป็นการแก้ปัญหาดังกล่าว เราจะใช้ plugin ของ Grunt ในการตัด CSS Rule ส่วนเกินดังกล่าวออก ให้เราติดตั้ง plugin ที่มีชื่อว่า grunt-uncss ด้วยคำสั่งด้านล่างนี้npm install grunt-uncss --save-devเมื่อติดตั้ง plugin เรียบร้อยแล้ว ให้เราเข้าไปที่ไฟล์ Gruntfile.js เพื่อที่จะโหลด plugin grunt-uncss ที่เพิ่งจะติดตั้งไปมาใช้งาน พร้อมกับ config ค่าต่างๆ (รายละเอียดการ config ทั้งหมด สามารถดูได้จากเว็บหลัก)module.exports = function(grunt) {grunt.initConfig({// config ของ uncss (เอามาจากเว็บหลักของ plugin ได้เลย) 
uncss: {
dist: {
files: {
// เอาเฉพาะโค้ด CSS ที่มีการเรียกใช้จริงๆ ใน index.html มาเซฟเป็นไฟล์ใหม่ที่ css/tidy.css
'css/tidy.css': ['index.html']
}
}
}
});
// โหลด plugin ที่ชื่อ grunt-uncss มาใช้
grunt.loadNpmTasks('grunt-uncss');
// กำหนดให้ uncss เป็น default task
grunt.registerTask('default', ['uncss']);
};
จากนั้นให้ลองรัน Grunt ดูเลย
gruntเมื่อเปิดไฟล์ tidy.css ดู ก็จะพบว่ามันเหลือแต่โค้ด CSS ที่มีการเรียกใช้จริงๆ ในหน้า index.html เท่านั้น

เสริมความสามารถด้วย grunt-processhtml

เพื่อให้การใช้งาน UnCSS มีระเบียบมากยิ่งขึ้น ให้เราติดตั้ง plugin ที่ชื่อ  grunt-processhtml เพิ่มเข้ามาอีกตัวnpm install grunt-processhtml --save-devเราจะใช้ grunt-processhtml สร้าง index.html ขึ้นมาอีกเวอร์ชันหนึ่ง ซึ่งจะเป็นเวอร์ชันสำหรับนำไปใช้จริงที่ production และในเวอร์ชันนี้เอง ที่เราจะเรียกใช้ tidy.css ซึ่งเป็นไฟล์ที่ผ่านการตัดโค้ด CSS ที่ไม่จำเป็นออกไปหมดแล้ว ก่อนอื่นให้เราเข้าไปที่ index.html เดิมของเรา แล้วเพิ่ม comment แบบนี้<!-- build:css css/tidy.css -->
<link rel="stylesheet" href="css/style.css">
<!-- /build -->
comment ด้านบน จะเป็นการบอก grunt-processhtml ให้ replace โค้ดจาก css/style.css มาเป็น css/tidy.css แทน เพราะเราต้องการจะเรียกใช้ tidy.css กับเวอร์ชันที่จะนำไปใช้จริง จากนั้น ให้เราเข้าไปที่ไฟล์ Gruntfile.js เพื่อที่จะโหลด plugin grunt-processhtml มาใช้งาน พร้อมกับ config ค่าต่างๆ เหมือนเคย ลองดูโค้ดด้านล่างนี้module.exports = function(grunt) {grunt.initConfig({uncss: {
dist: {
files: {
// เอาเฉพาะโค้ด CSS ที่มีการเรียกใช้จริงๆ ใน index.html มาเซฟเป็นไฟล์ใหม่ที่ dist/css/tidy.css
'dist/css/tidy.css': ['index.html']
}
}
},
// เพิ่ม config ของ processhtml (เอามาจากเว็บหลักของ plugin ได้เลย)
processhtml: {
dist: {
files: {
// process ไฟล์ index.html แล้วเซฟเป็นไฟล์ใหม่ที่ dist/index.html
'dist/index.html': ['index.html']
}
}
}
});
grunt.loadNpmTasks('grunt-uncss');// โหลด plugin ที่ชื่อ grunt-processhtml เพิ่มอีกตัว
grunt.loadNpmTasks('grunt-processhtml');
// เพิ่ม processhtml เข้ามาใน default task
grunt.registerTask('default', ['uncss', 'processhtml']);
};
จากนั้นให้ลองรัน Grunt ดูเลย
gruntเมื่อลองรันดู เราก็จะได้ไฟล์ index.html และ tidy.css เพิ่มเข้ามาในโฟลเดอร์ dist (ซึ่งเป็นโฟลเดอร์สำหรับเก็บไฟล์ที่เราจะนำไปใช้จริงที่ production) และเมื่อลองดูโค้ดในไฟล์ index.html แล้วก็จะพบว่ามันได้เปลี่ยนมาเรียกใช้ไฟล์ tidy.css แทนแล้ว (เดิมจะเป็น style.css) จากนี้ไป เวลาเราจะแก้ไฟล์ html หรือ css ก็ให้เราแก้ที่ไฟล์ต้นฉบับเหมือนเดิม (index.html และ css/style.css) แล้วตอนที่จะเอาขึ้น production ก็ค่อยมารัน Grunt เพื่อที่จะเอาไฟล์จากโฟลเดอร์ dist ไปใช้

แนะนำ Plugin ของ Grunt

นอกจาก plugin grunt-uncss และ grunt-processhtml แล้ว Grunt ยังมี plugin น่าสนใจอีกมากมาย ไม่ว่าจะเป็น
  • LESS (grunt-contrib-less)คอมไพล์ LESS ให้เป็น CSS
  • Watch (grunt-contrib-watch)สั่งให้รัน task ที่กำหนด เมื่อไฟล์มีการเปลี่ยนแปลง
  • Compress CSS files (grunt-contrib-cssmin)ย่อไฟล์ CSS ให้เล็กลง
  • Uglify (grunt-contrib-uglify)ย่อไฟล์ JS ให้เล็กลง
  • Minify images (grunt-contrib-imagemin)ย่อไฟล์รูปให้มีขนาดเล็กลง
  • Concatenate files (grunt-contrib-concat)รวมไฟล์หลายๆ ไฟล์ ให้กลายเป็นไฟล์เดียว
เราสามารถเข้าไปดูรายชื่อทั้งหมด รวมไปถึง plugin ที่มียอดดาวน์โหลดเยอะๆ ได้ที่หน้า Plugins

บทสรุปการใช้ Grunt

เราจะเห็นว่าการใช้ Grunt นั้น แทบจะเหมือนกับการใช้ gulp.js เลย แต่จะต่างนิดหน่อยตรงโค้ดที่ออกจะดูยากกว่า gulp.js เล็กน้อย รวมไปถึงในเรื่องของการทำงานที่อาจจะช้ากว่า gulp.js เล็กน้อยเช่นกัน(เนื่องจาก gulp.js ออกมาทีหลัง เลยต้องทำให้ดีกว่า Grunt อยู่แล้ว) แต่ Grunt ก็มีข้อได้เปรียบอยู่บ้างตรงที่มี plugin ให้เลือกใช้เยอะกว่ามาก(ปัจจุบัน Grunt มี plugin อยู่ประมาณ 3,000 ส่วน gulp.js นั้น มีแค่ประมาณ 700 เท่านั้น)หากเราไม่ได้สนใจเรื่องความเร็วในการรัน task มากนัก เราก็อาจจะใช้ Grunt ไปเลยก็ได้ แต่ถ้าเราอยากเขียนโค้ดแบบสั้นๆ เข้าใจง่าย หรือต้องการความเร็ว เราก็อาจจะเลือกใช้ gulp.js แทน แล้วค่อยใช้ Grunt เสริมเฉพาะกรณีที่ต้องการจะใช้ plugin ที่ gulp.js ยังไม่มีก็ได้

--

--