Copiar arxius no és instal·lar

Descobreix per què copiar arxius no és instal·lar i com evitar l'error 'funciona a la meva màquina' amb autoaprovisionament de dependències natives.

domingo, 19 de julio de 2026 • 5 min de lectura • Equip Q2BSTUDIO

Dependències natives: com evitar fallades en distribuir plugins

En el desenvolupament de programari modern, la bretxa entre un entorn de desenvolupament local i el de producció sol amagar suposicions perilloses. Una de les més comunes és assumir que copiar arxius equival a instal·lar un programa. No obstant això, copiar fitxers és només transferir bits; instal·lar implica resoldre dependències, compilar mòduls nadius i configurar l'entorn d'execució. Quan un marketplace desplega un plugin simplement copiant el seu directori, se salta tot el procés d'instal·lació. El resultat és un sistema que funciona a la màquina del desenvolupador—on les dependències ja estaven—però fracassa a la màquina de l'usuari final. Aquest problema, conegut col·loquialment com a 'funciona a la meva màquina', té arrels profundes en la gestió de dependències, especialment quan s'utilitzen mòduls nadius que requereixen compilació.

Imaginem un plugin que ofereix dues modalitats: una que es connecta a una API remota usant només JavaScript pur, sense dependències natives, i una altra que necessita una base de dades SQLite local, la qual requereix mòduls compilats C++ com better-sqlite3 i fs-ext. A l'entorn de desenvolupament, el comandament npm install ja es va executar, deixant node_modules llest. Però en copiar el plugin a través del marketplace, les dependències natives no existeixen. Quan el servidor intenta carregar el mòdul amb require, falla amb MODULE_NOT_FOUND. El plugin mor en l'arrencada, sense haver fet res. Aquest escenari no és rar: afecta qualsevol aplicació que combini codi pur amb dependències compperades i es distribueixi mitjançant còpia d' arxius.

La solució no és demanar-li a l'usuari que executi ningú. En un flux d'instal·lació impulsat per marketplace, aquesta acció trenca l'experiència i redueix l'adopció. En el seu lloc, el mateix plugin ha d' autoprovisionar les seves dependències en el moment de la primera arrencada, i només quan siguin necessàries. Per aconseguir-ho, s'utilitza un petit llançador (bootstrap) que s'executa abans que el servidor principal. Aquest llançador està escrit exclusivament amb mòduls nadius de Node.js (fs, path, child_process), sense dependre de res en node_modules. La seva funció és decidir si es necessiten dependències natives o no. Si l'aplicació s'executa en mode remot (sense SQLite), el llançador arrenca directament el servidor agrupat, sense cost addicional. Si es necessita el mode local, verifica si les dependències ja hi són presents. Si no és així, executa npm ci (no npm install) per instal·lar exactament les versions bloquejades al package-lock.json, garantint reproducibilitat. Després de la instal·lació, torna a comprovar i, si falla, avorta amb un missatge clar.

Un dels desafiaments més subtils és la concurrència. Quan un usuari obre diverses instàncies del plugin (per exemple, diverses finestres de Claude o múltiples agents), els processos poden arrencar simultàniament i intentar instal·lar en el mateix directori. Dos npm cis poden corrompre l'arbre de dependències. Per evitar-ho s'empra un bloqueig atòmic basat en mkdir: s'intenta crear un directori temporal (.native-install.lock). Si l'operació falla amb EEXIST, significa que un altre procés ja té el bloqueig. L'algoritme llavors espera, comprova si les dependències ja estan llestes (un altre procés va finalitzar), si el bloqueig està obsolet (més de 5 minuts, indicant un procés que va fallar), o si s'assoleix un temps màxim d'espera de 2 minuts. Aquest disseny evita condicions de carrera i garanteix que només un procés realitzi la instal·lació, mentre els altres esperen o continuen si ja està feta.

