Mari bersama-sama membangun aplikasi dengan mikro frontend

Pada artikel ini, saya akan memandu Anda tentang cara mengimplementasikan aplikasi mikro frontend dengan spa tunggal dan federasi modul di Webpack.

Contoh Repositori

Berikut adalah basis kode terakhir di GitHub:



Isi

Frontend Mikro

Micro frontend telah ada sejak tahun 2016 dalam perkembangan front end. Singkatnya, ide mikro frontend adalah memecah aplikasi monolit menjadi bagian-bagian yang lebih kecil, lebih mudah dibuat, dan lebih mudah dipelihara.

Itu memungkinkan Anda untuk:

  • Terapkan secara mandiri
  • Gunakan beberapa kerangka UI (React, Vue.js, dan Angular) di satu tempat
  • Pisahkan sebagian komponen UI dari basis kode besar

Ada juga kelemahan seperti kompleksitas pengaturan awal dan masalah kinerja karena kode duplikat, tetapi spa tunggal dan federasi modul dapat menyelesaikannya.

spa tunggal

single-spa adalah kerangka kerja yang memungkinkan Anda menyiapkan aplikasi mikro front-end dengan mudah.

Dengan mengabstraksi siklus hidup untuk seluruh aplikasi, single-spa memungkinkan Anda menggunakan beberapa kerangka kerja UI pada halaman yang sama.

Ini juga memberikan kemampuan untuk:

  • Terapkan secara mandiri
  • Lakukan pemuatan lambat
  • Memperkenalkan kerangka kerja baru tanpa modifikasi apa pun untuk aplikasi yang sudah ada

Dengan spa tunggal, Anda memiliki dua opsi untuk memilih ekosistem untuk berbagi ketergantungan:

Ide dari peta impor adalah untuk memetakan URL pernyataan impor JavaScript ke perpustakaan. Misalnya, jika Anda mengimpor moment ke kode Anda,

import moment from "moment";

Anda harus menyediakan browser dengan peta berikut:

<script type="importmap">
{
  "imports": {
    "moment": "/node_modules/moment/src/moment.js"
  }
}
</script>

Ini dapat mengontrol URL apa yang diambil melalui impor.

Dengan fitur baru ini dan eksternal webpack, yang dapat mengecualikan beberapa perpustakaan, ini akan menghasilkan modul yang dibundel tanpa duplikat dalam suatu aplikasi.

Tapi kami tidak akan menggunakan ini di aplikasi kami. Sebagai gantinya, kami akan memanfaatkan teknologi baru di Webpack 5.

Federasi Modul di Webpack

Federasi modul diperkenalkan di Webpack 5. Tujuan utamanya adalah untuk berbagi kode dan perpustakaan antar aplikasi.

Dengan federasi modul, kode JavaScript apa pun — seperti logika bisnis atau pustaka, dan kode manajemen status — dapat dibagikan antar aplikasi. Ini dapat membuat beberapa aplikasi mikro frontend bekerja sama seolah-olah Anda mengembangkan aplikasi monolit.

Anda mungkin bertanya-tanya apa perbedaan antara mikro frontend dan federasi modul. Mereka sebenarnya mencakup banyak hal yang sama. Tapi ada perbedaan.

Satu-satunya tujuan mikro front-end adalah untuk berbagi UI antar aplikasi, bukan logika JavaScript. Jadi, kode yang dibundel dapat menyertakan kode duplikat.

Tujuan federasi modul adalah untuk berbagi kode JavaScript antar aplikasi, bukan UI. Jadi, kode yang dibagikan dapat digunakan dalam suatu aplikasi.

Mereka sebenarnya saling melengkapi. Jadi, dengan federasi modul di aplikasi mikro-frontend, Anda dapat menghindari duplikat kode dan menyediakan komponen UI bersama di seluruh aplikasi.

Ikhtisar aplikasi

Saat ini, kita telah membahas ide dasar mikro frontend dan federasi modul.

Selanjutnya, kita akan membahas penerapan aplikasi demo sederhana untuk memahami cara keduanya bekerja sama.

Mari kita lihat ikhtisar tentang apa yang membentuk aplikasi ini:

  • Aplikasi rumah yang menangani semua aplikasi mikro-frontend.
  • Aplikasi navigasi yang menampilkan UI header dan footer yang dibuat oleh React.
  • Aplikasi body yang menampilkan elemen body halaman yang dibuat oleh Vue.js.

Siapkan paket Root.json

Sebelum mengimplementasikan aplikasi mikro-frontends, kami membuat package.json di root. Ketiga aplikasi tersebut disertakan dalam satu repo sebagai monorepo, jadi kami akan menggunakan yarn workspaces untuk berbagi beberapa paket di seluruh aplikasi.

