רן בר-זיק     לפני 9 שנים     כ- 3 דקות קריאה  

grunt watch | אינטרנט ישראל

תוכנה

זה מאמר שמלמד על grunt. אם אתם לא יודעים מה זה grunt, כדאי שתעיינו במאמר המלמד על Grunt.js ומסביר על ההתקנה ומה זה בכלל.
כשאני משתמש ב-uglify לקבצי ה-JavaScript שלי, autoprefixer לקבצי ה-CSS שלי ודברים נוספים (כמו csslint ו-jshint) אז אני לא רוצה לשנות את קבוץ ה-CSS או ה-JS ואז להריץ את ה-grunt בכל פעם כדי שיריץ את כל התהליכים שאני צריך כמו להוסיף תחיליות, לכווץ ולנקות. אני רוצה שכל התהליכים האלו ירוצו ברגע שאני משנה את אחד מקבצי ה-JS או ה-CSS. ואז כשאני ארפרש את האפליקציה אני אוכל לראות את השינוי שעשיתי.

את זה עושים באמצעות grunt watch. מדובר במודול של grunt שיושב ומאזין לקבצים שאני אומר לו להקשיב – לצורך העניין לקבצי המקור של CSS ו-JS. ברגע שיש שינוי כלשהו, הוא יריץ את המשימות שאני אומר לו.

איך זה עובד? קודם כל… התקנה של המודול

npm install grunt-contrib-watch

עכשיו צריך לומר ל-grunt בפרויקט שהמודול הזה קיים. ניכנס ל-Gruntfile.js ונכניס את השורה הזו שבעצם מודיעה ל-Grunt לטעון את המודול.

grunt.loadNpmTasks('grunt-contrib-watch');

כל מה שנותר הוא להוסיף משימה ל-Grunt. במקרה הזה watch:

	watch: {
	  scripts: {
	    files: ['source/*.css'],
	    tasks: ['postcss'],
	    options: {
	      spawn: false,
	    },
	  },
	}

מה יש לנו כאן? הגדרתי watch. שלושת הדברים היחידים שאני צריך להגדיר הוא files – אחרי אלו קבצים או תיקיות אני צריך לעקוב. במקרה הזה הגדרתי שהוא יעקוב אחר כל קבצי ה-CSS. אבל אני יכול להוסיף גם קבצי JS או בכלל להכניס את כל תיקית הפרויקט.
הדבר השני הוא אילו משימות ירוצו כאשר יהיה שינוי. במקרה הזה בחרתי רק במשימה אחת: postcss, אבל אני יכול להכניס משימות רבות נוספות כמו uglify ו-lint.
ב-options כדאי להשאיר את spawn כ-false כי זה יבטיח עבודה יותר מהירה.

אם אתם סקרנים לדעת, כך נראה הקובץ השלם:

module.exports = function(grunt) {

    grunt.initConfig({
        postcss: {
            options: {

                processors: [
                    require('autoprefixer-core')({
                        browsers: ['last 2 versions', 'Android >= 2.3']
                    }), // add vendor prefixes
                ]
            },
            main: {
                expand: true,
                flatten: true,
                src: 'source/*.css',
                dest: 'css/'
            }
        },
        watch: {
            scripts: {
                files: ['source/*.css'],
                tasks: ['postcss'],
                options: {
                    spawn: false,
                },
            },
        }
    });

    grunt.loadNpmTasks('grunt-postcss');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.registerTask('default', ['postcss']);

};

מה יש לנו פה? בגדול קובץ Gruntfile.js סטנדרטי לחלוטין. ב-initConfig אני מגדיר 2 משימות. הראשונה היא postcss שעליה דיברתי במאמר על תחיליות ב-CSS3. השניה היא משימת watch שאותה הראיתי קודם. בסוף הקובץ אני משתמש ב-loadNpmTasks על מנת לטעון את מודול postcss ואת contrib-watch. אני משתמש ב- grunt.registerTask('default', ['postcss']); על מנת להגדיר את postcss כ-default.

מה ש-watch עושה הוא לעקוב אחר קבצי ה-CSS שיש בתיקית source וברגע שמישהו מהם משתנה, הוא יפעיל את postcss.

איך זה נראה בפועל? ככה:

$ grunt watch Running "watch" task Waiting... >> File "source/transform2d.css" changed.  Running "postcss:main" (postcss) task >> 1 processed stylesheet created.  Running "watch" task Completed in 0.117s at Sat Jul 11 2015 20:41:11 GMT+0300 (IDT) - Waiting...
הפעלה של grunt watch שעוקב אחר קבצים ומפעיל תהליכים אוטומטית.
$ grunt watch
Running "watch" task
Waiting...
>> File "source/transform2d.css" changed.

Running "postcss:main" (postcss) task
>> 1 processed stylesheet created.

Running "watch" task
Completed in 0.117s at Sat Jul 11 2015 20:41:11 GMT+0300 (IDT) - Waiting...

זה הכל! פשוט וקל ובלי להתאמץ. למי שמשתמש ב-yeoman או בדומיו ולא הבין איך בדיוק האפליקציה יודעת להפעיל את ה-build בכל שינוי – זה נעשה כך.

במאמר הבא על Grunt אני מסביר איך לטעון מודולים אוטומטית ב-Grunt ללא כתיבה של loadNpmTasks שוב ושוב ושוב בכל פעם שאני משתמש במודול חדש.