Ich habe kürzlich eines meiner Projekte – Minimal Theme for Twitter – als Next.js Chrome-Erweiterung neu geschrieben, da ich React für das Popup verwenden wollte. Die Verwendung von React würde es mir ermöglichen, die Popup-Komponente meiner Erweiterung und ihre Anwendungslogik klar von ihren Content-Skripten zu trennen, bei denen es sich um die CSS- und JavaScript-Dateien handelt, die zur Ausführung der Funktionalität der Erweiterung benötigt werden.
Wie Sie vielleicht wissen, gibt es verschiedene Möglichkeiten, mit React zu beginnen, vom einfachen Hinzufügen von Skript-Tags bis zur Verwendung eines empfohlenen Toolchains wie Create React App, Gatsby oder Next.js. Es gibt einige sofortige Vorteile, die Sie von Next.js als React-Framework erhalten, wie die statische HTML-Funktion, die Sie mit next export erhalten. Während Funktionen wie das Vorladen von JavaScript und das integrierte Routing großartig sind, war mein Hauptziel bei der Neufassung meiner Chrome-Erweiterung die bessere Organisation des Codes, und hier glänzt Next.js wirklich. Es bietet Ihnen das Meiste aus der Box für die geringste Menge an unnötigen Dateien und Konfiguration. Ich habe versucht, mit Create React App herumzuspielen, und es gibt eine überraschende Menge an Boilerplate-Code, die ich nicht brauchte.
Ich dachte, es wäre einfach, zu einer Next.js Chrome-Erweiterung zu konvertieren, da es möglich ist, eine Next.js-Anwendung als statisches HTML zu exportieren. Es gibt jedoch einige Tücken, und in diesem Artikel erzähle ich Ihnen davon, damit Sie einige Fehler vermeiden können, die ich gemacht habe.
Zuerst hier das GitHub-Repo, wenn Sie direkt zum Code springen möchten.
Neu in der Entwicklung von Chrome-Erweiterungen? Sarah Drasner hat einen Leitfaden, der Ihnen den Einstieg erleichtert.
Ordnerstruktur
next-export ist ein Nachbearbeitungsschritt, der Ihren Next.js-Code kompiliert, sodass wir den eigentlichen Next.js- oder React-Code nicht in die Erweiterung aufnehmen müssen. Dies ermöglicht es uns, unsere Erweiterung auf ihre kleinstmögliche Dateigröße zu reduzieren, was wir für den Fall wünschen, dass die Erweiterung schließlich im Chrome Web Store veröffentlicht wird.
Hier ist also, wie der Code für meine Next.js Chrome-Erweiterung organisiert ist. Es gibt zwei Verzeichnisse – eines für den Code der Erweiterung und eines, das die Next.js-App enthält.
📂 extension
📄 manifest.json
📂 next-app
📂 pages
📂 public
📂 styles
📄 package.json
README.md
Das Build-Skript
Um next export in einem normalen Webprojekt zu verwenden, würden Sie das Standard-Next.js-Build-Skript in package.json wie folgt ändern:
"scripts": {
"build": "next build && next export"
}
Dann generiert die Ausführung von npm run build (oder yarn build) ein out-Verzeichnis.
In diesem Fall, der eine Chrome-Erweiterung betrifft, müssen wir die Ausgabe jedoch in unser extension-Verzeichnis exportieren, anstatt nach out. Außerdem müssen wir alle Dateien umbenennen, die mit einem Unterstrich (_) beginnen, da Chrome eine Warnung ausgibt, dass "Dateinamen, die mit „_“ beginnen, für die Verwendung durch das System reserviert sind."

