0

Chia sẻ component giữa các website: Từ đơn giản đến hiệu quả

Việc chuyển giao component giữa các website là một nhu cầu phổ biến trong quá trình phát triển ứng dụng web. Bài viết này sẽ hướng dẫn bạn một số phương pháp chia sẻ component, từ cơ bản đến thực tiễn, giúp tối ưu hóa quá trình phát triển.

Bạn có thể đọc thêm: Component là gì? Tìm hiểu về những chức năng chính của Component

Khi tạo ứng dụng web, việc cần chuyển component giữa các website là điều không hiếm gặp. Thông thường, đó là một số loại nút chung, các khối như footer, header, v.v.

Component nút cơ bản

Ví dụ, chúng ta có thể lấy component nút, thứ mà chúng ta sẽ chuyển giữa các component. Nó sẽ trông như thế này:

<button class="button">Click Me</button>
<style>
  .button {
    background-color: #4caf50;
    color: white;
    border: none;
    padding: 12px 24px;
    text-align: center;
    text-decoration: none;
    font-size: 16px;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.3s, transform 0.2s;
  }

  .button:hover {
    background-color: #45a049;
  }

  .button:active {
    transform: scale(0.95);
  }
</style>

Kết quả trên website sẽ như sau: image.png

Giờ, hãy lấy hai website mà bạn cần làm cho component trở nên chung. Giả sử đó là example1 và example2. Chúng có thể được lưu trữ trên các website hosting khác nhau. Một website được triển khai từ GitHub và website còn lại từ một hosting cục bộ nào đó.

Bây giờ, câu hỏi chính đặt ra - làm thế nào để chia sẻ?

Các phương pháp chia sẻ component

Tôi sẽ mô tả một số phương pháp thường được sử dụng cho việc này. Từ phương pháp thông thường nhất đến phương pháp thực tiễn nhất. image.png

Cả hai cách tiếp cận này sẽ trông giống như thế này.

1. Xuất ra file và kết nối bằng script

Phương pháp này giả định rằng sẽ có một hàm trả về mã HTML. Và hàm này có thể được kết nối thông qua một file từ xa. Không quan trọng file này sẽ được đặt ở đâu. Bạn chỉ cần kết nối nó từ đó.

createButton.js

// buttonModule.js
(function (global) {
  // Define the createButton function
  function createButton() {
    // Create a <style> element and add styles
    const style = document.createElement('style');
    style.textContent = `
      .button {
        background-color: #4caf50;
        color: white;
        border: none;
        padding: 12px 24px;
        text-align: center;
        text-decoration: none;
        font-size: 16px;
        border-radius: 5px;
        cursor: pointer;
        transition: background-color 0.3s, transform 0.2s;
      }
      .button:hover {
        background-color: #45a049;
      }
      .button:active {
        transform: scale(0.95);
      }
    `;

    // Create the button element
    const button = document.createElement('button');
    button.className = 'button';
    button.textContent = 'Click Me';

    // Return the elements (style and button)
    return { style, button };
  }

  // Expose the function to the global scope
  global.buttonModule = {
    createButton,
  };
})(window);

example1/root/index.html, example2/root/index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Button Module</title>
  <script src="https://.../buttonModule.js"></script>
</head>
<body>
  <div id="wrapper"></div>
  <script>
    // Use the buttonModule
    const { style, button } = buttonModule.createButton();
    const wrapper = document.getElementById("wrapper");
    wrapper.append(style); // Attach styles to the document
    wrapper.append(button); // Add the button to the page
  </script>
</body>
</html>

Ở đây, chúng ta kết nối module thông qua một website không được kết nối với hai website của chúng ta. Đó có thể là cùng một GitHub.

Ưu và nhược điểm của phương pháp sử dụng script

Ưu điểm:

  • Dễ dàng thực hiện với thẻ <script> tiêu chuẩn trong HTML mà không cần thiết lập bổ sung.
  • Không yêu cầu các công cụ hoặc cấu hình hiện đại như Webpack hoặc Vite.
  • Phù hợp với các ứng dụng nhỏ, một trang hoặc các thử nghiệm nhanh.
  • Thiết lập tối thiểu, cho phép phát triển nhanh hơn.
  • Có thể được tích hợp liền mạch vào các dự án hiện có vốn đã dựa vào các biến toàn cục.

Nhược điểm:

  • Nếu có nhiều component, sẽ có hàng nghìn script, điều này làm cho phương pháp này chỉ phù hợp cho một lần sử dụng.
  • Thêm các biến hoặc đối tượng vào phạm vi toàn cục, làm tăng nguy cơ xung đột tên.
  • Khó tránh khỏi xung đột khi sử dụng nhiều script.
  • Khiến dự án khó mở rộng hoặc tái cấu trúc hơn.
  • Các script phụ thuộc vào thứ tự tải chính xác, điều này phải được quản lý thủ công.
  • Khó bảo trì hơn và không phù hợp với các phương pháp hay nhất hiện nay.

