• בלוג
  • הוספת Babel לפרויקט Webpack

הוספת Babel לפרויקט Webpack

אם כבר הגדרתם פרויקט ווב עם Webpack בונוס נחמד שתוכלו לקבל יהיה להתאים את כל קבצי ה JavaScript שלכם לדפדפנים ישנים באמצעות Babel. בואו נראה איך עושים את זה ומה זה בכלל אומר דפדפן ישן.

1. מהו Babel

בעולם ה JavaScript פיצ'רים חדשים נכנסים לשפה כל הזמן, וגירסאות חדשות של דפדפנים יוצאות כל הזמן כדי לתמוך בפיצ'רים החדשים האלה, אבל עדיין אין לנו דרך להכריח את כל האנשים להתקין את הגירסאות הכי חדשות של כל הדפדפנים. לכן חלק לא מבוטל מהמשתמשים שלכם ימשיכו להריץ דפדפן שלא יודע מה ההבדל בין let ל const ולא שמע שאפשר להגדיר מחלקות עם המילה class.

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

https://babeljs.io/repl

דוגמא קטנה לקסמים של בייבל אפשר למצוא כשנדביק את הקוד הבא בפאנל השמאלי באתר שלהם:

class Point {

  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  equals(other) {
    return this.x === other.x && this.y === other.y;
  }
}

const c1 = new Point(10, 10);
const c2 = new Point(10, 10);
console.log(c1.equals(c2));

ומיד בפאנל הימני נקבל את הגירסא הארוכה יותר (אבל שעובדת ברוב הדפדפנים):

"use strict";

function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } }

function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

var Point =
/*#__PURE__*/
function () {
  function Point(x, y) {
    _classCallCheck(this, Point);

    this.x = x;
    this.y = y;
  }

  _createClass(Point, [{
    key: "equals",
    value: function equals(other) {
      return this.x === other.x && this.y === other.y;
    }
  }]);

  return Point;
}();

var c1 = new Point(10, 10);
var c2 = new Point(10, 10);
console.log(c1.equals(c2));

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

2. הגדרת דפדפני יעד עם Browserlist

בשילוב וובפאק ובייבל אצלנו על המכונה אנחנו נבקש מ Webpack להריץ את Babel על כל אחד מהקבצים בפרויקט תוך כדי תהליך שילוב הקבצים וכך קובץ הפלט שנקבל בתיקיית dist יכיל רק קוד שדפדפנים ישנים מוכנים להריץ. אבל רגע, מה זה בעצם דפדפנים ישנים? האם כרום 72 הוא ישן? ומה עם אקספלורר 11? ואיזה גירסא של ספארי נחשבת ישנה?

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

את browserlist נתקין עם:

$ npm install --save-dev browserslist

ולאחר מכן נריץ אותו כדי לראות את הדפדפנים בהם בייבל יתמוך:

$ npx browserslist

והתוצאה אצלי:

and_chr 75
and_ff 67
and_qq 1.2
and_uc 12.12
android 67
baidu 7.12
chrome 75
chrome 74
chrome 73
edge 18
edge 17
firefox 68
firefox 67
firefox 60
ie 11
ie_mob 11
ios_saf 12.2-12.3
ios_saf 12.0-12.1
ios_saf 11.3-11.4
kaios 2.5
op_mini all
op_mob 46
opera 62
opera 60
safari 12.1
safari 12
samsung 9.2
samsung 8.2

אנחנו יכולים לעדכן את הגירסאות באמצעות יצירת קובץ הגדרות בשם .browserslistrc. הקובץ מורכב משורות שכל אחת מגדירה עוד קבוצה של דפדפנים שנרצה לתמוך בה, לדוגמא:

> 5% in IL

שאומר שאנחנו רוצים לתמוך רק בדפדפנים שיש להם מעל 5% נתח שוק כאן בארץ, כלומר:

and_chr 75
chrome 75
chrome 74
ios_saf 12.2-12.3

או הגירסא הבאה שמוסיפה תמיכה גם בשתי הגירסאות האחרונות של Internet Explorer:

> 5% in IL
last 2 ie versions

והתוצאה היא רשימת הדפדפנים:

and_chr 75
chrome 75
chrome 74
ie 11
ie 10
ios_saf 12.2-12.3

בגדול ברירת המחדל של Browserslist תתאים לרוב המצבים ולכן מומלץ להשאיר את הקובץ עם השורה היחידה:

defaults

ולהוסיף דפדפנים כשעולה הצורך.

3. עדכון הגדרות Webpack כדי להפעיל גם את Babel

עכשיו שאנחנו מבינים מה Babel עושה ואיך הוא עושה את זה אפשר להמשיך ולחבר אותו ל Webpack. נתקין את Babel והפלאגין המתאים לוובפאק באמצעות:

npm install -D babel-loader @babel/core @babel/preset-env

ונעדכן את קובץ ההגדרות webpack.config.js כך שיכיל את התוכן הבא:

const path = require('path');

module.exports = {
  entry: './src/main.js',
  output: {
    filename: 'app.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
          },
        },
      },
    ],
  }
};

התוספת מתחילה במפתח module ובתוכו המפתח rules. אלה הכללים שאומרים ל Webpack מה לעשות עבור כל מודול, כלומר עבור כל קובץ JavaScript שמצאנו. המפתח test הוא החשוב ביותר באוביקט, והוא זה שמציין על איזה סוגי קבצים בכלל הפקודה הזאת משפיעה. במקרה שלנו הביטוי הרגולארי מציין קבצים שמסתיימים בסיומת js או mjs.

במפתח הבא, exclude, אנחנו משתמשים כדי לציין קבצים שבשום מקרה לא נרצה להפעיל עליהם את הקוד בכלל הנוכחי. אני רשמתי שם את הספריות node_modules ו bower_components שכן אלה תיקיות שבדרך כלל יישמרו בהם קבצי קוד שלקחתי מהאינטרנט, ואני סומך על מי שנתן לי את הספריות שכבר הפעיל את בייבל איפה שהיה צריך.

המפתח האחרון use הוא שקובע מה עושים על כל הקבצים האלה שהתאימו לשאילתה. הכתיב בדוגמא מפעיל עליהם את babel-loader, שזה רכיב שמחבר בין babel ל webpack. אופציית ה preset שהעברתי היא שגורמת לבייבל להסתכל על הקובץ .browserslistrc שיצרנו מוקדם יותר בפוסט ולפיו להחליט לאיזה דפדפנים לכוון.