עברית

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

פדרציית מודולים ב-JavaScript עם Webpack 5: מדריך מקיף למיקרו-פרונטאנדים

בנוף המתפתח תמיד של פיתוח ווב, בניית יישומים גדולים ומורכבים יכולה להיות משימה מרתיעה. ארכיטקטורות מונוליטיות מסורתיות מובילות לעיתים קרובות לזמני פיתוח ארוכים יותר, צווארי בקבוק בפריסה, ואתגרים בשמירה על איכות הקוד. מיקרו-פרונטאנדים הופיעו כתבנית ארכיטקטונית חזקה כדי להתמודד עם אתגרים אלה, ומאפשרים לצוותים לבנות ולפרוס חלקים עצמאיים של יישום רשת גדול יותר. אחת הטכנולוגיות המבטיחות ביותר ליישום מיקרו-פרונטאנדים היא פדרציית מודולים של JavaScript, שהוצגה ב-Webpack 5.

מהם מיקרו-פרונטאנדים?

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

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

היתרונות של מיקרו-פרונטאנדים:

האתגרים של מיקרו-פרונטאנדים:

מהי פדרציית מודולים של JavaScript?

פדרציית מודולים של JavaScript היא תכונה של Webpack 5 המאפשרת לשתף קוד בין יישומי JavaScript שקומפלו בנפרד, בזמן ריצה. היא מאפשרת לכם לחשוף חלקים מהיישום שלכם כ"מודולים" שניתן לצרוך על ידי יישומים אחרים, ללא צורך לפרסם אותם למאגר מרכזי כמו npm.

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

לדוגמה, צוות מערכת עיצוב (design system) יכול לחשוף רכיבי ממשק משתמש כמודולים, וצוותי יישומים שונים יכולים לצרוך את הרכיבים הללו ישירות מיישום מערכת העיצוב, מבלי להתקין אותם כחבילות npm. כאשר צוות מערכת העיצוב מעדכן את הרכיבים, השינויים משתקפים אוטומטית בכל היישומים הצורכים אותם.

מושגי מפתח בפדרציית מודולים:

הגדרת פדרציית מודולים עם Webpack 5: מדריך מעשי

בואו נעבור על דוגמה מעשית של הגדרת פדרציית מודולים עם Webpack 5. ניצור שני יישומים פשוטים: יישום מארח (Host) ויישום מרוחק (Remote). היישום המרוחק יחשוף רכיב, והיישום המארח יצרוך אותו.

1. הגדרת הפרויקט

צרו שתי ספריות נפרדות עבור היישומים שלכם: `host` ו-`remote`.

```bash mkdir host remote cd host npm init -y npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev npm install react react-dom cd ../remote npm init -y npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev npm install react react-dom ```

2. הגדרת היישום המרוחק (Remote)

בספריית `remote`, צרו את הקבצים הבאים:

src/index.js:

```javascript import React from 'react'; import ReactDOM from 'react-dom/client'; import RemoteComponent from './RemoteComponent'; const App = () => (

Remote Application

); const root = ReactDOM.createRoot(document.getElementById('root')); root.render(); ```

src/RemoteComponent.jsx:

```javascript import React from 'react'; const RemoteComponent = () => (

This is a Remote Component!

Rendered from the Remote Application.

); export default RemoteComponent; ```

webpack.config.js:

```javascript const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const path = require('path'); module.exports = { entry: './src/index', mode: 'development', devServer: { port: 3001, static: { directory: path.join(__dirname, 'dist'), }, }, output: { publicPath: 'auto', }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-env'], }, }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: 'remote', filename: 'remoteEntry.js', exposes: { './RemoteComponent': './src/RemoteComponent', }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, }, }), new HtmlWebpackPlugin({ template: './public/index.html', }), ], resolve: { extensions: ['.js', '.jsx'], }, }; ```

צרו את הקובץ `public/index.html` עם מבנה HTML בסיסי. הדבר החשוב הוא `

`

3. הגדרת היישום המארח (Host)

בספריית `host`, צרו את הקבצים הבאים:

  • `src/index.js`: נקודת הכניסה של היישום.
  • `webpack.config.js`: קובץ התצורה של Webpack.

src/index.js:

```javascript import React, { Suspense } from 'react'; import ReactDOM from 'react-dom/client'; const RemoteComponent = React.lazy(() => import('remote/RemoteComponent')); const App = () => (

Host Application

Loading Remote Component...
}>
); const root = ReactDOM.createRoot(document.getElementById('root')); root.render(); ```

webpack.config.js:

```javascript const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const path = require('path'); module.exports = { entry: './src/index', mode: 'development', devServer: { port: 3000, static: { directory: path.join(__dirname, 'dist'), }, }, output: { publicPath: 'auto', }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-env'], }, }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: 'host', remotes: { remote: 'remote@http://localhost:3001/remoteEntry.js', }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, }, }), new HtmlWebpackPlugin({ template: './public/index.html', }), ], resolve: { extensions: ['.js', '.jsx'], }, }; ```

צרו את הקובץ `public/index.html` עם מבנה HTML בסיסי (בדומה ליישום המרוחק). הדבר החשוב הוא `

`

4. התקנת Babel

בשתי הספריות, `host` ו-`remote`, התקינו את תלויות Babel:

```bash npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader ```

5. הרצת היישומים

בשתי הספריות, `host` ו-`remote`, הוסיפו את הסקריפט הבא לקובץ `package.json`:

```json "scripts": { "start": "webpack serve" } ```

כעת, הריצו את שני היישומים:

```bash cd remote npm start cd ../host npm start ```

פתחו את הדפדפן ונווטו אל `http://localhost:3000`. אתם אמורים לראות את היישום המארח עם הרכיב המרוחק מוצג בתוכו.

הסבר על אפשרויות תצורה מרכזיות:

טכניקות מתקדמות בפדרציית מודולים

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

Remotes דינמיים

במקום לקודד את כתובות ה-URL של יישומים מרוחקים בתצורת ה-Webpack, ניתן לטעון אותם באופן דינמי בזמן ריצה. זה מאפשר לכם לעדכן בקלות את המיקום של יישומים מרוחקים מבלי לבנות מחדש את היישום המארח.

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

```javascript // In webpack.config.js remotes: { remote: `promise new Promise(resolve => { const urlParams = new URLSearchParams(window.location.search); const remoteUrl = urlParams.get('remote'); // Assume remoteUrl is something like 'http://localhost:3001/remoteEntry.js' const script = document.createElement('script'); script.src = remoteUrl; script.onload = () => { // the key of module federation is that the remote app is // available using the name in the remote resolve(window.remote); }; document.head.appendChild(script); })`, }, ```

כעת תוכלו לטעון את היישום המארח עם פרמטר שאילתה `?remote=http://localhost:3001/remoteEntry.js`

מודולים משותפים עם ניהול גרסאות

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

ניתן לציין את טווח הגרסאות של כל מודול משותף בתצורת ה-Webpack.

```javascript // In webpack.config.js shared: { react: { singleton: true, eager: true, requiredVersion: '^18.0.0' }, 'react-dom': { singleton: true, eager: true, requiredVersion: '^18.0.0' }, }, ```

טועני מודולים מותאמים אישית

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

שיתוף מצב (State) בין מיקרו-פרונטאנדים

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

שיטות עבודה מומלצות ליישום מיקרו-פרונטאנדים עם פדרציית מודולים

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

דוגמאות מהעולם האמיתי של פדרציית מודולים בפעולה

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

סיכום

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

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