איך להתחיל פרויקט React ו Webpack מאפס על המכונה שלכם
פוסט זה כולל טיפ קצר לעבודה עם React. אם אתם רוצים ללמוד איתי ריאקט מההתחלה ובצורה מקצועית תשמחו לשמוע שבניתי קורס מלא הכולל עשרות שיעורי וידאו והמון תרגול בו לומדים ריאקט מההתחלה ועד לנושאים המתקדמים.
לפרטים נוספים והרשמה בקרו בדף קורס ריאקט כאן באתר.
עם השידרוג ל Webpack 4 גם כל ההגדרות של הכלי הפכו הרבה יותר פשוטות והיום בהרבה פרויקטים כבר לא צריך להתחיל עם משהו גדול כמו create-react-app ואפשר יחסית בקלות לבנות לעצמכם קובץ הגדרות Webpack שיגדל יחד עם הפרויקט שלכם.
בואו נראה איך לגשת לזה מאפס ולהגיע לפרויקט ריאקט שעובד.
1. התקנת הכלים
בשביל שנוכל להפוך קוד ריאקט לקוד שדפדפן יוכל לקרוא אנחנו צריכים כלי שנקרא Babel וכלי נוסף שנקרא Webpack. היחס ביניהם הוא ש Webpack מריץ את Babel על קבצי ה JavaScript שלכם ומייצר מהם קובץ JavaScript שדפדפן יכול לקרוא.
שני הכלים האלה הם חלק מה Eco System של Node.JS לכן המקום הראשון שתצטרכו ללכת אליו הוא התקנת Node.JS. אפשר להתקין את הגירסא העדכנית מהאתר שלהם כאן:
https://nodejs.org/en/download/
אחרי זה פותחים תיקיה חדשה עבור הפרויקט, נכנסים אליה מתוך ה CMD ובתוכה כותבים את הפקודות הבאות כדי לייצר מבנה פרויקט Node בסיסי:
npm install --save-dev babel-loader @babel/core @babel/preset-env webpack webpack-cli @babel/preset-react react react-dom
2. קובץ הגדרות מינימאלי
עכשיו אפשר להמשיך לקובץ הגדרות Webpack מינימאלי עבור Webpack 4 ומסתבר שצריך מעט מאוד הגדרות בשביל להתחיל לעבוד. פיתחו את תיקיית הפרויקט החדש בעורך הטקסט האהוב עליכם וכיתבו בתוכה קובץ בשם webpack.config.js עם התוכן הבא:
module.exports = {
entry: './src/index.js',
output: {
path: __dirname + '/dist',
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
}
}
}
]
},
};
הקוד שכתבנו מגדיר אוביקט שמתאר ל Webpack איך להפוך את הפרויקט שלנו מקבצי JavaScript שמכילים קוד React (כלומר קבצי jsx) לקבצי JavaScript רגילים שדפדפן יכול לקרוא. כל מפתח באוביקט הזה מציין משהו לגבי מבנה הפרויקט או ההמרה שאנחנו רוצים לבצע.
המפתח הראשון, entry, מציין את נקודת הכניסה לפרויקט. בפרויקטים יותר מורכבים אפשר יהיה לציין יותר מקובץ אחד, ובינתיים זה אומר ש Webpack מחפש את הקובץ הזה, וממנו ימשיך ויחפש את כל הקבצים שקובץ זה טוען באמצעות import. כש Webpack מסיים למצוא את כל הקבצים הוא יבצע המרה על כולם ויחבר את התוצאות לקובץ יחיד.
שם קובץ התוצאה היחיד והנתיב אליו הם בדיוק מה שאנחנו קובעים במפתח הבא, output. רק עד לכאן יש לנו קוד שיודע לקחת קובץ שטוען קבצים אחרים באמצעות import ולהפוך את כל עץ הקבצים שהוא טוען לקובץ js יחיד במקרה שלנו בשם bundle.js שנשמר בתיקיה בשם dist.
המפתח האחרון, module, מספר ל Webpack איזה פעולות נוספות צריך לבצע על הטקסט במהלך ההמרה שלו מ src/index.js ל dist/bundle.js. המפתח מורכב מכללים וכל כלל מציין בדיקה (במפתח test), ו use שאומר מה לעשות עם הקבצים שעוברים את הבדיקה. בקובץ שלנו הבדיקה היא האם הקובץ מסתיים ב js או jsx, המפתח exclude אומר שאנחנו מתעלמים מקבצים שנמצאים בתיקיית node_modules
והערך babel-loader במפתח use קובע שכל קובץ js או jsx יעבור דרך הכלי שנקרא Babel. כלי זה הוא שימיר את ה JSX לקוד JavaScript תקני.
נעבור לכתוב את הקובץ src/index.js כך שיכיל קוד JSX. הנה תוכן לדוגמא לקובץ זה:
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
render() {
return <p>Hello World</p>
}
}
ReactDOM.render(<App />, document.querySelector('main'));
ולסיום נפתח תיקיה בשם dist ובתוכה נכתוב קובץ בשם index.html עם התוכן הבא:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Public</title>
</head>
<body>
<main></main>
<script src="bundle.js"></script>
</body>
</html>
חיזרו לשורת הפקודה ושם רישמו:
node node_modules/webpack/bin/webpack.js -d
התוצאה אצלי על המחשב נראית כך:
Hash: 4be067e54e5bddfc520d
Version: webpack 4.28.4
Time: 1022ms
Built at: 01/11/2019 8:18:57 PM
Asset Size Chunks Chunk Names
bundle.js 2.1 MiB main [emitted] main
Entrypoint main = bundle.js
[./node_modules/webpack/buildin/global.js] (webpack)/buildin/global.js 472 bytes {main} [built]
[./src/index.js] 2.66 KiB {main} [built]
+ 11 hidden modules
וקיבלנו קובץ JavaScript בגודל שני מגה שמכיל את ה-5 שורות שכתבנו ועוד אינסוף קוד של סיפריות ושטויות של Babel ו Webpack. בשביל ההתרשמות הכללית נסו לפתוח את הקובץ dist/bundle.js בעורך הטקסט האהוב עליכם וחפשו את הקוד שכתבתם בעצמכם.
אחרי שמצאתם (או שלא, זה לא כזה משנה) פיתחו את הקובץ dist/index.html בדפדפן כדי לראות את המשפט Hello World על המסך.
3. פיתוח מול ייצור
בתוך שני המגה האלה של קובץ ה JavaScript וובפאק הוסיף הרבה מאוד מידע שעוזר לנו בשלבי ה Debug של היישום. בשביל לראות את זה פיתחו את הקובץ dist/index.html בתוך דפדפן, ביחרו Inspect Element, עברו לטאב Sources ושם בצד שמאל תוכלו למצוא תיקיה בשם webpack. לחיצה עליה תפתח לכם את כל קבצי הפרויקט בגירסת ה Source שלהם, כלומר לפני ש Webpack הפך אותם לקבצים שדפדפן יכול להריץ. הפיצ'ר שמאפשר את זה נקרא Source Maps והוא מעולה כדי לשים נקודת עצירה ולמצוא בעיות בקוד.
יחד עם זאת שני מגה לקובץ JS זה לא משהו שאפשר לעלות איתו לייצור ולכן יש ל Webpack גם מצב Production שגורם ליצירת קובץ קטן בהרבה. נריץ משורת הפקודה את הפקודה הבאה:
node node_modules/webpack/bin/webpack.js -p
והפלט הפעם נראה כך:
Hash: 2f3b4f02f11dbff5475a
Version: webpack 4.28.4
Time: 2767ms
Built at: 01/11/2019 8:27:10 PM
Asset Size Chunks Chunk Names
bundle.js 111 KiB 0 [emitted] main
Entrypoint main = bundle.js
[3] ./src/index.js 2.66 KiB {0} [built]
[8] (webpack)/buildin/global.js 472 bytes {0} [built]
+ 7 hidden modules
אותו קובץ js ירד לגודל של קצת מעל 100k. זה עדיין הרבה בשביל להגיד Hello World אבל זה המחיר שמשלמים על השימוש בפריימוורק.
4. התקנת סיפריות נוספות
במהלך העבודה שלנו על הפרויקט יש סיכוי טוב שנרצה להוסיף סיפריות נוספות מ npm ולשלב גם אותן בקוד. רק עבור ריאקט יש סיכוי טוב שתירצו את Immutable ואת Redux, וכמובן שיש עוד המון סיפריות שאפשר לדמיין לעבודה השוטפת.
במבנה הפרויקט שכתבנו קל מאוד להוסיף סיפריות חדשות באמצעות הכלי npm. נניח שאנחנו רוצים להוסיף את סיפריית underscore.js מ npm ולשלב אותה בקוד. בשביל זה נתחיל עם הפעלת הפקודה הבאה משורת הפקודה:
npm install --save-dev underscore
ולאחר מכן נוכל להשתמש בסיפריה ישירות מכל קובץ js שיש לנו בפרויקט פשוט באמצעות import. כך יוכל להיראות הקובץ src/index.js שירצה להשתמש בסיפרית underscore:
import React from 'react';
import ReactDOM from 'react-dom';
import _ from 'underscore';
class App extends React.Component {
render() {
return <p>Hello {_.random(10)}</p>
}
}
ReactDOM.render(<App />, document.querySelector('main'));
עכשיו בכל טעינה של הדף תקבלו על המסך מספר אקראי שהגיע מהפונקציה random של סיפריית underscore.
5. מה הלאה
ל Webpack יש עוד המון הגדרות, על חלקן אני מספר כאן בקורס ES6 ועל חלקן שווה לכתוב פוסט המשך (או 5). בכל מקרה התיעוד שלהם מעולה ואני חושב ששווה להשקיע יום או יומיים בקריאה שלו ובניסוי כל מיני אפשרויות משם. כדאי להתחיל מכאן: