2013-06-25

47 ספריות ג'אווהסקריפט שכל מפתח *חייב* להכיר (חלק ב')


בפוסט הקודם סקרנו כ 21 מתוך 47 ספריות שכל מפתח ווב "חייב" להכיר (כלומר: לדעת על קיומן), בפוסט זה נמשיך את הרשימה.


בדיקות-יחידה ואוטומציה



יסמין (Jasmine) היא ככל הנראה הספריה הפופולריות ביותר היום לכתיבת בדיקות-יחידה בצד-הדפדפן. בעבר הספרייה הפופולרית ביותר הייתה QUnit (אם כי היא עדיין פופולרית למדי). לפניה הייתה גם ספרייה בשם jsUnit, שכמעט ואיננה רלוונטית היום.

Jasmine כוללת תחביר אלגנטי שמושפע מ RSpec (כלומר BDD), כך הקוד שדומה יותר לטקסט בשפה האנגלית, נוסח:
expect(items.length).toBeGreaterThan(6);

Jasmine היא דיי מקיפה וכוללת יכולות לבדיקת קוד אסינכרוני (פקודות waitFor ו runs) ו Mock Objects (ליתר דיוק: Spies או fakes).

QUnit היא ספריית הבית של jQuery. היא פשוטה יותר ומבוססת על תחביר פחות אלגנטי של xUnit נוסח:
ok(items.length > 6); // ok = "assertTrue"
או
strictEqual(0, items.length); // strict to reflect ===

הייחוד של QUnit הוא ביכולת שנקראת Fixtures - היכולת "לשתול" ב DOM קטע של HTML עליו יתבצע הבדיקה - ולהעיף אותו מיד אחריה. ניתן לעשות זאת גם ב Jasmine - במחיר של מספר שורות קוד.
שינויי DOM בעת הבדיקה לא הטכניקה המומלצת לבדיקות-יחידה - אבל לעתים היא נדרשת. במיוחד אם אתם ספרייה שבעיקר עובדת על גבי ה DOM - כמו jQuery.

מכיוון שאין ל QUnit יכולות של Mock Objects, מצמדים אותה לרוב עם ספרייה בשם Sinon - ספרייה עשירה, אלגנטית וטובה ליצירת Mock Objects בג'אווהסקריפט מכל הסוגים (Spy, stub, mock או fake).

בגלל האופי הדינמי של שפת ג'אווהסריפט - קל מאוד לייצר בה Mock Objects. מספר פעמים יצא לי לצרף את Sinon ל Jasmine - בכדי "לכתוב קוד אלגנטי יותר", אך בכל הפעמים גיליתי ש sinon לא מצדיקה את עצמה כש Jasmine בסביבה: Jasmine עם קצת אלתור מספקת יכולת מקבילה ל Sinon - כך שלא הייתה הצדקה להשתמש בספרייה נוספת. הסבר: אני מקפיד להיפטר מספריות שאני משתמש בפונקציה אחת או שתיים שלהן - שאני יכול לכתוב בעצמי ב 5 דקות. (ע"פ עקרון ה segregation of interfaces + כדי לא ליצור דילמה חוזרת באיזה כלי להשתמש לכל בדיקה).

Mocha (מוקה) היא ספרייה שמשתמשים בה יותר ב Node.js, אבל היא מתאימה גם לדפדפן. אפשר לבחור להשתמש בה בתחביר BDD (כמעט כמו התחביר של Jasmine, אך טיפה פחות אלגנטי) או xUnit (נקרא משום מה "TDD") - שניהם נתמכים. למוקה מצד שני, יש תחביר יפה לבדיקות אסינכרוניות (ולכן כנראה אוהבים אותה ב Node). עבור Mock objects מצמדים לה את sinon.

Mocha מבצעת גם הרצה של הבדיקות כך שהיא לא זקוקה ל jsTestDriver. פיצ'רים נחמדים הם סימון בדיקות אטיות כמו ב Karma (כדי שתשפרו אותן או תעבירו אותן ל suite של האינטגרציה) וגילוי קוד שכותב משתנים למרחב הגלובלי.


תרשים המתאר בקירוב את תחום הכיסוי של כל ספרייה.
כשעבדנו ב JUnit נהגנו לקבל הכל ביחד, אולם בג'אווהסקריפט עדיין עליכם "לקושש" יכולות בכדי להגיע לתמונה המלאה.


ספריות חדשות בברנג'ה הן Karma, Intern ו Casper.

Intern מנסה לספק פתרון בדיקות-יחידה מקיף, מקצה-לקצה, שאין כדוגמתו עד היום (כלומר: יש להרכיב כיום מספר ספריות שונות על מנת לקבל אותו). דברים כגון: הקמה, כתיבת בדיקות, הרצת בדיקות, CI, Coverage וכו'.
עצתי אליה: שתשקיע באינטגרציה ל IDEs - כרגע זה לא נראה על המפה שלה. היא נשמעת מבטיחה מאוד - אבל היא עדיין הספרייה עם הכי פחות משתמשים (בינתיים).

Karma (לשעבר Testacular (נשמע כמו "אשכים"?), מבית Angular.js מבית גוגל) היא פורט של jsTestDriver (הכתוב ב java) ל Node.js (כלומר היא כתובה בג'אווהסקריפט ומריצה ג'אווהסקריפט).

עבדתי עם Karma מעט ומאוד אהבתי. היא כוללת את כל היכולות של jsTestDriver וקצת יותר, היא נראית יציבה יותר מ jsTestDriver (שהשרת שלה לא חי זמן רב ללא restart), היא עובדת טוב יותר עם AMD/require.js, ונראה שחלק גדול מהקהילה של jsTestDriver עובר אליה. היא יודעת להאזין למערכת הקבצים לשינויים ולהריץ את הבדיקות לבד ברקע - מוד עבודה נהדר ל TDD! יש לה את כל הנתונים להצליח בגדול.

היתרונות של jsTestDriver כרגע: אינטגרציה ל WebStorm ו Eclipse וקהילת משתמשים קיימת.

Casper הוא עוד כוכב עולה: הוא מיועד לכתיבת בדיקות אינטגרציה שהן יותר מבדיקות-יחידה אבל עדיין לא בדיקות UI (כלומר Selenium).
Casper מבוסס על Phantom.js (כלומר headless webkit - דפדפן ללא Shell) ויכול לבדוק את קוד הג'אווהסקריפט עם DOM ו CSS. היתרון על Selenium: הוא מהיר הרבה יותר. החיסרון: זה לא דפדפן אמיתי. התנהגויות ייחודיות לדפדפנים ספציפיים לא ישתקפו בו.

אם אתם רציניים לגבי אוטומציה - זהו כלי שבהחלט כדאי לבדוק!

הערה: עם ההצגה של WebDriver, יכול Selenium להריץ גם את Phantom.js ולהנות מהמהירות של דפדפן ללא Shell / שלא מצייר באמת על המסך. יש פה באמת פתח לתחרות אם כי נראה ש Casper דווקא הולך וצובר מומנטום למרות עובדה זו.



Template Engines


Template Engines הן הספריות שחוסכות מאתנו ללכלך את קוד הג'אווהסקריפט שלנו עם concatenations של מקטעי HTML.

מוד העבודה הוא לרוב כזה:
  • כתוב template ל HTML sinppet רצוי והשאר "placeholders" לחלקים הדינמיים.
  • אכסון את ה template כ string, כמקטע בלתי-נראה ב HTML או טען אותו ב ajax מהשרת.
  • "קמפל" (בעזרת ה Template Engine) "אוטומט" של ה template. תוצאת הקומפילציה היא פונקציה שמקבלת נתונים מתאימים ומייצרת על בסיס ה template מחרוזת HTML מתאימה. הערה: פעולת הקומפילציה היא אטית 
  • הפעל את הפונקציה שנוצרה כדי להזריק נתונים ולקבל HTML snippet מעודכן - פעולה זו היא מהירה.

