Ich habe dieses Wochenende eine Chrome-Erweiterung erstellt, weil ich feststellte, dass ich immer wieder die gleiche Aufgabe ausführte und diese automatisieren wollte. Außerdem bin ich ein Nerd, der während einer Pandemie lebt, also investiere ich meine aufgestaute Energie in das Erstellen von Dingen. Ich habe im Laufe der Jahre einige Chrome-Erweiterungen erstellt, hoffentlich hilft Ihnen dieser Beitrag ebenfalls beim Einstieg. Fangen wir an!
Manifest erstellen
Der erste Schritt ist die Erstellung einer Datei manifest.json in einem Projektordner. Diese hat eine ähnliche Funktion wie eine package.json und liefert dem Chrome Web Store wichtige Informationen über das Projekt, einschließlich des Namens, der Version, der erforderlichen Berechtigungen und so weiter. Hier ist ein Beispiel
{
"manifest_version": 2,
"name": "Sample Name",
"version": "1.0.0",
"description": "This is a sample description",
"short_name": "Short Sample Name",
"permissions": ["activeTab", "declarativeContent", "storage", "<all_urls>"],
"content_scripts": [
{
"matches": ["<all_urls>"],
"css": ["background.css"],
"js": ["background.js"]
}
],
"browser_action": {
"default_title": "Does a thing when you do a thing",
"default_popup": "popup.html",
"default_icon": {
"16": "icons/icon16.png",
"32": "icons/icon32.png"
}
}
}
Sie bemerken vielleicht ein paar Dinge – erstens: Die **Namen** und **Beschreibungen** können beliebig sein.
Die **Berechtigungen** hängen davon ab, was die Erweiterung tun muss. Wir haben in diesem Beispiel ["activeTab", "declarativeContent", "storage", "<all_urls>"], da diese spezielle Erweiterung Informationen über den aktiven Tab benötigt, den Seiteninhalt ändern muss, auf localStorage zugreifen muss und auf allen Websites aktiv sein muss. Wenn sie nur auf einer Website gleichzeitig aktiv sein muss, können wir den letzten Index dieses Arrays entfernen.
Eine Liste aller Berechtigungen und deren Bedeutung finden Sie in der Chrome-Erweiterungsdokumentation.
"content_scripts": [
{
"matches": ["<all_urls>"],
"css": ["background.css"],
"js": ["background.js"]
}
],
Der Abschnitt content_scripts legt die Websites fest, auf denen die Erweiterung aktiv sein soll. Wenn Sie eine einzelne Website wünschen, wie zum Beispiel Twitter, würden Sie ["https://twitter.com/*"] angeben. Die CSS- und JavaScript-Dateien sind alles, was für Erweiterungen benötigt wird. Zum Beispiel verwendet meine productive Twitter-Erweiterung diese Dateien, um das Standardaussehen von Twitter zu überschreiben.
"browser_action": {
"default_title": "Does a thing when you do a thing",
"default_popup": "popup.html",
"default_icon": {
"16": "icons/icon16.png",
"32": "icons/icon32.png"
}
}
Es gibt auch optionale Elemente in browser_action. Wenn die Erweiterung beispielsweise kein Popup für ihre Funktionalität benötigt, können sowohl default_title als auch default_popup entfernt werden. In diesem Fall wird nur das Symbol für die Erweiterung benötigt. Wenn die Erweiterung nur auf bestimmten Websites funktioniert, wird das Symbol von Chrome ausgegraut, wenn es inaktiv ist.
Debugging
Sobald das Manifest, die CSS- und JavaScript-Dateien fertig sind, gehen Sie über die Adressleiste des Browsers zu chrome://extensions/ und aktivieren Sie den Entwicklermodus. Dies aktiviert die Schaltfläche "Entpackte Erweiterung laden", um die Erweiterungsdateien hinzuzufügen. Es ist auch möglich, ein- und auszuschalten, ob die Entwicklerversion der Erweiterung aktiv ist oder nicht.

