Sử Dụng Patch Package Để Tùy Chỉnh NPM Package Theo Ý Muốn
🤗

Sử Dụng Patch Package Để Tùy Chỉnh NPM Package Theo Ý Muốn

Tags
Notion
Node.js
OSS
Software Development
Published
August 14, 2024
Author
AI summary

Giới thiệu

Đôi khi, bạn cảm thấy rất vui khi tìm thấy một npm package phù hợp với nhu cầu của mình. Rồi bạn chợt nhận ra trong package có một đoạn code hoặc một function lại không thật sự đúng như nhu cầu.
Về cơ bản, có một số cách để giải quyết vấn đề này.
  1. Tìm repository của package. Sau đó cập nhật code theo ý muốn và tạo một Pull Request cho repository.
  1. Tìm repository của package. Sau đó fork thành một repository và public lại lên npm với một package name mới.
  1. Clone code trong package và sửa nó theo ý của mình rồi coi nó như một đoạn code trong dự án của mình thay vì là một npm package.
Với cả 3 cách trên, chúng ta đều sẽ gặp các vấn đề khác nhau:
  1. Tốn thời gian.
  1. Chưa chắc đã được merge code vào repository.
  1. Code dễ bị lỗi thời khi có các phiên bản mới được phát hành.
Kết hợp giữa các vấn đề trên, mình đã tìm ra một cách đơn giản hơn và tránh việc code bị outdate, đó là sử dụng patch package.
notion image
Hiểu đơn giản thì chúng ta vẫn install package như bình thường. Sau đó có thể apply các doạn code thay đổi để override lại, cơ chế sẽ tương tự như một commit của Git.

Tạo patch

Chúng ta có thể tạo ra patch files tùy thuộc vào package manager bạn sử dụng:
  1. Sử dụng pnpm: Built-in trong pnpm CLI
  1. Sử dụng yarn: Cần phải cài thêm package (patch-package)
Mình sẽ lựa chọn pnpm trong bài viết này vì nó tiện lợi, không cần cài thêm package và mình cũng đang sử dụng nó cho các dự án của mình.
Ví dụ:
  1. Yêu cầu:
    1. Vấn đề: Mình có một project sử dụng Vue và sử dụng SSR. Data trong component đôi khi bị sai nên đến quá trình render component có exception (undefined…). Từ đó, mình cần render một trang lỗi thay vì chỉ không render component đó.
    2. Solution: Project của mình được deploy trên 3 env khác nhau: dev, stag, prod. Với các env dev, stag mình vẫn giữ logic render của Vue. Tuy nhiên trên prod thì mình sẽ thêm catch để có thể log và không bắn một exception ra làm lỗi cả quá trình render các components của page.
  1. Thực hiện:
    1. Mở terminal và đi tới path của project
    2. Sử dụng command với pnpm để thay đổi @vue/server-renderer
      1. pnpm patch @vue/server-renderer
    3. Sau khi chạy command, có thể sẽ có một vài tùy chọn. Bạn chỉ cần chọn và xác nhận.
    4. Commit các thay đổi cho patch
      1. pnpm patch-commit '~/js/blog/.pnpm_patches/@vue/server-renderer@3.4.23'
  1. Chi tiết:
Với ví dụ ở trên, mình sẽ sử dụng IDE và tìm đến folder chứa code của @vue/server-renderer. Ở package này thì Vue có chia hai envs là prod và default. Cùng với đấy là hai types module hoặc commonjs.
Ở project của mình thì mình chạy với env là production và sử dụng package type là module. Vì thế mình sẽ mở file server-renderer.esm-bundler.js và làm các bước sau:
a. Tìm đến đoạn code xử lý render components.
notion image
Phân tích một chút, bạn sẽ thấy try block nhưng không có catch block đúng không? Chính vì không có catch nên khi xảy ra lỗi, nó sẽ throw exception và dừng toàn bộ quá trình render.
b. Sửa lại đoạn code theo yêu cầu
Để sửa đoạn code cho nó hoạt động như yêu cầu, đơn giản chúng ta chỉ cần thêm catch vào cho nó phải không?
Nhưng chúng ta còn một yêu cầu khác nữa là không phải env nào chúng ta cũng làm như vậy. Mục đích là với các env để testing như dev, stag thì việc throw ra là phù hợp. Lý do là chúng ta vẫn cần phải biết component nào đấy đang xử lý chưa tốt, có lỗi xảy ra khi render và chúng ta cần phải sửa lại nó.
Vì vậy, mình sẽ sửa lại code như sau, dựa trên biến môi trường SKIP_RENDER_ERROR.
notion image

Sử dụng patch

Khi bạn đã tạo patch, trong project sẽ có thêm folder patches. Đây là nơi chứa các thay đổi theo từng package mà bạn đã tạo.
Nếu dùng pnpm, bạn gần như được chăm sóc tận răng! Cài đặt xong là patch sẽ tự động được áp dụng.
Nếu bạn sử dụng yarn, bạn cần thêm một command vào scripts của package.json. Sau khi install package xong bạn cần chạy command để apply patches.
Ví dụ:
yarn patch-package

Lời kết

Mình rất thích việc contribute hoặc tạo ra các package open source. Tuy nhiên, để được approve và release version mới của package không phải lúc nào cũng dễ dàng. Patch package không chỉ là một giải pháp tạm thời, mà còn giúp bạn tiết kiệm thời gian và công sức để tập trung vào những điều thực sự quan trọng.