יש ה-מ-ו-ן ספריות של Template Engines: אני מכיר כ 15.
במבט ראשון, קשה מאוד להבין מה ההבדל. אפילו קריאה מהירה של ה tutorials - לא מגלה הבדלים משמעותיים בין הספריות.

אז מה בעצם ההבדלים? מדוע צריך כ"כ הרבה ספריות?
  • יש ספריות מהירות יותר ומהירות פחות בהזרקת הנתונים (חלקן יודעות "להזריק ל DOM" רק את מה שהשתנה)
  • יש ספריות מהירות יותר בשלב הקומפילציה.
  • (יש ספריות שלא מאפשרות קומפילציה - אבל מעט).
  • יש ספריות בתחביר ERB / JSP קרי < val %> ויש כאלו בתחביר {{ val }} - ענין של סגנון.
  • יש כאלו עם מעט לוגיקה של templating (לולאות, תנאים), יש כאלה עם הרבה לוגיקה (פונקציות, משתנים, ...) ויש כאלו שבתור עקרון לא מאפשרות לוגיקה (כי לוגיקה אמורה להיות ב Model ולא ב View).
  • יש ספריות גדולות (כ 2k) או גדולות (כ 30K ויותר).
  • חלקן מתאימות יותר לצד הלקוח (דפדפן) וחלקן מתאימות יותר לצד השרת (node).
  • נראה אבל שהגרום המשמעותי לכך שיש כ"כ הרבה ספריות הוא שלרובן יש פטרון חשוב, מישהו שמקדם אותן ושומר על קיומן. מיד אחשוף מעט מהפוליטיקה המורכבת הזו.


בהחלט רשימה חלקית

אינני מתכוון לעשות השוואה מקיפה של כל היכולות הנ"ל עבור הספריות השונות - אינני יודע את כל הפרטים. לצערי גם לא מצאתי טבלת השוואה טובה ביניהן.

שתי הספריות הבולטות ביותר הן כנראה mustache.js  ו handlebars.

Mustache.js (שבולטת בתחביר ה {{ x }}). הסוגריים המסולסלים נראים כ"שפם" שסובבו ב90 מעלות - ומכאן שמה. היא פשוטה ובעלת קהילה גדולה. הפטרון שלה הוא פרויקט mustache שיצר מימושים של התחביר לשפות תכנות שונות, javaScript היא רק אחת מהן. Mustache מקפידה לא לאפשר לוגיקה עסקית ב template. המימוש של mustache.js אינו "מקפל" templates ולכן איננה כ"כ יעילה. Handlebars ו Hogan הן ספריות המממשות את תחביר mustache בצורה יעילה.

Handlebars (מקור השם) היא הרחבה של Mustache המספקת יכולות משופרות, בעיקר רינדור הדרגתי ב DOM רק של מה שהשתנה - מה שגורם לה להיות אחרת הספריות המהירות בהזרקת נתונים. היא נכתבה ע"י יהודה כץ, וכך פטרון מרכזי של Handlebars היא ספריית Ember.js (שראינו בחלק א' של הפוסט).

Jade היא לא ספרייה קטנה (כ 40kb) וכל כן כנראה היא פופולרית יותר בצד השרת (קרי node). הפטרון שלה הוא express.js - ספרייה מאוד דומיננטית ב node (סוג של low level Servlet ב node). jade הוא ה default שלה לייצור HTML markup.

Hogan.js היא ספרייה קטנה ומהירה מאוד שטובה ל templates פשוטים. היא תומכת בתחביר של mustache, ללא כל תוספות. הפטרון שלה הוא חברת טוויטר.