Ich empfehle dringend, zu diesem Zeitpunkt ein GitHub-Repository zu erstellen, um die Dateien per Versionierung zu verwalten. Das ist eine gute Möglichkeit, die Arbeit zu speichern.
Die Erweiterung muss über diese Schnittstelle neu geladen werden, wenn sie aktualisiert wird. Ein kleines Aktualisierungssymbol wird auf dem Bildschirm angezeigt. Außerdem wird, wenn die Erweiterung während der Entwicklung Fehler aufweist, hier auch eine Fehlerschaltfläche mit einem Stacktrace und weiteren Informationen angezeigt.
Popup-Funktionalität
Wenn die Erweiterung ein Popup verwenden muss, das vom Erweiterungssymbol ausgeht, ist das glücklicherweise ziemlich einfach. Nachdem Sie den Namen der Datei mit browser_action in der Manifestdatei angegeben haben, kann eine Seite mit beliebigem HTML und CSS erstellt werden, das Sie einfügen möchten, einschließlich Bildern (ich verwende normalerweise Inline-SVG).
Wir möchten wahrscheinlich ein wenig Funktionalität zu einem Popup hinzufügen. Das kann etwas JavaScript erfordern, stellen Sie also sicher, dass die JavaScript-Datei in der Manifestdatei angegeben und auch in Ihrer Popup-Datei verknüpft ist, wie hier: <script src="background.js"></script>
In dieser Datei beginnen wir mit der Erstellung von Funktionalität und wir haben Zugriff auf das Popup-DOM wie folgt
document.addEventListener("DOMContentLoaded", () => {
var button = document.getElementById("submit")
button.addEventListener("click", (e) => {
console.log(e)
})
})
Wenn wir in der Datei popup.html einen Button erstellen, ihm die ID submit geben und dann ein Konsolenprotokoll zurückgeben, stellen Sie vielleicht fest, dass nichts tatsächlich in der Konsole protokolliert wird. Das liegt daran, dass wir uns in einem anderen Kontext befinden, was bedeutet, dass wir mit der rechten Maustaste auf das Popup klicken und einen anderen Satz von DevTools öffnen müssen.

Jetzt haben wir Zugriff auf Protokollierung und Debugging! Beachten Sie jedoch, dass, wenn etwas in localStorage gespeichert ist, es nur im localStorage der Erweiterungs-DevTools existiert; nicht im localStorage des Browser des Benutzers. (Das ist mir beim ersten Versuch passiert!)
Skripte außerhalb der Erweiterung ausführen
Das ist alles schön und gut, aber sagen wir, wir möchten ein Skript ausführen, das Zugriff auf Informationen im aktuellen Tab hat? Hier sind ein paar Möglichkeiten, wie wir das tun würden. Ich würde normalerweise eine separate Funktion aus dem DOMContentLoaded Event-Listener aufrufen
Beispiel 1: Eine Datei aktivieren
function exampleFunction() {
chrome.tabs.executeScript(() => {
chrome.tabs.executeScript({ file: "content.js" })
})
}
Beispiel 2: Nur ein bisschen Code ausführen
Diese Methode ist gut, wenn nur ein kleiner Codeabschnitt ausgeführt werden muss. Sie wird jedoch schnell schwierig zu handhaben, da alles als Zeichenkette oder Vorlagen-Literal übergeben werden muss.
function exampleFunction() {
chrome.tabs.executeScript({
code: `console.log(‘hi there’)`
})
}
Beispiel 3: Eine Datei aktivieren und einen Parameter übergeben
Denken Sie daran, dass die Erweiterung und der Tab in unterschiedlichen Kontexten arbeiten. Das macht die Übergabe von Parametern zwischen ihnen zu einer nicht ganz trivialen Aufgabe. Was wir hier tun, ist die Verschachtelung der ersten beiden Beispiele, um ein bisschen Code in die zweite Datei zu übergeben. Ich werde alles, was ich brauche, in einer einzigen Option speichern, aber wir müssen das Objekt serialisieren, damit das richtig funktioniert.
function exampleFunction(options) {
chrome.tabs.executeScript(
{ code: "var options = " + JSON.stringify(options) },
function() {
chrome.tabs.executeScript({ file: "content.js" })
}
)
}
Icons
Obwohl die Manifestdatei nur zwei Icons definiert, benötigen wir zwei weitere, um die Erweiterung offiziell im Chrome Web Store einzureichen: eines, das 128 Pixel quadratisch ist, und eines, das ich icon128_proper.png nenne, das ebenfalls 128 Pixel groß ist, aber etwas Polsterung zwischen dem Bildrand und dem Icon hat.
Beachten Sie, dass jedes verwendete Icon sowohl im hellen als auch im dunklen Modus des Browsers gut aussehen muss. Ich finde meine Icons normalerweise auf dem Noun Project.
Einreichung im Chrome Web Store
Nun begeben wir uns zur Entwicklerkonsole des Chrome Web Store, um die Erweiterung einzureichen! Klicken Sie auf die Schaltfläche "Neuer Artikel", dann ziehen und legen Sie die gezippte Projektdatei in den Uploader.

