Ulepszone debugowanie
W ciągu ostatnich kilku miesięcy zespół Narzędzi deweloperskich w Chrome współpracował z zespołem Angulara nad ulepszeniami debugowania w Narzędziach deweloperskich w Chrome. Pracownicy obu zespołów współpracowali ze sobą i podejmowali działania, aby umożliwić deweloperom debugowanie i profilowanie aplikacji internetowych z perspektywy autora: w języku źródłowym i strukturze projektu, z dostępem do informacji, które są im znane i przydatne.
W tym poście przyjrzymy się bliżej temu, jakie zmiany w Angular i Narzędziach deweloperskich w Chrome były potrzebne do osiągnięcia tego celu. Chociaż niektóre z tych zmian są demonstrowane na przykładzie Angulara, można je zastosować również w innych ramach. Zespół Chrome DevTools zachęca inne frameworki do korzystania z nowych interfejsów API konsoli i punktów rozszerzenia mapy źródłowej, aby również one mogły oferować użytkownikom lepsze możliwości debugowania.
Kod ignorowania wizytówki
Podczas debugowania aplikacji za pomocą Narzędzi deweloperskich w Chrome autorzy zwykle chcą widzieć tylko swój kod, a nie frameworku lub zależności ukrytej w folderze node_modules.
Aby to osiągnąć, zespół Narzędzi deweloperskich wprowadził rozszerzenie map źródeł o nazwę x_google_ignoreList. To rozszerzenie służy do identyfikowania źródeł zewnętrznych, takich jak kod frameworku lub kod wygenerowany przez pakiet. Gdy framework używa tego rozszerzenia, autorzy mogą automatycznie unikać kodu, którego nie chcą widzieć lub przez który nie chcą przechodzić bez konieczności ręcznej konfiguracji.
W praktyce Narzędzia deweloperskie Chrome mogą automatycznie ukrywać kod zidentyfikowany w śladach stosu, drzewie źródeł i oknie Szybkie otwieranie, a także poprawiać działanie funkcji krokowania i wznawiania w debugerze.

Rozszerzenie mapy źródeł x_google_ignoreList
W mapach źródeł nowe pole x_google_ignoreList odwołuje się do tablicy sources i wypisuje indeksy wszystkich znanych źródeł zewnętrznych w danym pliku mapy źródeł. Podczas analizowania mapy źródłowej Narzędzia deweloperskie w Chrome użyją tego parametru, aby ustalić, które sekcje kodu należy pominąć.
Poniżej znajduje się mapa źródłowa wygenerowanego pliku out.js. Do wygenerowania pliku wyjściowego przyczyniły się 2 pierwotne sources: foo.js i lib.js. Pierwsza to część napisana przez dewelopera witryny, a druga to framework, którego użył.
{
"version" : 3,
"file": "out.js",
"sourceRoot": "",
"sources": ["foo.js", "lib.js"],
"sourcesContent": ["...", "..."],
"names": ["src", "maps", "are", "fun"],
"mappings": "A,AAAB;;ABCDE;"
}
sourcesContent jest uwzględniony w przypadku obu tych źródeł, a Narzędzia deweloperskie w Chrome wyświetlają te pliki domyślnie w Debugerze:
- jako pliki w drzewie źródeł.
- W oknie Szybkie otwieranie.
- Jako mapowane lokalizacje wywołań w ramkach błędów w wyświetleniu ścieżki błędów podczas wstrzymywania w miejscu punktu przerwania i przechodzenia.
W mapach źródeł można teraz uwzględnić 1 dodatkowy element informacji, który pozwala określić, które z nich są kodem własnym, a które kodem zewnętrznym:
{
...
"sources": ["foo.js", "lib.js"],
"x_google_ignoreList": [1],
...
}
Nowe pole x_google_ignoreList zawiera pojedynczy indeks odwołujący się do tablicy sources: 1. Określa to, że regiony mapowane na lib.js są w istocie kodem zewnętrznym, który powinien być automatycznie dodawany do listy ignorowanych.
W bardziej złożonym przykładzie pokazanym poniżej wskaźniki 2, 4 i 5 wskazują, że regiony mapowane na lib1.ts, lib2.coffee i hmr.js to kody innych firm, które powinny być automatycznie dodawane do listy ignorowanych.
{
...
"sources": ["foo.html", "bar.css", "lib1.ts", "baz.js", "lib2.coffee", "hmr.js"],
"x_google_ignoreList": [2, 4, 5],
...
}
Jeśli jesteś deweloperem frameworka lub pakietu, upewnij się, że mapy źródeł wygenerowane podczas procesu kompilacji zawierają to pole, aby można było korzystać z tych nowych funkcji w narzędziach programistycznych Chrome.
x_google_ignoreList w Angular
Od wersji Angular 14.1.0 zawartość folderów node_modules i webpack została oznaczona jako „do zignorowania”.
Osiągnięto to przez zmianę w angular-cli, tworząc wtyczkę, która łączy się z modułem Compiler w webpacku.
Wtyczka webpack, którą nasi inżynierowie stworzyli na etapie PROCESS_ASSETS_STAGE_DEV_TOOLING, wypełnia pole x_google_ignoreList w mapach źródeł dla końcowych zasobów, które webpack generuje i które przeglądarka wczytuje.
const map = JSON.parse(mapContent) as SourceMap;
const ignoreList = [];
for (const [index, path] of map.sources.entries()) {
if (path.includes('/node_modules/') || path.startsWith('webpack/')) {
ignoreList.push(index);
}
}
map[`x_google_ignoreList`] = ignoreList;
compilation.updateAsset(name, new RawSource(JSON.stringify(map)));
Połączone zrzuty stosu
Ścieżki stosu odpowiadają na pytanie „jak się tu znalazłem”, ale często jest to widok z perspektywy maszyny i niekoniecznie odpowiada on postrzeganiu dewelopera lub jego mentalnemu modelowi działania aplikacji. Jest to szczególnie ważne, gdy niektóre operacje są zaplanowane do wykonania asynchronicznie w późniejszym czasie: nadal może być interesujące poznanie „przyczyny źródłowej” lub strony planowania takich operacji, ale nie będzie to widoczne w asynchronicznym śladzie stosu.
V8 ma wewnętrzny mechanizm śledzenia takich zadań asynchronicznych, gdy używane są standardowe prymitywy harmonogramowania w przeglądarce, takie jak setTimeout. W takich przypadkach jest to domyślne, więc deweloperzy mogą już je sprawdzić. W przypadku bardziej złożonych projektów nie jest to jednak takie proste, zwłaszcza gdy używasz platformy z bardziej zaawansowanymi mechanizmami harmonogramowania, np. takiej, która wykonuje śledzenie stref, kolejkowanie niestandardowych zadań lub dzieli aktualizacje na kilka jednostek pracy, które są wykonywane w czasie.
Aby rozwiązać ten problem, DevTools udostępnia mechanizm o nazwie „Interfejs API otagowania stosu asynchronicznego” w obiekcie console, który umożliwia twórcom frameworków wskazywanie lokalizacji, w których zaplanowano operacje, oraz lokalizacji, w których są one wykonywane.
Async Stack Tagging API
Bez oznaczenia kodu asynchronicznego zrzuty kodu w przypadku kodu, który jest asynchronicznie wykonywany w złożony sposób przez frameworky, pojawiają się bez związku z kodem, w którym został zaplanowany.