dust.js נחשבת ספרייה מבטיחה. הפטרון שלה הוא חברת LinkedIn.

doT.js היא עוד ספרייה פצפונית (פחות מ 3k) שטוענת להיות מאוד מהירה ותומכת בכתיבת לוגיקה. אין לי מושג מי הפטרון שלה... אבל בטח יש מישהו!

jsRender - היא "הדור הבא של jQuery Templates". אני מניח ש jQuery Templates הייתה פופולרית בזכות המותג "jQuery", אבל עובדה שזה לא הספיק לה. היא נסגרה. אינני יודע להשוות את jsRender לאחרות, אבל נדמה לי שהפופולריות שלה בנסיגה. הפטרון: רוחה של jQuery Templates.


איך משווים בין כל הספריות? איך בוחרים?
  1. אם אתם משתמשים בספרייה שעובדת עם אחד מהמנועים - נסו להיצמד אליה ולחסוך לעצמיכם בעיות אינטגרציה.
  2. נסו את http://garann.github.io/template-chooser/ - אתר שכל ייעודו לנסות לעזור לכם לבחור Template Engine.
  3. לא עזר? הייתי מהמר על הגדולות: Hogan - למשימות מיני, Mustache למשימות קטנות או Handlebars למשימות גדולות ומורכבות.



טעינת סקריפטים דינמית, AMD ו CommonJS


פירטתי על ספריות אלו והקשרים בניהן בפוסט require.js - צלילה לעומק.


אני חושב שבפוסט ההוא תמצאו תמונה דיי מפורטת של היחסים בין הספריות:
תרשים מתוך הפוסט.



גרפיקה וויזואליזציה


פירטתי על קטגוריה של ספריות אלו בפוסט ויזואליזציה בצד הדפדפן.


מאז הפוסט נראה ש D3 (קיצור של Data Driven Documents) רק הולכת וצוברת תאוצה!
מזכירים אותה המון, ומשתמשים בה בהמון פרויקטים - משמעותית יותר משאר הספריות בקטגוריה.

תרשים מתוך הפוסט

לינק: סקירה נוספת לספריות ויזואליזציה.


ספריות אחרות

כמה ספריות שלא התאימו לי לשום קטגוריה, אך הן עדיין חשובות למדי:


Modernizr - "הספריה" ל Feature Detection. במקום לעקוב אחרי גרסאות הדפדפנים (כבר אי אפשר [א]) והיכולות שלהם, קרי "IE8 לא תומך ב SVG, אז נבצע fallback ל gif" - אפשר לשאול בעזרת Modernizr: "דפדפן, האם אתה תומך ב SVG?" ולפעול בהתאם. דרך כתיבה זו הרבה יותר אמינה (robust) לאורך זמן.

על feature detection ו שימוש ב Modernizr ניתן לקרוא בעברית בבלוג אינטרנט-ישראל.

Underscore.js - היא ספרייה נוספת מהיוצר של Backbone שמספקת utilities רבים: עבודה עם מערכים ואובייקטים, תכנות פונקציונלי או סתם utilities שעוזרים לכתוב קוד קצר יותר. כמו ש jQuery תופסת את השם "$", Underscore תופסת את השם "_" ומכאן שמה. לדוגמה:
_.sortBy(array, function(n) {...});

פעמים רבות רציתי להשתמש ב underscore. צירפתי אותה למספר פרויקטים - אבל היא לא שרדה שם ללא Backbone (שם היא מתאימה כמו כפפה ליד): יכולות של ECMAScript 5 (כגון foreach על מערך) והסט המצומצם של utilties של jQuery (כמו each, filter, extend) - סיפקו את הסחורה מספיק טוב כדי לייתר את Underscore.