La lliçó general és profunda: qualsevol sistema que distribueixi programari mitjançant còpia d'arxius (marketplaces, instal·ladors sense gestor de paquets, desplegaments serverless) ha de considerar l'aprovisionament de dependències com a part del runtime, no del build. Les eines d'integració contínua (CI) sovint instal·len dependències abans d'executar les proves, ocultant el problema. Per detectar-ho, cal un esmòbid test que simuli una instal·lació neta: copiar els arxius a un directori buit, sense node_modules, i executar el llançador exactament com ho faria un usuari. Si la prova passa, el codi és robust. Si falla, es detecta abans d'alliberar la versió.

Aquest enfocament té aplicacions directes en el desenvolupament d' aplicacions a mida i programari a mida. En Q2BSTUDIO, entenem que cada projecte té necessitats úniques d' infraestructura i dependències. Per exemple, en construir solucions d'intel·ligència artificial per a empreses, sovint combinem models de llenguatge grans (LLM) amb bases de dades vectorials que requereixen mòduls nadius. Si despleguem aquests sistemes en entorns cloud (AWS, Azure) mitjançant contenidors o funcions serverless, l'aprovisionament sota demanda és crucial per evitar temps d'arrencada excessius i fallades silencioses. Els nostres equips apliquen patrons similars d'autoinstal·lació i bloqueig per garantir que tant els agents IA com els pipelins de dades funcionin de manera fiable des del primer moment.

La ciberseguretat també es beneficia d'aquest disseny. Un plugin que assumeix dependències preinstal·lades pot ser vulnerable a atacs de suplantació de ruta o dependències malicioses si l'usuari no controla el procés d'instal·lació. En centralitzar l' aprovisionament en un llançador minimalista, es redueix la superfície d' atac. A més, l' ús de npm ci amb package-lock.json verificat evita la injecció de versions no autoritzades. En els nostres desenvolupaments d'IA per a empreses, combinem aquestes pràctiques amb anàlisi de vulnerabilitats a les dependències, oferint solucions segures i auditables.

Un altre aspecte rellevant és la integració amb serveis d'intel·ligència de negoci com Power BI. Quan construïm connectors personalitzats o extensions per a Power BI, sovint necessitem instal·lar controladors nadius o biblioteques de compressió. Aplicant la mateixa filosofia—verificar dependències només quan es fan servir i provisionar-les sota demanda—evitem que l'usuari final hagi d'executar scripts addicionals. Això s'alinea amb la nostra oferta de serveis intel·ligència de negoci, on prioritzem l'experiència d'usuari sense sacrificar la reproducibilitat.

Des d' una perspectiva empresarial, aquest patró permet escalar equips sense friccions. Quan un nou desenvolupador s'uneix a un projecte, no necessita executar comandaments d'instal·lació manual; el propi sistema es configura en arrencar. Això és especialment valuós en entorns que utilitzen serveis cloud AWS i Azure, on les màquines virtuals o contenidors es creen i destrueixen constantment. Un llançador que autoprovisiona dependències natives garanteix que cada instància sigui idèntica, eliminant el clàssic 'a la meva màquina funciona'.

En resum, copiar arxius no és instal·lar. Perquè un plugin o aplicació funcioni de manera predictible en qualsevol entorn—local, cloud o marketplace—cal que el propi runtime gestioni les seves dependències de forma idempotent, concurrent i amb missatges d'error clars. En Q2BSTUDIO apliquem aquests principis en cada projecte d'aplicacions a mida, assegurant que les nostres solucions d'intel·ligència artificial, ciberseguretat i serveis cloud ofereixin la màxima fiabilitat des de la primera arrencada. Perquè en el món real, no n'hi ha prou que el codi estigui ben escrit; també ha de ser capaç de posar-se en marxa per si mateix.

UNA PAUSA?

Juga una estona abans de marxar

ELS NOSTRES SERVEIS

Com et podem ajudar

Tens un projecte en ment?

Explica'ns la teva visió i la convertim en una solució de programari. Sigui quin sigui l'abast, fem realitat la teva idea.