В этом руководстве предполагается, что у вас есть опыт или базовые знания для разработки расширения Chrome, или вы можете начать отсюда.

Расширение Chrome в основном состоит из файлов HTML и JavaScript, хотя у них разные роли и обязанности. Вы можете легко создать его с помощью исходного HTML, JavaScript, но есть проблема, которую мы хотим решить - поддержка современного JavaScript, такого как ES2015 + или SCSS и т. Д.

Чтобы завершить нашу цель, основная концепция заключается в том, что мы должны передать новый синтаксис JavaScript или других, которые браузеры еще НЕ поддерживают. Я знаю, что есть много решений, например, вы можете использовать Babel напрямую, Webpack, rollup и т. Д.

Большинство из этих способов требуют настройки, я могу только сказать, что это не очень просто для проекта расширения Chrome. В следующем разделе мы начнем наше простое решение с Parcel, которое адаптируется к проекту расширения Chrome.

Начиная

$ mkdir demo && cd demo
$ npm init
$ mkdir src
$ mkdir static

У нас получилась структура вида:

.
├── package.json
├── src
└── static

Мы поместим такие файлы, как manifest.json, _locales, images в static, которые не нужно передавать. Тогда независимо от того, .html или .js, если он нуждается в переносе, мы должны поместить его в папку src.

Манифест

Расширение начинается с manifest.json. Оно используется для настройки разрешений и функций. Поскольку нам не нужно передавать manifest.json, мы помещаем его в static

$ touch static/manifest.json

JSON следующим образом

{ 
  "name": "Demo",
  "version": "1.0.0", 
  "description": "", 
  "manifest_version": 2 
}

Расширение состоит из файлов, которые сохраняются в папке и в zip-архиве. На первом этапе мы установим Parcel, и он поможет нам скопировать те файлы, которые не нужно компилировать в dist

$ npm i parcel-bundler parcel-plugin-static-files-copy -D
# Parcel need a entry so we create background first
# We'll discuss later
$ touch src/background.js

Измените package.json, чтобы добавить команду сценариев

{
  ...
  "scripts": {
    "build": "parcel build src/background.js"
  },
  ...
}

После изменения package.json мы можем запустить команду:

$ npm run build

Вы должны увидеть папку dist, содержащую manifest.json и background.js.

На этом этапе вы уже получаете нашу основную концепцию, основываясь на вашем опыте расширения, вы можете организовать желаемую структуру. Опять же, основная концепция - файлы, которые нужно скомпилировать, должны сохраняться в src, остальные файлы, которые не нужно компилировать, сохраняются в static. Наконец, все результаты останутся в dist, а затем заархивированы, чтобы стать расширением.

Прямо сейчас вы можете протестировать свое расширение, открыв chrome://extensions в Chrome

  • Включите режим разработчика
  • Нажимаем на кнопку «Загрузить распакованный» и выбираем нашу папку dist.

Фон

Вы уже знаете, что расширение - это программа, основанная на событиях. Что это значит? Это означает, что мы можем поддерживать некоторые операции, инструкции, когда браузер выполняет такое действие, как закрытие вкладки, удаление закладки, открытие новой страницы и т.д. место, которое нам нужно.

Во-первых, нам нужно зарегистрировать фон в manifest.json, чтобы включить его.

{
  "name": "Demo",
  "version": "1.0.0",
  "description": "",
  "manifest_version": 2,
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  }
}

Измените src/background.js

chrome.runtime.onInstalled.addListener(() => {
  console.log('[background] chrome.runtime.onInstalled initialize'); 
});

В этом посте мы сосредоточимся только на организации и поддержке современного JavaScript. Если вы хотите больше, проверьте docs.

И снова вы запускаете npm run build, чтобы проверить результат в dist

Uncaught ReferenceError: регенератор Время выполнения не определено

Если вы используете такой синтаксис, как async/await, вы можете получить указанные выше ошибки.

Чтобы исправить это, добавьте browserslist в package.json.

"browserslist": [
   "last 1 Chrome versions"
]

Пользовательский интерфейс

Самая важная из причин, по которой я рекомендую вам попробовать расширение Parcel для Chrome, заключается в том, что оно может легко добавить дополнительную запись для компиляции. Например, в этом разделе мы хотим добавить всплывающее окно для browser_action. Можем добавить src/popup.html

<!DOCTYPE html>
<html>
  <head>
    <style>
      button {
        height: 30px;
        width: 30px;
        outline: none;
      }
    </style>
  </head>
  <body>
    <button id="change-color"></button>
  </body>
</html>

Изменить manifest.json

"browser_action": {
  "default_popup": "popup.html"
}

Наконец, самый важный шаг - добавить наш источник в команду Parcel в package.json

"scripts": {
  "build": "parcel build src/background.js src/popup.html"
}

Более того, в этом popup.html вы можете использовать современную структуру внешнего интерфейса JavaScript, такую ​​как React, Vue, Angular. В следующем разделе я покажу вам, как интегрироваться с React.

Скрипт контента с приложением React

content-script - это способ помочь нашему расширению вставлять контент в целевой URL. В этом разделе мы добавим iframe с нашим приложением React. Я думаю, что эта способность очень важна, что поможет реализовать вашу идею расширения.

Установите React и библиотеку

$ npm i react react-dom

Создавать файлы в src

$ touch src/content-script.js
$ touch src/app.html
$ touch src/app.js

Снова зарегистрируйте нашу функцию в manifest.json

"content_scripts": [
  {
    "matches": ["\\u003Call\\u005Furls\\u003E"],
    "js": ["content-script.js"],
    "run_at": "document_end"
  }
],
"web_accessible_resources": ["images/*", "app.html"]

src/app.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <style>
      html,
      body {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
      }
      #app {
        width: 100%;
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div id="app"></div>
    <script src="app.js" type="text/javascript"></script>
  </body>
</html>

app.js

import React from 'react';
import { render } from 'react-dom';
const App = () => (
  <div>Hello, Chrome extension with React</div>
);
render(
  <App />,
  document.getElementById('app'),
);

content-script.js

const iframe = document.createElement('iframe');
iframe.sandbox = 'allow-scripts allow-same-origin allow-forms';
iframe.setAttribute('allowFullScreen', '');
iframe.scrolling = 'no';
iframe.style.cssText = `
  width: 100%;
  height: 100%;
  border: 0;
  margin: 0;
  top: 0;
  left: 0;
  z-index: 2147483647;
  background-color: white;
  filter: none;
  display: block;
  position: fixed;
  overflow: auto;
`;
// NOTE: Add React application.
iframe.src = chrome.runtime.getURL('app.html');
document.body.appendChild(iframe);

Снова добавьте две записи в package.json

"scripts": {
  "build": "parcel build src/background.js src/popup.html src/app.html src/content-script.js"
}

npm run build снова, и вы должны проверить результат. Чтобы сделать команды более удобными, мы можем улучшить наши скрипты в package.json

"scripts": {
  "start": "parcel watch src/background.js src/popup.html src/app.html src/content-script.js --no-hmr",
  "build": "parcel build src/background.js src/popup.html src/app.html src/content-script.js && zip -9 -r extension.zip dist"
}

Ресурсы