בקיצור: זו ספרייה יפה. סביר שתשמעו עליה ותתקלו בה בפרויקטים או פוסטים שונים על ג'אווהסקריפט, אבל אני אישית עדיין מעדיף לממש פונקציה אחת בעצמי מאשר להוסיף תלות לספרייה. אולי יום אחד היא עוד תצדיק את עצמה באחד הפרוייקטים שאני עובד עליהם.


על Bootstrap ו Foundation ניתן להסתכל בשני אופנים:
  1. סט מוכן של של CSS files (ומעט javaScript משלים) לשימוש מהיר באתרי אינטרנט.
  2. ספריית UI מבוססת CSS ולא ג'אווהסקריפט - ועל כן רזה ומהירה. 
שתי דרכי ההתבוננות נכונות במידה, אולם אני רוצה לפרגן ולהתמקד בנקודת המבט השנייה.

אי אפשר להתעלם מכך שרוב ה"קוד" בספריות אלו כתוב ב CSS - זה אולי מטריד כמה אנשים, אולם בסופו של יום הן מספקות פונקציונליות מקבילה ל jQuery UI או כל ספריית פקדים אחרת. מלבד הפשטות והביצועים הטובים שנובעים מהשימוש ב CSS, הן מאפשרות Responsive Design מובנה - כך שה"פקדים" או "Layouts" שלהם יתאימו את עצמם לכל גודל של מסך: מסך מחשב, טאבלט או סמארטפון - ויעשו את זה יפה. זה חלק מהיתרון של שימוש ב CSS.
שתי הספריות יכולות לעבוד יפה מאוד עם ספריות שאינן כוללות פקדים כגון MVC או Meteor.

נראה שההתפתחות של CSS3 (שהוא מתקדם בהרבה מ CSS2.1) - הוא שאפשרה זן חדש זה של ספריות.

אופי העבודה עם הספריות גם הוא דיי שונה:
  • לכל ספרייה של כ 100-200 CSS classes שעליכם להצמיד ל DOM במקומות הנכונים. יש כללים שיש ללמוד אילו classes יכולים להשתלב עם אחרים. "מאות CSS Classes" נשמע כדבר מאיים, אך ישנה חוקיות פשוטה ו references טובים שיאפשרו לכם להסתדר איתם בקלות.
  • הפקדים שנוצרים הם דיי "שמרנים". אלו לא ספריות ל UI "סקסי ויוצא דופן" - אלו ספריות ל UI פשוט, אסתטי, אך לא מתחכם. לא תקבלו את פקד ה Date המשוכלל של jQuery UI, למשל. Bootstrap ו Foundation מתאימות במיוחד ל Multiple Page Applications (בניגוד ל SPA) - אפליקציות בעלות מספר רב של מסכים, שאנו רוצים שיהיו אחידים. אלו לרוב יהיו "אתרי אינטרנט המשרתים back-end" או LOB Applications (כלומר: אפליקציות עסקיות).
  • הנתונים עבור הפקדים לא מגיעים מקריאת JavaScript - הם מגיעים מה DOM. יש classes של תיאור נתונים ו classes של "קשירת נתונים לפקד". איך הם מגיעים ל DOM? אולי מצד השרת (RoR, Java, node או ASP.NET), אולי ע"י קוד ג'אווהסקריפט (הנעזר ב template engine?) הדוחף אותם ל DOM. כלומר: מודל זה לא מיטיב מבחינת ביצועים עם אפליקציות שמחליפות נתונים כל הזמן (כמו Dashboards|).
התוצאה היא שאפשר דיי להסתבך ב SPA כשמנסים לעבוד איתן, אבל אפשר להתחיל מהר ולהתקדם מהר כשעובדים על MPA (כקונספט, יכולה להיות MPA עם דף אחד).

האם Bootstrap ו Foundations הן "הדבר הבא"? הדעות חלוקות.
כרגע הן קונספט חדש, מעניין וחם - שכדאי להכיר.


