Spis treści
1. Problem: "działa na moim Macu"
CRXJS to open-source'owy plugin Vite z ponad 3,9 tysiącami gwiazdek na GitHub, który sprawia, że budowanie rozszerzeń do przeglądarek opartych o Chrome jest tak proste jak tworzenie nowoczesnej aplikacji webowej. Obsługuje HMR, parsowanie manifestu, content scripty i cały pipeline budowania.
Ale jak wiele projektów open-source powstałych na macOS i Linux, miał martwy punkt: Windows. CI działało tylko na Ubuntu. Testy nigdy nie były walidowane na Windows. Obsługa ścieżek zakładała forward slashe. Kopiowanie plików używało zachowań specyficznych dla Unixa. Testy snapshotowe przechwytywały output zależny od platformy.
Dla znaczącej części deweloperów pracujących na Windows — i dla zespołów enterprise, gdzie Windows jest platformą wymaganą — oznaczało to kryptyczne błędy budowania, zepsuty HMR i brakujące pliki publiczne bez jasnej ścieżki do naprawy.
2. CRXJS buduje i testuje na Windows
Rozwijamy rozszerzenia Chrome na Windows od 2021 roku używając CRXJS. Wiedzieliśmy, gdzie są bugi, bo trafialiśmy na nie codziennie. Gdy zostaliśmy kontrybutorami projektu, wieloplatformowość była pierwszą rzeczą, którą się zajęliśmy.
Podejście było proste: dodaj Windows do matrycy CI, uruchom cały zestaw testów i napraw wszystko, co się wysypie. Rzeczywistość była bardziej złożona — flagowy PR ( #1008 ) dotknął 45 plików z 6 110 dodaniami i 3 926 usunięciami.
3. Co się faktycznie psuło (i dlaczego)
Windows to nie "Linux z innym interfejsem." System plików, separatory ścieżek, zakończenia linii i zachowanie blokowania plików są fundamentalnie inne. Oto co znaleźliśmy i naprawiliśmy:
Pliki publiczne nie były kopiowane
Statyczne zasoby jak .ico, .svgi .js w katalogu public nie były kopiowane do outputu buildu na Windows. Logika kopiowania plików używała wzorców ścieżek, które działały na Unix, ale cicho failowały na Windows. Zidentyfikowaliśmy to po raz pierwszy w 2024 roku i naprawiliśmy w ramach pracy nad Windows CI.
HMR nie wyzwalał się na Windows
HMR (Hot Module Replacement) w Vite polega na zdarzeniach systemu plików do wykrywania zmian. Na Windows sam fs.copy() nie zawsze aktualizuje timestamp modyfikacji pliku w sposób, jakiego oczekuje HMR. Musieliśmy zmodyfikować kod, aby explicite dotknąć plik (zaktualizować datę modyfikacji) po kopiowaniu, zapewniając niezawodne wykrywanie zmian przez HMR.
Różnice w separatorach ścieżek
Windows używa backslashy (\), a Unix forward slashy (/). Każde porównanie ścieżek, rozwiązywanie plików czy wpis w manifeście, który zakodował na stałe forward slashe, psuł się na Windows. Znormalizowaliśmy obsługę ścieżek w całym codebase.
Snapshoty zależne od platformy
Funkcja add_location() w Svelte zawiera pozycje znaków zależne od zakończeń linii. Windows używa \r\n (2 bajty), a Unix \n (1 bajt), co przesuwa pozycje znaków i powoduje fail testów snapshotowych. Zaimplementowaliśmy platformowo-niezależne czyszczenie snapshotów i naprawiliśmy placeholdery base64 sourcemap, które zostały przypadkowo zacommitowane.
Problemy z timeoutami CI
Runnery CI na Windows są wolniejsze niż na Ubuntu. Testy E2E, które działały na Ubuntu, trafiały w limity czasu na Windows. Istniejące testy e2e na Ubuntu były również niestabilne z powodu timeoutów, utrudniając weryfikację PR-a dla Windows. Zwiększyliśmy timeouty, ustabilizowaliśmy testy Ubuntu i dodaliśmy konfigurowalne limity czasu we wszystkich jobach CI.
4. Pipeline CI/CD, który zbudowaliśmy
Poza poprawką Windows, przebudowaliśmy cały pipeline CI/CD dla CRXJS. Oto jak wygląda pipeline teraz:
Matryca wieloplatformowa
Każdy PR i push do main uruchamia testy na Ubuntu i Windows. Matryca zapewnia, że regresje specyficzne dla platformy są łapane natychmiast, a nie miesiące później, gdy użytkownik Windows zgłosi buga.
Testowanie wielu wersji Vite
Skonsolidowaliśmy osobne workflow w jedno CI oparte na matrycy, testujące na Vite 3, 6, 7 i 8 ( #1093). Jedna definicja workflow, pełne pokrycie wersji. Gdy pojawiła się beta Vite 8, mieliśmy wsparcie CI gotowe od pierwszego dnia ( #1096).
Zabezpieczenia timeoutów
Joby CI mają teraz konfigurowalne limity czasu ( #1106). Koniec z zablokowanymi jobami spalającymi minuty CI. Jeśli test się zawiesi, failuje szybko z jasnym błędem zamiast cicho konsumować zasoby.
Automatyczne powiadomienia o wydaniach
Każdy npm publish z pipeline changeset wyzwala powiadomienie na Discordzie ( #1094). Społeczność dowiaduje się o nowych wydaniach natychmiast.
CI na zmianach CI
Dodaliśmy trigger, który uruchamia pełny build gdy zmieni się sama definicja workflow CI ( #1025). Zmiany CI to zmiany kodu — zasługują na tę samą walidację.
5. 27 pull requestów: pełna lista kontrybucji
Nasze kontrybucje do CRXJS wykraczają poza CI/CD. Oto kluczowe PR-y, a następnie pełna lista:
Kluczowe kontrybucje
feat: make the project build and test on windows
Flagowy PR. Dodanie matrycy CI dla Windows, naprawa obsługi ścieżek w całym codebase, rozwiązanie różnic w snapshotach zależnych od platformy (zakończenia linii w Svelte), naprawa kopiowania plików publicznych na Windows i poprawne działanie HMR z systemem plików Windows.
Odblokowanie developmentu na Windows dla całej społeczności CRXJS
refactor: consolidate Vite version tests into matrix-based CI
Zastąpienie zduplikowanych workflow CI jednym pipeline opartym na matrycy, testującym na Vite 3, 6, 7 i 8. Mniejsza złożoność konfiguracji CI przy większym pokryciu.
Jedna definicja workflow pokrywa wszystkie wersje Vite
feat: add Vite 8.0.0-beta.7 support and CI testing
Wsparcie Vite 8 beta w CRXJS przed oficjalnym wydaniem, zapewniając kompatybilność od pierwszego dnia dla developerów rozszerzeń.
Użytkownicy CRXJS mają wsparcie Vite 8 od dnia premiery
ci: add timeout limits to CI jobs
Konfigurowalne limity czasu, aby zapobiec nieskończonemu zawieszaniu się jobów CI. Mała zmiana z dużym wpływem na niezawodność i koszty CI.
Koniec z zablokowanymi jobami CI spalającymi minuty
feat: add Discord notifications after changeset publish
Automatyczne powiadomienia o wydaniach na Discordzie społeczności CRXJS. Każdy npm publish wyzwala powiadomienie, więc developerzy wiedzą, kiedy aktualizować.
Społeczność dowiaduje się o wydaniach natychmiast
feat: make crxjs development easier by providing dev setup
Uproszczenie onboardingu kontrybutorów z konfiguracjami dev containerów i skryptami setup. Obniżenie bariery wejścia dla nowych kontrybutorów.
Nowi kontrybutorzy mogą zacząć kodować w minuty
Wszystkie 27 pull requestów
6. Co to oznacza dla Twojego zespołu
To nie jest tylko historia kontrybucji open-source. Bezpośrednio odzwierciedla to, jak podchodzimy do DevOps dla naszych klientów:
Wieloplatformowość domyślnie
Jeśli Twój zespół używa Windows, Twój pipeline developmentu rozszerzeń działa na Windows. Bez obejść, bez "po prostu użyj WSL," bez doświadczenia drugiej kategorii. Wykonaliśmy ciężką pracę, żeby to działało wieloplatformowo na poziomie narzędzi.
CI/CD, które łapie prawdziwe bugi
Testowanie CI oparte na matrycy na różnych platformach i wersjach Vite oznacza, że łapiemy regresje zanim dotrą do użytkowników Twojego rozszerzenia. To samo podejście, które zbudowaliśmy dla CRXJS, stosujemy w projektach klienckich.
Głęboka wiedza o narzędziach
Gdy zatrudniasz zespół, który kontrybuuje do narzędzi build, których używa, dostajesz zespół potrafiący debugować na każdym poziomie stacku. Nie tylko "rozszerzenie nie działa" — ale dokładnie dlaczego nie działa, aż do wewnętrznych mechanizmów pluginu Vite, zachowania systemu plików i konfiguracji runnera CI.
Nie tylko używamy narzędzi open-source. Ulepszamy je. Tę samą dyscyplinę inżynierską wnosimy do każdego projektu klienckiego.
Potrzebujesz zespołu, który rozumie cały stack?
Od wewnętrznych mechanizmów pluginów Vite po wieloplatformowe CI/CD — budujemy rozszerzenia przeglądarkowe z tą samą dyscypliną inżynierską, którą wnosimy do open-source. Pozwól nam zbudować Twoje.