Von dort wird Chrome einige Fragen zur Erweiterung stellen und Informationen zu den angeforderten Berechtigungen und deren Notwendigkeit abfragen. **Vorsicht:** Die Anforderung von Berechtigungen wie "activeTab" oder "tabs" erfordert eine längere Überprüfung, um sicherzustellen, dass der Code keine missbräuchlichen Aktionen durchführt.
Das ist alles! Damit sollten Sie bestens vorbereitet sein und auf dem besten Weg, eine Chrome-Browsererweiterung zu entwickeln! 🎉
Ich benutze extensionizr.com
Das ist cool!
Danke! Ich habe kürzlich auch eine Erweiterung entwickelt und musste durch sehr alte Tutorials und Dokumentationen stöbern, um genau diese Art von Informationen zusammenzutragen. Habe das gerade als Lesezeichen gespeichert. <3
Ich habe nie daran gedacht, Dinge über Browsererweiterungen zu automatisieren, also danke sowohl für die Idee als auch für den Leitfaden.
Ich konnte eine Erweiterung erstellen, die eine JSON-Antwort von unserer API parst, was ich auch noch nie zuvor gemacht habe.
Sie erwähnten background.js im Abschnitt content_scripts im Manifest, es gibt auch einen Kontext namens background scripts in der Extension Runtime. Stellen Sie sicher, dass Sie diese beiden niemals verwechseln.
Hallo Sarah, tolle Sache! Danke, dass du das geschrieben hast. Es gibt nicht genug gute Inhalte über das Schreiben von Erweiterungen und die Dokumentation ist leider nicht so toll und manchmal sogar verwirrend.
Was ist der Zweck der Verwendung von
executeScripthier? Ihre Content-Skripte sollten standardmäßig bereits Zugriff auf das DOM haben, da sie wie jedes andere Skript-Tag auf Seiten geladen werden, auf denen die URL mit den von Ihnen im Manifest aufgeführten Websites übereinstimmt.Ich stimme der Person über mir zu, dass es etwas verwirrend ist, Ihre Content-Skript-Datei
background.jszu nennen, da es einen großen Unterschied zwischen der Rolle von Content-Skripten, die auf der Seite ausgeführt werden, wie ich erwähnt habe, und Hintergrund-Skripten gibt, die separat im Manifest deklariert werden und immer in einem Thread im Hintergrund laufen, solange Ihre Erweiterung aktiviert ist, aber sie haben keinen Zugriff auf den Inhalt der Tabs (verwendet für Dinge wie das Abhören von Post-Nachrichten, die Aufrechterhaltung des Zustands über Tabs/Seiten hinweg, die Bearbeitung von Post-Installations-/Update-Ereignissen usw.).Ich hoffe, das hilft und nochmals vielen Dank, ich liebe Ihre Inhalte und schätze, dass Sie sich immer die Zeit nehmen zu schreiben und zu unterrichten!
Laden Sie Ihre Erweiterung wirklich mit chrome.tabs.executeScript hoch? Und wurde sie vom Chrome Web Store genehmigt? Ich bezweifle es.
chrome.tabs.executeScript ist eine ernsthafte Sicherheitslücke. Ich glaube, CWS wird solche Erweiterungen blockieren.
Wenn Sie ein Skript im Kontext der aktuellen Tab-Seite ausführen möchten, sollten Sie sendMessage an ein "content script" aufrufen und dann die Nachricht dort verarbeiten.
Sie wurde genehmigt. Es gibt auch eine konstruktivere Art, Wissen zu teilen als diese.
Das war super hilfreich! Habe gerade meine erste Erweiterung eingereicht.
Hallo Sarah, vielen Dank für die tollen Inhalte. Ich habe Ihren Beitrag verfolgt, um meine Erweiterung zu erstellen, aber als ich versuchte, eine JS-Datei so einzufügen, wie Sie es tun, erhalte ich diesen Fehler
„Uncaught TypeError: Error in invocation of tabs.executeScript(optional integer tabId, extensionTypes.InjectDetails details, optional function callback): No matching signature.“
Ich verwende im Grunde den gleichen Ansatz wie Sie, um die JS-Datei hinzuzufügen, aber anscheinend gibt es ein Problem mit der Anweisung „executeScript“
$(document).ready(() => {
var button = document.getElementById(“submit”);
function exampleFunction() {
chrome.tabs.executeScript(() => {
chrome.tabs.executeScript({ file: “content.js” });
});
}
$(button).click((e) => {
exampleFunction();
});
});
Gut, dass ich das gefunden habe! Ich bin mir nicht ganz sicher, worum es geht, aber ich habe immer Probleme mit der Manifestdatei und der Zuweisung der richtigen Berechtigungen, also danke für die Klarstellung!
Aus Neugier, was ist Ihre Meinung zu etwas wie Extensionizr.com oder ChromeExtensionKit.com, das bei der Einrichtung hilft?
Ich denke, ein wirklich gutes Beispiel ist GoodPlan Notes aus dem Store aus technischer Sicht.
Das Setzen von content_scripts deaktiviert die Erweiterung nicht auf Websites, die nicht mit dem matches-Array übereinstimmen.
Ein Weg, den ich gefunden habe, um es zum Funktionieren zu bringen, ist
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
chrome.declarativeContent.onPageChanged.addRules([{
conditions: [new chrome.declarativeContent.PageStateMatcher({
pageUrl: {hostEquals: ‘domain.com’},
})
],
actions: [new chrome.declarativeContent.ShowPageAction()]
}]);
});
Frage
Sind wir uns ganz sicher, dass wir verschachtelte
executeScriptim Beispiel brauchen?Leute, können wir bitte ein neues Tutorial für Manifest v3 haben? Ich schlage mir gerade den Kopf an, da es im Moment nur sehr wenige Ressourcen für Manifest v3 gibt.