אז מה ההבדלים בין שתי הספריות?
  • Bootstrap (מבית טווטיר) משתמשת ב LESS, בעוד Foundation משתמשת ב SASS (כיסיתי את LESS ו SASS בפוסט זה). אם אתם מושקעים כבר באחד הכלים - הרי לכם מוטיבציה להעדיף ספרייה אחת על השנייה.
  • ל Bootstrap יש בפירוש קהילה גדולה יותר. הנה אתר עם יותר מ 300 plugins והרחבות ל bootstrap. נ.ב.: הנתונים של JSter נראים מוגזמים לחלוטין, לפיהם נראה כאילו Bootstrap היא הספרייה הפופולרית בכל הפוסט - זה לא המצב.
  • Bootstrap תומכת ב IE7-8 (אם אתם פונים למגזר העסקי - זה משמעותי).
  • Foundation נחשבת גמישה יותר לשינויי עיצוב.
  • יש עוד הרבה הבדלים קטנים בפרטים ובסגנון של כל ספרייה.


סיכום

עברנו על מספר לא מבוטל של ספריות (47!). אני מאמין ש"התמצאות במרחב הספריות" היא חשובה ויכולה בהחלט לסייע, אפילו אם לא תשתמשו ביותר מרבע מהן עד יום מותכם.
  • הסיכוי ללמוד כך על קיום ספרייה שאולי תזדקקו לה בקרוב (או אף היום) - שווה את המאמץ.
  • גם ללא שימוש בספריה ניתן להיות מושפעים מרעיונות שהיא מציגה.
  • לא תצאו טמבלים חסרי ידע בשיחה עם מקצוענים אחרים בתחום.


שיהיה בהצלחה!


---

[א] כשגרסאות דפדפן יוצאות בקצב של 6 שבועות (כרום, פיירפוקס) או פעם בשנה (ספארי, IE) - כבר לא סביר באמת לעקוב בקוד אחר הגרסאות.


קישור רלוונטי:
https://github.com/codylindley/frontend-tools
הרבה ספריות Frontend וכמה השוואות

רשימה של ספריות Polyfill - ספריות שמאפשרות תכונות "חדשות" בדפדפנים "ישנים".


6 תגובות:

  1. אנונימי26/6/13 00:07

    נחמד ומוסיף
    (מתגעגע לפוסטים המעמיקים יותר שלך)

    השבמחק
  2. אנונימי26/6/13 01:38

    מסכים עם ידידי מלמעלה

    השבמחק
    תשובות
    1. תודה על התגובות.

      אני חושב שהפוסט כן כולל הרבה ידע:
      * מיהן הספריות החשובות? - לוקח זמן להכיר שהן בכלל קיימות
      * מה הפאנץ' ליין / ההבדלים המהותיים בין אופציות בכל קטגוריה - גם דבר שלוקח זמן רב להכיר ויכול לשמש נקודת פתיחה טובה יותר ל evaluation.

      בקיצור, אני חושב ש"התמצאות במרחב הפתרונות הקיימים" הוא חשוב ושימושי לא פחות מחפירה ב internals של הדפדפן. בכל זאת, אני מכבד את דעתכם.

      ליאור

      מחק
  3. אנונימי27/6/13 13:14

    רציתי לשאול שאלה:
    האם אתה מכיר יכולת של חיבור הרצה ותוצאות של בדיקות-יחידה לדו"ח של בילד ב-TFS?

    השבמחק
    תשובות
    1. היי,

      אני מניח ש TFS הוא Team Foundation Server (משהו כמו SVN + Sonar - בעולם ה NET.).
      אני לא מכיר את TFS ולא יודע כמה הוא פתוח, אבל לפחות Karma ו Mocha יודעים לייצא את הנתונים בכמה פורמטים. הסטנדרטי בהם הוא כנראה הפורמט של JUnit. צריך לחפש ולראות...

      בקיצור: אני לא מכיר.

      מחק
    2. אנונימי27/6/13 14:27

      תודה

      מחק