Dies führt uns zu einem neuen Build-Skript wie diesem:
"scripts": {
"build": "next build && next export && mv out/_next out/next && sed -i '' -e 's/\\/_next/\\.\\/next/g' out/**.html && mv out/index.html ../extension && rsync -va --delete-after out/next/ ../extension/next/"
}
sed funktioniert unter MacOS anders als unter Linux. MacOS benötigt das Flag '' -e, um korrekt zu funktionieren. Wenn Sie unter Linux sind, können Sie dieses zusätzliche Flag weglassen.
Assets
Wenn Sie Assets im public-Ordner Ihres Next.js-Projekts verwenden, müssen wir diese ebenfalls in unseren Chrome-Erweiterungsordner übertragen. Zur Organisation stellt die Hinzufügung eines next-assets-Ordners innerhalb von public sicher, dass Ihre Assets nicht direkt in das extension-Verzeichnis ausgegeben werden.
Das vollständige Build-Skript mit Assets ist dieses, und es ist ein großes:
"scripts": {
"build": "next build && next export && mv out/_next out/next && sed -i '' -e 's/\\/_next/\\.\\/next/g' out/**.html && mv out/index.html ../extension && rsync -va --delete-after out/next/ ../extension/next/ && rm -rf out && rsync -va --delete-after public/next-assets ../extension/"
}
Chrome-Erweiterungsmanifest
Das gängigste Muster zur Aktivierung einer Chrome-Erweiterung ist das Auslösen eines Popups, wenn auf die Erweiterung geklickt wird. Dies können wir in Manifest V3 tun, indem wir das Schlüsselwort action verwenden. Und darin können wir default_popup angeben, damit es auf eine HTML-Datei verweist.
Hier verweisen wir auf eine index.html von Next.js.
{
"name": "Next Chrome",
"description": "Next.js Chrome Extension starter",
"version": "0.0.1",
"manifest_version": 3,
"action": {
"default_title": "Next.js app",
"default_popup": "index.html"
}
}
Die action-API hat in Manifest V3 browserAction und pageAction ersetzt.
Von Chrome-Erweiterungen nicht unterstützte Next.js-Funktionen
Einige Next.js-Funktionen erfordern einen Node.js-Webserver. Daher sind serverbezogene Funktionen wie next/image von einer Chrome-Erweiterung nicht unterstützt.
Mit der Entwicklung beginnen
Der letzte Schritt ist, die aktualisierte Next.js Chrome-Erweiterung zu testen. Führen Sie npm build (oder yarn build) aus dem Verzeichnis next-app aus, und stellen Sie sicher, dass die Datei manifest.json im Verzeichnis extension liegt.
Gehen Sie dann in einem neuen Chrome-Browserfenster zu chrome://extensions, aktivieren Sie den Entwicklermodus und klicken Sie auf die Schaltfläche Entpackt laden. Wählen Sie Ihr extension-Verzeichnis aus, und Sie können mit der Entwicklung beginnen!

Zusammenfassung
Das war's! Wie ich sagte, nichts davon war mir beim Einstieg in meine Chrome-Erweiterungs-Neufassung sofort klar. Aber hoffentlich sehen Sie jetzt, wie relativ einfach es ist, die Vorteile der Next.js-Entwicklung für die Entwicklung einer Chrome-Erweiterung zu nutzen. Und ich hoffe, es spart Ihnen die Zeit, die ich gebraucht habe, um es herauszufinden!
Toller Artikel. Wie wäre es mit der Erstellung einer Firefox-Erweiterung? Ist sie ähnlich wie das, was Sie oben gemacht haben? Wie wäre es außerdem mit der Verwendung der ‚browser‘-Erweiterungs-API, um eine gemeinsame Erweiterung für alle Browser zu erstellen?
Hallo Abu! Ja, tatsächlich ist die Portierung einer Chrome-Erweiterung auf Firefox mittlerweile sehr kompatibel. Das Einzige, was Sie beachten sollten, ist, dass sie derzeit unterschiedliche Pläne für Manifest V3 haben.
— Porting a Google Chrome extension
Nehmen wir an, ich benötige Content-Skripte. Wie kann ich von innerhalb der Content-Skripte auf die Komponenten zugreifen, oder ist das nicht möglich?
Das ist vielleicht möglich, aber extrem schwierig zu konfigurieren und liegt außerhalb des Rahmens dieses Beispiels. Sie können tatsächlich keine Module in
content_scriptsimportieren – https://stackoverflow.com/a/58137279/7948880Toller Artikel! Ich fand ihn sehr hilfreich.
Beachten Sie, dass Sie im Beispiel einige Verweise auf
/_next/vermissen, von denen einer in einem Regex enthalten ist.Ich habe ein kurzes, JavaScript-basiertes Skript erstellt, das für alle Plattformen funktioniert. Sehen Sie es in Aktion hier.
Danke, Weber! Ich mag dein Skript.
Können Sie klären, welche Referenzen fehlen?
Hallo Thomas
Zu Ihrer Information, ich konnte dies etwas vereinfachen, indem ich die manifest.json in den Public-Ordner aufgenommen habe.
Auf diese Weise wird sie während des Builds automatisch kopiert.
Ich bin aus einem Nickerchen aufgewacht und mir wurde klar, dass ich ein Chrome-Plugin erstellen musste. Ich war super besorgt, bis ich das hier sah. Kinderleicht und ich habe es am Laufen! Das ist fantastisch! Danke!
Erstaunlicher Beitrag. Vielen Dank!
Eine Sache, die ich am Build-Skript leicht ändern würde, ist: Es hat mich eine Weile gekostet, zu verstehen, warum Links zu anderen Seiten in meinem statischen Export nicht funktionierten.
Das liegt daran, dass das Skript nur die index.html-Datei verschiebt. Um alle Seiten zu verschieben, würde ich es wie folgt ändern:
Danke! Hier ist eine modifizierte Version von Webers Skript, wenn Sie Node.js verwenden möchten: https://github.com/typefully/minimal-twitter/blob/main/popup/sanitize.js