Grunt הוא כלי אוטומציה מבוסס node.js. הכלי בדרך כלל מופעל בשלבי הפיתוח (לפני שאנו מעלים את האפליקציה/אתר לשרת החי – הפרודקשן) ומשמש אותנו למגוון משימות באפליקציה שלנו הנוגעות לאופטימיזציה של האפליקציה.
מגוון המשימות יכול להיות אגרגציה של קבצי CSS ו-JS, מיניפקציה שלהם ודחיסה שלהם. הוא יכול להיות צירוף כל התמונות לספרייט אחד גדול ב-CSS. זה יכול להיות בדיקות קוד סטטית של CSS ו-JS, הרצת בדיקות אוטומטיות וכל פעולה אחרת שאנחנו עושים בקבצי האפליקציה שלנו. Grunt יכול לרוץ בכל סביבה שהיא ומשתמשים בו במגוון פרויקטים – גם בפרויקטים של Node.js אבל גם בפרוייקטים מבוססי דרופל, וורדפרס או ג'אווה.
ישנם מגוון אדיר של כלים שמשתמשים ב-Grunt. במאמר הזה אני מסביר על איך מתקינים ומשתמשים בו באופן בסיסי ביותר.
חשוב להדגיש כמה דברים לפני ההתחלה – ראשית מדובר בכלי מבוסס node.js. לא חייבים להבין ב-node.js על מנת להשתמש בו, אבל חייב להיות לכם מותקן node.js על סביבת העבודה. בחלק הראשון של מדריך ה-node.js הארוך שכתבתי, אני מסביר איך מתקינים node.js ו-npm.
שנית, אפשר להתקין ולהשתמש ב-grunt גם בחלונות וגם בלינוקס.
לפני ההתקנה, נבדוק ש-npm מותקן. נכתוב npm -v בקונסולה (או ב-cmd, תלוי במערכת שלכם). עובד? מעולה. לא עובד? צריך להתקין node.js.
עכשיו צריך להתקין את grunt שכאמור הוא מודול של node.js. כל מה שצריך זה לכתוב npm install grunt . אם נזכור את node.js והתקנות המודולים, אם אין g המשמעות היא התקנה לוקלית (שהיא הדרך הנכונה לעבוד עם grunt – התקנה לוקלית לכל פרויקט). אם הכל תקין, grunt יותקן עם כל המודולים שהוא צריך אותם על מנת לעבוד. אם נכתוב grunt בקונסולה/cmd אנו נקבל את הטקסט הבא:
grunt-cli: The grunt command line interface. (v0.1.13) Fatal error: Unable to find local grunt. If you're seeing this message, either a Gruntfile wasn't found or grunt hasn't been installed locally to your project. For more information about installing and configuring grunt, please see the Getting Started guide: http://gruntjs.com/getting-started
מה שאומר שהוא מותקן, אבל אין לו בדיוק על מה לעבוד. grunt צריך הוראות. את ההוראות אנו נותנים לו באמצעות קובץ שנקרא Gruntfile.js. הקובץ הזה מכיל הוראות – למשל – קח את הקבצים האלו והאלו ועשה איתם כך וכך.
בואו ונדגים! ניצור תיקיה ריקה במערכת שלנו, למשל grunt_test_project או כל שם אחר שבא לכם. בתיקיה הזו ניצור קובץ JavaScript קטן וטיפשי. משהו בסגנון הזה:
var a = 1; var b = '1'; var c = a+b; alert(c);
בוא ונניח שאני רוצה להריץ תהליך שיבדוק את הקובץ על מנת לראות שהוא תקין מבחינת הג'אווהסקריפט. אני אכתוב על כך במאמר אחר יותר בפירוט, אבל תהליך בדיקה סטטית של קוד נקרא lint שזה מוך שיש בפופיק (נשבע לכם). התוכנה שעושה את הבדיקה הסטטית של הקוד נקראת jshint וקיימת אימפלמנטציה שלה ל-grunt.
התוכנה הזו גם היא מודול של node.js. בואו ונוריד אותה באמצעות:
npm install grunt-contrib-jshint
עכשיו, כשזה קיים, אנחנו יכולים להשתמש בו. בתיקיה שבה יצרנו את קובץ הג'אווהסקריפט הטפשי שלנו, ניצור קובץ ששמו הוא Gruntfile.js ובו נכניס את הפשתגן הבא:
module.exports = function(grunt) { grunt.initConfig({ //object with all tasks. jshint: { //run jshint all: ['*.js'] //settings for jshint } }); grunt.loadNpmTasks('grunt-contrib-jshint'); //activate jshint };
בקובץ הזה אני בעצם אומר ל-grunt מה לעשות. על מנת להריץ אותו, אני אכתוב grunt עם שם המשימה. מה המשימה? jshint:
$ grunt jshint Running "jshint:all" (jshint) task >> 2 files lint free. Done, without errors.
כך זה נראה.
אז בואו ונסתכל על קובץ ההגדרות שדרכו ה-grunt עובד. מה יש שם בעצם? למי שמכיר קצת node.js, השורה הראשונה: module.exports = function(grunt) { תראה מאוד מוכרת. למי שלא – כאן אנו בעצם מגדירים פונקציה שנקראת ברגע שאנו מפעילים את grunt. בפונקציה הזו מתקבל אובייקט grunt עם מתודות שאפשר לקרוא להן.
המתודה הראשונה שאנו קוראים לה היא grunt.initConfig שמקבלת אובייקט. כל תכונה באובייקט הזה היא משימה. במקרה הזה יש לנו רק תכונה אחת ומשימה אחת בשם jshint. המשימה גם היא אובייקט שמכיל מה שהמשימה דורשת. הוא יכול לא להכיל כלום והוא יכול להכיל שלל של פרמטרים. תלוי במשימה. ב-jshint יש שלל של פרמטרים. אבל המינימום של המינימום הוא להואיל ולומר ל-jshint על איזה קבצים לעבוד. במקרה הזה אנו מבקשים ממנה לעבור על כל קבצי ה-js בתיקיה, כולל קובץ ה-Grunfile.js. זה הכל.
המתודה השניה שאנו קוראים לה היא grunt.loadNpmTasks שכוללת את כל המודולים שאנו צריכים שיעבדו עבור המשימות השונות. במקרה הזה יש לנו משימה אחת בלבד שהיא jshint.
יש עוד המון להרחיב על grunt, כמו למשל לבחור משימה דיפולטיבית או משימות דיפולטיביות, שאת זה עושים עם מתודת:
grunt.registerTask('default', ['jshint']);
אבל על זה נכתוב במדריכים הבאים. לפחות עכשיו אתם יודעים מה זה Grunt ואיך להשתמש בו. במאמר על טיפול בתחיליות של CSS3 אני מסביר על שימוש מעשי של Grunt.js. מומלץ לקרוא.