2. Sử dụng thư viện bên thứ ba và chuyển component sang API

Đối với phương pháp này, chúng ta sẽ sử dụng một module như HMPL. Nó sẽ cho phép bạn kết nối các component từ máy chủ bằng cách sử dụng các template đơn giản dựa trên các đối tượng. Để bắt đầu, hãy đưa component lên máy chủ. Tạo một file HTML riêng biệt và cung cấp nó thông qua yêu cầu API. File .html sẽ trông như thế nào:

button.html

<button class="button">Click Me</button>
<style>
  .button {
    background-color: #4caf50;
    color: white;
    border: none;
    padding: 12px 24px;
    text-align: center;
    text-decoration: none;
    font-size: 16px;
    border-radius: 5px;
    cursor: pointer;
    transition: background-color 0.3s, transform 0.2s;
  }

  .button:hover {
    background-color: #45a049;
  }

  .button:active {
    transform: scale(0.95);
  }
</style>

Sau đó, chúng ta sẽ cần phải chuyển tệp này đến máy chủ bằng cách nào đó. Hãy để backend trên Node.js. Chúng ta sẽ sử dụng express.js làm một trong những framework phổ biến nhất để tạo API. Đầu tiên, chúng ta sẽ thiết lập tuyến đường mà chúng ta sẽ nhận được thành phần của mình:

buttonController.js

const express = require("express");
const expressRouter = express.Router();
const path = require("path");

const buttonController = (req, res) => {
  res.sendFile(path.join(__dirname, "../button.html"));
};

expressRouter.use("/getButton", buttonController);

app.js

const express = require("express");
const path = require("path");
const bodyParser = require("body-parser");
const cors = require("cors");
const PORT = 8000;
const app = express();
const routes = require("./routes/buttonController");

app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors({ origin: true, credentials: true }));

app.set(express.static(path.join(__dirname, "src")));

app.use("/api", routes);

app.listen(PORT);

Sau đó, chúng ta sẽ có một tuyến đường mà giờ đây chúng ta có thể dễ dàng lấy thành phần. Trên trang web, chúng tôi kết nối HMPL. Có thể kết nối theo nhiều cách, chúng ta hãy xem xét những cách chính:

Via script

<script src="https://unpkg.com/json5/dist/index.js"></script>
<script src="https://unpkg.com/hmpl-js/dist/hmpl.min.js"></script>

Via import

import hmpl from "hmpl-js";

Chúng tôi sử dụng phương pháp 1 vì index.html là mặc định trên trang web của chúng tôi.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Button Module</title>
  </head>
  <body>
    <script src="https://unpkg.com/json5/dist/index.js"></script>
    <script src="https://unpkg.com/hmpl-js/dist/hmpl.min.js"></script>
    <script>
      const templateFn = hmpl.compile(
        `<div id="wrapper">{{ src: "https://.../api/getButton" }}</div>`
      );
      const btnWrapper = templateFn().response;
      document.body.append(btnWrapper);
    </script>
  </body>
</html>

Ở đây chúng ta làm gần giống như phương pháp đầu tiên, nhưng mẹo là bây giờ bạn có thể tái sử dụng thành phần một cách an toàn. Giả sử bạn có thể làm như thế này:

const btnWrapper1 = templateFn().response;
const btnWrapper2 = templateFn().response;

Ngoài ra, còn có rất nhiều chức năng bổ sung đến từ mô-đun - chỉ báo, xử lý lỗi yêu cầu, v.v. Vì mô-đun dựa trên chức năng tìm nạp nên bạn có thể tùy chỉnh yêu cầu một cách hiệu quả và làm được nhiều việc hơn.

Ưu điểm:

  • Tái sử dụng các thành phần
  • Phù hợp cho cả ứng dụng nhỏ và lớn với hàng ngàn thành phần
  • Một lượng lớn chức năng nhắm cụ thể vào phương pháp tiếp cận hướng máy chủ này đối với các thành phần được hiển thị trên máy khách
  • Tính linh hoạt trong sử dụng

Nhược điểm:

  • Kết nối hai tập tin script
  • Tạo một API bổ sung

Cách tiếp cận này có vẻ giống với cách tiếp cận SSR, nhưng trên máy khách không có yếu tố chính - khả năng hiển thị cho robot, nhưng mặt khác - thì đây là một phương pháp tuyệt vời có thể giúp giải quyết vấn đề dễ dàng hơn.

Phần kết luận

Tùy thuộc vào tình huống, bạn có thể sử dụng cách tiếp cận đầu tiên hoặc cách thứ hai. Trong cách đầu tiên, bạn có toàn quyền kiểm soát quy trình, nhưng vẫn không phù hợp khi bạn cần làm việc với nhiều thành phần, vì bạn sẽ phải liên tục nhập tệp, điều này không tốt.

Cảm ơn các bạn đã theo dõi bài viết!


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí