Перевод: сумасшедший технический ботаник
оригинал:呜呜.site point.com/build-v ue- from...
Копирование без разрешения строго запрещено
Расширения браузера — это небольшие программы, которые изменяют и улучшают функциональность вашего веб-браузера. Их можно использовать для различных задач, таких как блокировка рекламы, управление паролями, организация тегов, изменение внешнего вида и поведения веб-страниц и многое другое.
Хорошая новость заключается в том, что расширения для браузера писать несложно. Может быть создан с использованием уже знакомых вам веб-технологий (HTML, CSS и JavaScript) — точно так же, как и обычные веб-страницы. Но, в отличие от веб-страниц, расширения имеют доступ к ряду специфичных для браузера API-интерфейсов, и это становится интересным.
В этом уроке я покажу вам, как создать простое расширение для Chrome, которое изменяет поведение страницы новой вкладки. Для JavaScript-части этого расширения я буду использовать фреймворк Vue.js, потому чтоЭто позволит нам быстро приступить к работе, а работать с vue весело.
Код для этого руководства можно найти на GitHub.
Основы расширений Chrome
Основной частью расширения Chrome являетсяфайл манифестаа такжефоновый скрипт. Файл манифеста имеет формат JSON и предоставляет важную информацию о расширении, такую как его версия, ресурсы или необходимые разрешения. Фоновые сценарии позволяют расширениям реагировать на определенные события браузера, например на создание новой вкладки.
Чтобы продемонстрировать эти концепции, давайте начнем с написания расширения «Hello, World!» для Chrome.
Создатьhello-world-chromeновая папка и два файла:manifest.jsonа такжеbackground.js:
mkdir hello-world-chrome
cd hello-world-chrome
touch manifest.json background.js
Открытьmanifest.jsonи добавьте следующий код:
{
"name": "Hello World Extension",
"version": "0.0.1",
"manifest_version": 2,
"background": {
"scripts": ["background.js"],
"persistent": false
}
}
name,versionа такжеmanifest_versionобязательные поля.nameа такжеversionПоля могут быть какими угодно;manifest versionДолжно быть установлено значение 2 (начиная с Chrome 18).
backgroundпозволяет нам зарегистрировать фоновый скрипт, вscriptsперечислены в следующем массиве. если расширение не требуетchrome.webRequest APIблокировать или изменять сетевые запросы, в противном случаеpersistentключи должны быть установлены наfalse.
Добавьте следующий код вbackground.js, чтобы в браузере отображалось приветственное диалоговое окно при установке расширения:
chrome.runtime.onInstalled.addListener(() => {
alert('Hello, World!');
});
Наконец, установите расширение. Откройте Chrome и введите в адресной строкеchrome://extensions/. Вы должны увидеть страницу с установленными расширениями.
Поскольку мы устанавливаем собственное расширение из файла (а не из Интернет-магазина Chrome), его необходимо активировать с помощью переключателя в правом верхнем углу страницы.режим разработчика. Это должно добавить дополнительную строку меню сLoad unpackedопции. Нажмите эту кнопку и выберите тот, который вы создали ранееhello-world-chromeпапка. нажмитеОткрыть, вы должны увидеть установленные расширения и всплывающее окно «Hello, World!».
Поздравляем! Вы только что сделали расширение Chrome.
Переопределить новую вкладку Chrome
Приветствовать нас при открытии новой вкладки — это собственное расширение. можно сделать с помощьюOverride Pages APIдля завершения этой операции.
Примечание. Прежде чем продолжить, обязательно отключите другие расширения, которые охватывают новую вкладку Chrome. Только одно расширение может изменить это поведение одновременно.
Сначала создайте страницу для отображения, а не новую вкладку. мы называем егоtab.html. Он должен находиться в той же папке, что и файл манифеста и фоновый скрипт:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My New Tab Page!</title>
</head>
<body>
<h1>My New Tab Page!</h1>
<p>You can put any content here you like</p>
</body>
</html>
Следующий шаг — сообщить расширению о существовании страницы. можно указать в файле манифеста с помощьюchrome_url_overridesреализовать следующим образом:
"chrome_url_overrides": {
"newtab": "tab.html"
}
Наконец, вам нужно перезагрузить расширение, чтобы изменения вступили в силу. Вы можете сделать это, нажав на расширение Hello Worldreloadзначок, чтобы сделать это.
Теперь, когда вы открываете новую вкладку, появится ваше собственное сообщение.
Добавьте Vue в расширение
Теперь, когда у нас есть очень простое расширение, пришло время реализовать остальные необходимые функции. Когда пользователь открывает новую вкладку, я хочу, чтобы расширение:
- С замечательного сайта анекдотовicanhazdadjoke.comПолучите шутку.
- Покажите шутку пользователю в хорошем формате.
- Выводит кнопку, что пользователю нравится шутка. Это сохраняет шутку
chrome.storage. - Отображает кнопку для просмотра пользователями любимых шуток.
Конечно, вы также можете сделать все это с помощью чистого JavaScript или библиотеки, такой как jQuery — все готово!
Но для целей этого урока я буду использовать Vue и awesomevue-web-extensionШаблон для реализации этой функциональности.
Использование Vue позволяет мне писать более организованный код быстрее и лучше. Как мы видели, шаблон предоставляет несколько сценариев, которые решают некоторые распространенные и болезненные задачи при создании расширений Chrome (например, необходимость перезагружать расширение каждый раз, когда вы вносите изменения).
vue-web-extension-boilerplate
В этом разделе предполагается, что на вашем компьютере установлены Node и npm. Если нет, вы можете перейти кnodejs.org/en/Получите соответствующие двоичные файлы, или вы можетеИспользуйте менеджер версий. Я рекомендую использовать менеджер версий.
Нам также необходимо установитьVue CLIа также@vue/cli-init package:
npm install -g @vue/cli
npm install -g @vue/cli-init
Как только это будет сделано, давайте получим копию шаблона:
vue init kocal/vue-web-extension new-tab-page
Это откроет мастер и задаст вам кучу вопросов. Чтобы сохранить фокус этого урока, я перечислил ответы:
? Project name new-tab-page
? Project description A Vue.js web extension
? Author James Hibbard <jim@example.com>
? License MIT
? Use Mozilla's web-extension polyfill? No
? Provide an options page? No
? Install vue-router? No
? Install vuex? No
? Install axios? Yes
? Install ESLint? No
? Install Prettier? No
? Automatically install dependencies? npm
Вы можете настроить ответ по своему вкусу, но вы должны установитьaxios. Мы будем использовать его, чтобы получить шутки.
Затем перейдите в каталог проекта и установите зависимости:
cd new-tab-page
npm install
Затем мы можем создать наше новое расширение с помощью сценария, предоставленного шаблоном:
npm run watch:dev
Это создаст расширение в корневом каталоге проекта.distпапка для разработки и отслеживания изменений.
Чтобы добавить расширение в Chrome, выполните те же действия, что и выше, чтобы выбратьdistпапка в качестве каталога расширения. Если все пойдет по плану, вы должны увидеть сообщение «Hello world!» при инициализации расширения.
Настройки проекта
Давайте на минутку посмотрим, что дает нам шаблон. Текущая структура папок должна выглядеть так:
.
├── dist
│ └── <the built extension>
├── node_modules
│ └── <one or two files and folders>
├── package.json
├── package-lock.json
├── scripts
│ ├── build-zip.js
│ └── remove-evals.js
├── src
│ ├── background.js
│ ├── icons
│ │ ├── icon_128.png
│ │ ├── icon_48.png
│ │ └── icon.xcf
│ ├── manifest.json
│ └── popup
│ ├── App.vue
│ ├── popup.html
│ └── popup.js
└── webpack.config.js
Как вы можете видеть в корневом каталоге проекта, шаблон использует webpack. Это хорошо, потому что это обеспечивает наш фоновый скриптHot Module Reloading.
srcПапка содержит все файлы, которые мы будем использовать для расширения. файл манифеста иbackground.jsНам знакомо, но также обратите внимание на включение компонентов Vuepopupпапка. Когда шаблон строит расширение дляdistпапка, это пройдетvue-loaderуправлять всем.vueфайл и вывести пакет JavaScript, понятный браузерам.
существуетsrcВ папке есть еще одинiconsпапка. Если вы посмотрите на панель инструментов Chrome, вы увидите новый значок нашего расширения (также известный какbrowser action). Вот что я получил из этой папки. Если вы нажмете на него, вы должны увидеть всплывающее окно с надписью «Hello world!» Это делается с помощьюpopup/App.vueсозданный.
Наконец, обратите вниманиеscriptsДва скрипта для папок: один для удаленияevalИспользование для соблюдения Политики безопасности контента Интернет-магазина Chrome, а другое — для упаковки расширения в ZIP-файл, когда вы хотите загрузить его в Интернет-магазин Chrome.
существуетpackage.jsonВ файле также объявлены различные скрипты. мы будем использоватьnpm run watch:devДля разработки расширений используйтеnpm run build-zipСоздайте ZIP-файл для загрузки в веб-магазин Chrome.
Используйте компоненты Vue на новых вкладках
Первый изbackground.jsудалить раздражающийalertутверждение.
существуетsrcсоздать новую папкуtabПапка для хранения кода новой вкладки. Мы добавим в эту новую папку три файла:App.vue,tab.html,tab.js:
mkdir src/tab
touch src/tab/{App.vue,tab.html,tab.js}
Открытьtab.htmlи добавьте следующее:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>New Tab Page</title>
<link rel="stylesheet" href="tab.css">
</head>
<body>
<div id="app"></div>
<script src="tab.js"></script>
</body>
</html>
Здесь нет ничего особенного. Это простая HTML-страница, которая будет содержать наш экземпляр Vue.
следующий вtab.jsДобавить:
import Vue from 'vue';
import App from './App';
new Vue({
el: '#app',
render: h => h(App)
});
Импортируйте Vue сюда, используйте его, чтобы передать селектор элементу, а затем скажите ему, чтобы он отображалсяAppкомпоненты.
Наконец вApp.vueНапишите следующий код в:
<template>
<p>{{ message }}</p>
</template>
<script>
export default {
data () {
return {
message: "My new tab page"
}
}
}
</script>
<style scoped>
p {
font-size: 20px;
}
</style>
Прежде чем использовать эту новую вкладку, нам нужно обновить файл манифеста:
{
"name":"new-tab-page",
...
"chrome_url_overrides": {
"newtab": "tab/tab.html"
}
}
Чтобы сделать их доступными для расширений, нам также нужно, чтобы наши файлы были скомпилированы по шаблону и скопированы вdistпапка.
Изменить, как показано нижеwebpack.config.js,продлитьentryа такжеpluginsключ:
entry: {
'background': './background.js',
'popup/popup': './popup/popup.js',
'tab/tab': './tab/tab.js'
}
plugins: [
...
new CopyWebpackPlugin([
{ from: 'icons', to: 'icons', ignore: ['icon.xcf'] },
{ from: 'popup/popup.html', to: 'popup/popup.html', transform: transformHtml },
{ from: 'tab/tab.html', to: 'tab/tab.html', transform: transformHtml },
...
})
вам нужно перезагрузитьсяnpm run watch:devзадача, чтобы эти изменения вступили в силу. После этого перезагрузите расширение и откройте новую вкладку. Вы должны увидеть «Моя новая вкладка».
Получить и показать шутки
Хорошо, мы рассмотрели новую вкладку Chrome и заменили ее мини-приложением Vue. Но мы собираемся сделать больше, чем просто показать сообщение.
Изменятьsrc/tab/App.vueРаздел шаблона выглядит следующим образом:
<template>
<div>
<div v-if="loading">
<p>Loading...</p>
</div>
<div v-else>
<p class="joke">{{ joke }}</p>
</div>
</div>
</template>
Буду<script>Часть его изменена на следующий код:
<script>
import axios from 'axios';
export default {
data () {
return {
loading: true,
joke: "",
}
},
mounted() {
axios.get(
"https://icanhazdadjoke.com/",
{ 'headers': { 'Accept': 'application/json' } }
)
.then(res => {
this.joke = res.data.joke
this.loading = false;
});
}
}
</script>
Наконец, будет<style>Часть его изменена на следующий код:
<style>
body {
height: 98vh;
text-align: center;
color: #353638;
font-size: 22px;
line-height: 30px;
font-family: Merriweather,Georgia,serif;
background-size: 200px;
display: flex;
align-items: center;
justify-content: center;
}
.joke {
max-width: 800px;
}
</style>
если вы бежитеnpm run watch:devзадача, расширение автоматически перезагрузится, и вы будете видеть шутку каждый раз, когда открываете новую вкладку.
Затем найдите время, чтобы понять, что вы сделали.
В шаблоне мы используемv-ifблок для отображения загрузки сообщений или шуток, в зависимости отloadingположение дел. Изначально было установленоtrue(отображая сообщение о загрузке), наш скрипт инициирует Ajax-запрос для получения шутки. После завершения Ajax-запросаloadingсвойство будет установлено вfalse, вызывая повторный рендеринг компонента и показ шутки.
существует<script>мы импортировали axios, а затем объявили несколько свойств данных — упомянутый вышеloadingатрибуты иjokeсобственность, чтобы сохранить шутку. а затем использовалmount крючки жизненного цикла, который срабатывает после монтирования нашего экземпляра Vue, чтобыjoke APIСделайте запрос Ajax. После завершения запроса обновите два свойства данных, чтобы вызвать повторную визуализацию компонента.
Все идет нормально.
Сохранять шутки в Chrome Storage
Затем добавьте кнопки, которые позволяют пользователям ставить лайки шуткам и перечислять их любимые шутки. Так как мы будем использоватьAPI хранилища Chromeдля сохранения шуток, поэтому может потребоваться добавить третью кнопку для удаления шуток из хранилища.
Добавьте кнопку в блок v-else:
<div v-else>
<p class="joke">{{ joke }}</p>
<button @click="likeJoke" :disabled="likeButtonDisabled">Like Joke</button>
<button @click="logJokes" class="btn">Log Jokes</button>
<button @click="clearStorage" class="btn">Clear Storage</button>
</div>
Больше ничего захватывающего. Обратите внимание, что мы поместили что-то вроде кнопкиdisabledСвойства привязаны к свойствам данных в экземпляре Vue, чтобы определить его состояние. Это связано с тем, что пользователи не должны лайкать шутку более одного раза.
Затем добавьте обработчик кликов иLike Button DisabledДобавьте в раздел script:
export default {
data () {
return {
loading: true,
joke: "",
likeButtonDisabled: false
}
},
methods: {
likeJoke(){
chrome.storage.local.get("jokes", (res) => {
if(!res.jokes) res.jokes = [];
res.jokes.push(this.joke)
chrome.storage.local.set(res);
this.likeButtonDisabled = true;
});
},
logJokes(){
chrome.storage.local.get("jokes", (res) => {
if(res.jokes) res.jokes.map(joke => console.log(joke))
});
},
clearStorage(){
chrome.storage.local.clear();
}
},
mounted() { ... }
}
Здесь мы объявляем три новых метода для обработки трех новых кнопок.
likeJokeКак найти в хранилище ChromejokesАтрибуты. Если он не существует (то есть пользователю еще не понравилась шутка), он будет инициализирован пустым массивом. Затем он помещает текущую шутку в этот массив и сохраняет ее в хранилище. Наконец, будетlikeButtonDisabledСвойство данных установлено вtrue, и отключите кнопку «Нравится».
logJokesМетод также ищет в хранилище ChromejokesАтрибуты. Если он будет найден, он переберет все свои записи и выведет их на консоль.
clearStorageМетод отвечает за очистку данных.
Продолжайте настраивать эту новую функцию в расширении, пока она вас не устроит.
Сделайте некоторые украшения для расширения
Это работает, но кнопки некрасивые, а страница немного проще. Теперь давайте добавим немного блеска в расширение.
Далее установитеvue-awesomeбиблиотека. Это позволяет нам использовать значки Font Awesome на странице и сделать эти кнопки более красивыми:
npm install vue-awesome
существуетsrc/tab/tab.jsЗарегистрировано в библиотеке:
import Vue from 'vue';
import App from './App';
import "vue-awesome/icons";
import Icon from "vue-awesome/components/Icon";
Vue.component("icon", Icon);
new Vue({
el: '#app',
render: h => h(App)
});
Измените шаблон:
<template>
<div>
<div v-if="loading" class="centered">
<p>Loading...</p>
</div>
<div v-else>
<p class="joke">{{ joke }}</p>
<div class="button-container">
<button @click="likeJoke" :disabled="likeButtonDisabled" class="btn"><icon name="thumbs-up"></icon></button>
<button @click="logJokes" class="btn"><icon name="list"></icon></button>
<button @click="clearStorage" class="btn"><icon name="trash"></icon></button>
</div>
</div>
</div>
</template>
Наконец, давайте добавим к кнопке еще несколько стилей и добавим изображение:
<style>
body {
height: 98vh;
text-align: center;
color: #353638;
font-size: 22px;
line-height: 30px;
font-family: Merriweather,Georgia,serif;
background: url("https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2018/12/1544189726troll-dad.png") no-repeat 1% 99%;
background-size: 200px;
display: flex;
align-items: center;
justify-content: center;
}
.joke {
max-width: 800px;
}
.button-container {
position: absolute;
right: 0px;
top: calc(50% - 74px);
}
.btn {
background-color: #D8D8D8;
border: none;
color: white;
padding: 12px 16px;
font-size: 16px;
cursor: pointer;
display: block;
margin-bottom: 5px;
width: 50px;
}
.btn:hover {
background-color: #C8C8C8;
}
.btn:disabled {
background-color: #909090;
}
</style>
Перезагрузите расширение и откройте новую вкладку, и вы должны увидеть что-то вроде этого.
Загрузите расширение в Интернет-магазин Chrome.
Если вы хотите, чтобы другие люди использовали ваше расширение, вы можете использоватьChrome Web Storeсделай это.
Для начала вам понадобится учетная запись Google, с помощью которой вы сможете войтиDeveloper Dashboard. Вам будет предложено ввести данные разработчика, и вам придется заплатить регистрационный сбор разработчика в размере 5 долларов США (с помощью кредитной карты) перед публикацией вашего первого приложения.
Затем вам нужно создать ZIP-файл для вашего приложения. ты можешь пройтиnpm run build-zipДелайте это локально. Это создает файл в корневом каталоге проекта с именемdist-zipпапку, содержащую ZIP-файл, готовый для загрузки в Интернет-магазин.
Для простых небольших расширений этого достаточно. Однако, прежде чем загружать собственное расширение, обязательно прочитайте официальнуюPublish in the Chrome Web Storeгид.
Суммировать
В этом руководстве я сосредоточился на основных частях расширения Chrome и показал, как использовать его в Vue.js.vue-web-extensionШаблон создает расширение и, наконец, показывает, как загрузить расширение в Интернет-магазин.
Надеюсь, вам понравился этот урок, и вы использовали его для создания собственного расширения Chrome.