Buat package.json di root, seperti:

Kemudian, instal dependensinya.

yarn

Aplikasi Rumah

Selanjutnya, kami membuat aplikasi rumah yang mengoordinasikan setiap aplikasi mikro-frontend. Beranda menangani tugas yang merender halaman HTML dan JavaScript yang mendaftarkan aplikasi.

Mari kita lihat struktur rumahnya:

├── packages
│   └── home
│       ├── package.json
│       ├── public
│       │   └── index.html
│       ├── src
│       │   └── index.ts
│       ├── tsconfig.json
│       └── webpack.config.js

Lalu, kami membuat file-file ini selangkah demi selangkah.

Pertama, buat package.json:

Dan buat webpack.config.js:

Ini adalah konfigurasi dasar untuk TypeScipt, tetapi Anda dapat menemukan federasi modul yang diimpor di bagian plugin.

Untuk memahami cara kerjanya, kita akan membahas tiga konsep penting.

remote

Bidang remotes mengambil nama aplikasi mikro-frontend gabungan untuk menggunakan kode. Dalam hal ini, aplikasi rumah akan menggunakan aplikasi navigasi dan aplikasi isi sehingga kita perlu menentukan namanya di kolom remotes, seperti:

remotes: {
  navigation: 'navigation',
  body: 'body',
},

Kami akan membahas lebih banyak detail saat mengimplementasikan aplikasi navigasi dan bodi.

mengekspos

Bidang exposes digunakan untuk mengekspor file ke aplikasi lain. Kuncinya harus berupa nama yang diekspor yang digunakan dalam aplikasi lain. Misalnya, jika Anda mengekspor komponen Button dari kode Anda, tulislah seperti ini:

exposes: {
  Button: './src/Button',
},

bersama

Ini shared adalah daftar semua dependensi yang dibagikan untuk mendukung file yang diekspor. Misalnya, jika Anda mengekspor komponen Vue.js, Anda harus mencantumkan vue di bagian bersama, seperti:

shared: ['vue'],

Hal ini akan mencegah aplikasi menyertakan pustaka duplikat dan akan membagikan satu instance ke seluruh aplikasi, meskipun kompiler webpack benar-benar terpisah.

Selanjutnya, kita akan membuat public/index.html:

Dan buat src/index.ts:

File ini akan digunakan untuk mendaftarkan aplikasi mikro-frontend yang digunakan di aplikasi rumah. Untuk saat ini, kami hanya menjalankan fungsi start untuk meningkatkan aplikasi.

Aplikasi Navigasi

Sekarang kita sudah menyiapkan aplikasi rumah, mari kita terapkan aplikasi navigasi.

Berikut struktur aplikasi navigasi:

├── packages
│   ├── home
│   │   ├── package.json
│   │   ├── public
│   │   │   └── index.html
│   │   ├── src
│   │   │   └── index.ts
│   │   ├── tsconfig.json
│   │   └── webpack.config.js
│   └── navigation
│       ├── package.json
│       ├── src
│       │   ├── Footer.tsx
│       │   ├── Header.tsx
│       │   └── index.ts
│       ├── tsconfig.json
│       ├── webpack.config.js

Kami akan mengekspor komponen Footer dan Header ke aplikasi rumah.

Untuk melakukan itu, pertama-tama kita membuat file-file itu. Buat navigation/package.json:

Aplikasi navigasi akan dibuat oleh React, jadi instal dependensinya dan buat navigation/webpack.config.js:

Lihat publicPath dan ModuleFederationPlugin.

publicPath adalah nama dasar URL jarak jauh yang akan digunakan di aplikasi rumah. Dalam hal ini, aplikasi navigasi akan disajikan di http://localshot:3001.

Bidang exposes mengambil dua komponen, Header dan Footer. Ini akan mengekspornya ke aplikasi rumah.

Seperti yang dinyatakan sebelumnya, kita harus membuat daftar perpustakaan bersama di bagian shared. Dalam hal ini, kita perlu menulis react, react-dom, dan single-spa-react.

Selanjutnya, buat src/Header.tsx dan src/Footer.tsx:

Daftarkan Aplikasi Navigasi

Sekarang kami siap untuk mulai mengekspor aplikasi navigasi.

Selanjutnya, kami mendaftarkannya di aplikasi rumah. Untuk mendaftarkan aplikasi mikro-frontends, diperlukan langkah-langkah berikut:

  • Sertakan tag skrip
  • Daftar di remote
  • Tambahkan registrasi
  • Sertakan wadah div

Mari kita lakukan langkah-langkah ini.

Sertakan tag skrip

Pertama, untuk menggunakan kode dari aplikasi navigasi, kita harus memasukkannya ke dalam file HTML.

Buka home/public/index.html dan sertakan tag skrip.

<!DOCTYPE html>
<html lang="en">
<head>
    <script src="http://localhost:3001/remoteEntry.js"></script>
    ...
</head>

Seperti yang dinyatakan sebelumnya, publicPath aplikasi navigasi adalah http://localhost:3001 dan nama filenya adalah remoteEntry.js.

Daftar di remote

Selanjutnya, buka home/webpack.config.js dan tentukan bagian remote:

remotes: {
  home-nav: 'navigation',
},

navigation adalah nama konfigurasi di navigation/webpack.config.js:

plugins: [
  new ModuleFederationPlugin({
    name: 'navigation',
    library: { type: 'var', name: 'navigation' },
    filename: 'remoteEntry.js',
    remotes: {},
    exposes: {
      Header: './src/Header',
      Footer: './src/Footer',
    },
    shared: ['react', 'react-dom', 'single-spa-react'],
  }),
],

home-nav adalah nama yang digunakan di aplikasi rumah.

Anda dapat mengubah nama impor dengan mengubah kunci sesuai keinginan Anda.

Tambahkan registrasi

Selanjutnya, kita daftarkan aplikasi navigasi di home/src/index.ts:

registerApplication membutuhkan tiga hal:

  • Nama aplikasi
  • Fungsi untuk memuat kode aplikasi
  • Fungsi yang menentukan kapan aplikasi aktif atau tidak aktif

Fungsi import menentukan nama kunci remotes seperti yang dinyatakan di atas.

() => import('home-nav/Header'),

Sertakan div kontainer

Terakhir, kita menulis container div yang digunakan untuk menyertakan komponen Header dan Footer.

Buka home/public/index.html dan tambahkan:

Secara default, tanpa opsi, single-spa akan mencari single-spa-application:{app name} dan merender HTML di bawah.

Dalam hal ini, kita telah mendaftarkan Header dan Footer sebagai header dan footer sehingga akan ditemukan id single-spa-application:header dan single-spa-application:footer.

Mari kita coba ini.

Sebelum itu, pastikan untuk menginstal dependensi:

yarn

Dan mulai server di root:

yarn start

Jadi, navigasikan ke http://localhost:3000 dan Anda akan menemukan dua komponen React berhasil dirender.

Sepertinya ini bekerja dengan baik.

Aplikasi Tubuh

Selanjutnya, kita akan membuat aplikasi body. Body app akan dibuat oleh Vue.js namun proses implementasinya hampir sama dengan yang ada pada aplikasi navigasi.

Ayo lakukan dengan cepat.

Struktur aplikasi body adalah:

├── packages
│   ├── body
│   │   ├── package.json
│   │   ├── src
│   │   │   ├── App.vue
│   │   │   ├── app.js
│   │   │   └── index.js
│   │   ├── tsconfig.json
│   │   └── webpack.config.js

Buat body/package.json:

Dan buat body/webpack.config.js:

Buat body/src/App.vue dan body/src/app.js:

Daftarkan Aplikasi Tubuh

Selanjutnya, kita akan mendaftarkan isi di aplikasi beranda seperti yang kita lakukan sebelumnya untuk navigasi.

Buka home/public/index.html dan tambahkan tag skrip:

<head>
    <script src="http://localhost:3001/remoteEntry.js"></script>
    <script src="http://localhost:3002/remoteEntry.js"></script>
    ...
</head>

Lalu pergi ke home/webpack.config.js dan tambahkan home-body:

remotes: {
  'home-nav': 'navigation',
  'home-body': 'body',
},

Lalu, buka home/src/index.ts untuk mendaftarkannya:

Terakhir, tambahkan wadah div untuk itu di home/public/index.html:

Mari kita uji ini.

Jalankan dependensi instalasi:

yarn

Dan mulai server di root:

yarn start

Navigasi ke http://localhost:3000:

Hebat — Anda dapat melihat bahwa komponen Vue berhasil dirender.

Kesimpulan

Dalam artikel ini, kami telah membahas cara mengimplementasikan aplikasi mikro-frontend menggunakan SPA Tunggal dan Federasi Modul di Webpack.

Micro-frontends menguntungkan pengembangan tim, terutama bagi tim yang lebih besar, dalam hal fleksibilitas, ekstensibilitas, dan pemeliharaan karena mikro-frontend memberi Anda penerapan independen, penggunaan kerangka kerja campuran, dan pemisahan masalah.

Meskipun ada kelemahannya, seperti kerumitan konfigurasi dan biaya pembelajaran, menurut saya kelebihan yang disebutkan di atas lebih besar daripada kekurangannya.

Saya harap artikel ini membuat Anda tertarik dengan mikro frontend!