Alterando uma lib Node de forma rápida
Caio Fuzatto
Posted on October 19, 2023
Você já se deparou com um bug chato na lib que você instalou para resolver os seus problemas? Aquele bug que depois de procurar bastante você caiu numa issue do github onde descobriu que era um defeito na lib? Ou seu PO te pediu algo que a lib não faz e você não quer esperar o pull request ser aceito pra poder continuar o desenvolvimento?
A ideia hoje é aprender como fazer um patch de uma alteração sua em uma lib, e também aprender a buildar sua lib corretamente com suas alterações, bora la?
Lib patch-package
Durante muito tempo o patch-package foi a solução mais utilizada para resolver esse problema. Ele é um pacote que permite que você faça alterações em libs que você instalou via npm, e que essas alterações sejam aplicadas toda vez que alguém rodar o comando npm install
no seu projeto.
Para começar a usar o patch-package, você precisa instalar ele no seu projeto:
yarn add patch-package postinstall-postinstall
E adicionar um script no seu package.json
:
"scripts": {
"postinstall": "patch-package"
}
O
postinstall-postinstall
é um pacote que vai executar o comandopatch-package
toda vez que alguém rodar o comandonpm install
no seu projeto.
Agora você pode fazer as alterações que você quiser na lib e depois é só rodar o comando yarn patch-package <nome da lib>
que o patch-package vai criar um arquivo .patch
com as alterações que você fez.
Além disso, uma das vantagens que eu gosto muito do patch-package é o a flag --create-issue
que abre uma página com uma issue em draft no github da lib que você está alterando. Assim você pode abrir uma issue com a sua alteração e quem sabe ela não é aceita e você não precisa mais fazer o patch?
Se quiser saber mais sobre contribuições em projetos open-source da uma olhada la no último artigo sobre A cultura open-source.
Yarn V2
O Yarn V2 também trás uma solução nativa para resolver esse problema, o patch. Com ele você consegue fazer a mesma coisa que o patch-package, mas de forma nativa. Bora vê como funciona!
Provavelmente você ainda não deve estar utilizando o Yarn V2 em nenhum dos seus projetos, então comece configurando a nova versão:
yarn set version berry && yarn install
Isso vai instalar a V2 e vai adicionar o arquivo .yarnrc.yml
na raiz do seu projeto, além da pasta .yarn
que vai conter os arquivos de cache do Yarn.
Para começar digite o comando patch e o nome da lib que você quer alterar, no meu caso será a @adminjs/passwords
:
yarn patch @adminjs/passwords
Você verá um output parecido com esse:
Olha que legal, o yarn criou uma pasta que contém todos os arquivos da lib, e você pode fazer as alterações necessárias para resolver o seu problema. Para o tutorial eu vou só adicionar um console.log("teste")
só para gente ver o resultado.
Terminou as alterações? Hora de "salvar" as alterações e aplicar o patch:
yarn patch-commit -s <caminho da pasta gerada pelo yarn>
Com esse comando o yarn vai criar um arquivo .yarn/patches/<nome da lib>.patch
com as alterações que você fez. Olha como ficou o meu:
diff --git a/src/bundle-component.ts b/src/bundle-component.ts
index 28a36f32426f984f7aac103a3a45775671ab7891..d5d727e2b4059b2e4d2aa24be650a8bef374b306 100644
--- a/src/bundle-component.ts
+++ b/src/bundle-component.ts
@@ -12,6 +12,7 @@ const bundleComponent = (
componentName: string,
) => {
const componentPath = path.join(__dirname, `./components/${componentName}`)
+ console.log("teste")
return loader.add(componentName, componentPath)
}
Agora é só commitar esse arquivo e pronto, toda vez que alguem rodar yarn install no seu projeto as alterações serão aplicadas na LIB.
pnpm
Se você navegou na net pelos últimos dias, você deve conhecer o pnpm, um gerenciador de pacotes que promete ser mais rápido que o Yarn e o NPM. Ele também tem uma solução nativa para resolver esse problema, o patch.
Assim como no Yarn aqui também temos o comando pnpm patch <nome da lib>
que vai criar uma pasta com os arquivos da lib para você alterar.
Também podemos aproveitar a própria node_modules
para fazer nossas mudanças, sem precisar criar uma pasta nova e além disso conseguindo testar a alteração diretamente no seu projeto. É só especificar a pasta no comando o patch-commit
, como no exemplo abaixo:
pnpm patch-commit node_modules/@adminjs/passwords
Buildando a Lib
A gente adicionou o console.log("teste")
na pasta src
do projeto mas o log não está sendo exibido quando você roda o projeto. Isso acontece porque o arquivo src
não é o que está sendo executado, e sim o dist
ou build
. Então vamos buildar a lib para que as alterações sejam aplicadas.
No seu terminal caminhe até a pasta da lib na node modules. No meu caso o comando ficou assim:
cd node_modules/@adminjs/passwords
Agora precisamos instalar as dependências da lib na pasta dela, para isso vamos usar o comando pnpm install
e depois disso basta rodar o comando pnpm build
para buildar a lib.
pnpm install && pnpm build
Agora quando você rodar o projeto você vai ver a alteração acontecendo.
Agora você pode usar os comandos de patch
apontando para a pasta da lib na node_modules e a alteração ficará salva. Veja o novo arquivo de patch com o console.log
em dois arquivos diferentes:
diff --git a/build/bundle-component.js b/build/bundle-component.js
index 9ac9a32d7a3f412fd0e8a90441fd0c35ec694e0e..f7e4ef64101ea60e17eaad74b4f42f789b695747 100644
--- a/build/bundle-component.js
+++ b/build/bundle-component.js
@@ -5,6 +5,7 @@ const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
const bundleComponent = (loader, componentName) => {
const componentPath = path.join(__dirname, `./components/${componentName}`);
+ console.log("teste");
return loader.add(componentName, componentPath);
};
export default bundleComponent;
diff --git a/src/bundle-component.ts b/src/bundle-component.ts
index 28a36f32426f984f7aac103a3a45775671ab7891..d5d727e2b4059b2e4d2aa24be650a8bef374b306 100644
--- a/src/bundle-component.ts
+++ b/src/bundle-component.ts
@@ -12,6 +12,7 @@ const bundleComponent = (
componentName: string,
) => {
const componentPath = path.join(__dirname, `./components/${componentName}`)
+ console.log("teste")
return loader.add(componentName, componentPath)
}
Lembre-se de dar commit do arquivo de patch gerado, só assim você conseguirá reutilizar em futuras instalações.
Conclusão
Hoje vimos como fazer um patch de uma lib e como buildar ela para que as alterações sejam aplicadas. Também vimos que o Yarn V2 e o pnpm tem soluções nativas para esse problema, e que o patch-package ainda é uma boa solução para quem não quer migrar para o Yarn V2 ou pnpm.
E você ja passou por isso? Compartilhe outras ideias e conhecimentos ai sobre codar libs!
Posted on October 19, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.