Расширения Chrome - отличный способ улучшить рабочий процесс пользователя. Они сокращают переключение контекста и упрощают работу разработчика. Вот как сделать их в React.
- Создание приложения React
- Создание расширения
- Добавление функциональности
- Добавление в Интернет-магазин Google Chrome
Создание приложения React
Первое, что вам нужно сделать, это создать приложение React. Чтобы упростить этот процесс, мы будем использовать create-react-app
в сочетании с шаблоном Typescript. В этом руководстве мы создадим простое расширение для игры в кости. Не стесняйтесь создавать свои собственные, просто обратите внимание на имена файлов, имена переменных и другие именованные параметры.
npx create-react-app roll-dice-extension --template typescript
Делаем расширение
После создания приложения вы увидите знакомую структуру папок. Перейдите в свою папку public
и обновите config.yaml
. Это файл, в котором указываются имя приложения, описание, значки и другие параметры, используемые Chrome.
{ "short_name": "Roll Dice", "name": "A simple extension for rolling dice", "icons": { "16": "/logo16.png", "32": "/logo32.png", "48": "/logo48.png", "128": "/logo128.png" }, "version": "1.0", "manifest_version": 3, "action": { "default_popup": "index.html" } }
Перед сборкой и загрузкой расширения в Chrome вам необходимо обновить package.json
скрипт сборки. Замените его следующим.
"build": "set \"INLINE_RUNTIME_CHUNK=false\" && react-scripts build"
Это просто удаляет небезопасный встроенный код Javascript из вашего приложения React, что запрещено в расширениях Chrome. Теперь, наконец, расширение можно создать, запустив npm run build
и перейдя в Chrome, где вы должны ввести chrome://extensions
в строке URL. Это приведет вас на страницу расширений, где можно загрузить расширение. Для этого вы должны сначала включить режим разработчика с помощью переключателя в правом верхнем углу, а затем нажать кнопку с надписью «Загрузить распакованный» и загрузить расширение, выбрав папку build
в вашем проекте.
Вот и все. Теперь ваше расширение должно быть доступно для запуска. Перейдите к своим расширениям, прикрепите их к заголовку Chrome и попробуйте нажать. Должно появиться следующее изображение.
Если вы хотите проверить расширение в производстве, не стесняйтесь проверить Math Embed - мое расширение для простого встраивания математических уравнений в Medium. В противном случае следуйте инструкциям, чтобы увидеть, как добавить базовую функциональность, или создайте свою собственную. (Github для встраивания математики)
Добавление функциональности
Добавление функциональности с этого момента - это вопрос обновления вашего приложения React. Мы не будем слишком зацикливаться на деталях того, как это работает, поскольку я предполагаю, что вы уже имеете хорошее представление о том, как работает React.
Запустите npm run start
, чтобы запустить сервер разработки. Вы должны увидеть то же приложение React, что и в расширении, только большего размера. Нам ничего из этого не нужно, поэтому просто удалите весь код tsx в App.tsx
.
//App.tsx import React from 'react'; import logo from './logo.svg'; import './App.css'; function App() { return ( ); } export default App;
Чтобы облегчить себе жизнь, мы установим Material UI npm install @material-ui/core
и создадим базовую тему и макет в нашем App.tsx
файле.
//App.tsx import { Box, Button, createMuiTheme, ThemeProvider, Typography, } from "@material-ui/core"; import { useState } from "react"; import "./App.css"; import RollDiceButton from "./RollDiceButton"; import RollDisplay from "./RollDisplay"; const theme = createMuiTheme({ typography: { allVariants: { color: "#FFFFFF", }, fontFamily: [ "Poppins", "sans-serif", '"Apple Color Emoji"', '"Segoe UI Emoji"', '"Segoe UI Symbol"', ].join(","), fontSize: 14, h1: { fontSize: 24, fontWeight: 700, }, }, }); function App() { return ( <ThemeProvider theme={theme}> <Box height="100%" flex={1} display="flex" justifyContent="center" alignItems="center" flexDirection="column" bgcolor="#023047" > </Box> </ThemeProvider> ); } export default App;
Разобравшись с этим, мы можем взглянуть на остальные функции нашего приложения. Мы будем разрабатывать:
- Базовое отображение всех выполненных нами бросков
- Сумма всех бросков
- Кнопки для увеличения и уменьшения количества брошенных кубиков
- И кнопка для бросания кубиков.
Для реализации этих функций мы разработаем следующее:
- Государства, в которых проводится подсчет кубиков и отдельные броски
- RollDiceButton: кнопка, которая принимает количество кубиков в качестве входных данных и возвращает отдельные броски.
- RollDisplay: отображение отдельных рулонов и их суммы
- Кнопки для увеличения или уменьшения количества кубиков
Мы начинаем с определения двух состояний в App.tsx
: одно, в котором хранятся отдельные значения броска игральных костей, и другое, в котором хранится текущее количество костей, которые мы бросаем.
const [diceRolls, setDiceRolls] = useState<number[]>([]); const [count, setCount] = useState(2);
Затем мы создадим новый файл для кнопки бросания кубиков RollDiceButton.tsx
. Кнопка будет принимать count
как счетчик кубиков и setDiceRolls
, который установит состояние в родительском компоненте.
Мы также добавим простые функции для генерации бросков кубиков getDiceRolls()
и getDiceRolls(count: number)
, которые будут запускаться при нажатии кнопки.
import { Box, Button } from "@material-ui/core"; import React, { useEffect } from "react"; interface RollDiceButtonProps { count: number; setDiceRolls: React.Dispatch<React.SetStateAction<number[]>>; } const getDiceRoll = () => { return Math.ceil(Math.random() * 6); }; const getDiceRolls = (count: number) => { var rolls: number[] = []; for (var i = 0; i < count; i++) { rolls.push(getDiceRoll()); } return rolls; }; const RollDiceButton: React.FC<RollDiceButtonProps> = (props) => { useEffect(() => { props.setDiceRolls(getDiceRolls(props.count)); }, [props.count]); return ( <Box> <Button variant="contained" color="primary" onClick={() => props.setDiceRolls(getDiceRolls(props.count))} > Roll Dice </Button> </Box> ); }; export default RollDiceButton;
Во-вторых, мы создадим компонент отображения RollDisplay.tsx
. Он будет принимать в качестве входных данных отдельные кубики diceRolls
бросков и отображать их в структурированном виде, включая сумму бросков.
import { Box, Typography } from "@material-ui/core"; import React from "react"; interface RollDisplayProps { diceRolls: number[]; } const RollDisplay: React.FC<RollDisplayProps> = (props) => { return ( <Box display="flex" justifyContent="center" alignItems="center" flexDirection="column" > <Box display="flex"> {props.diceRolls.map((roll) => ( <Box padding={1}> <Typography>{roll}</Typography> </Box> ))} </Box> <Box padding={1}> <Typography variant="h1"> {props.diceRolls.reduce((acc, value) => acc + value)} </Typography> </Box> </Box> ); }; export default RollDisplay;
Наконец, мы добавляем их к App.tsx
. Мы импортируем необходимые компоненты и включаем их в ThemeProvider
.
import { Box, Button, createMuiTheme, ThemeProvider, Typography, } from "@material-ui/core"; import { useState } from "react"; import "./App.css"; import RollDiceButton from "./RollDiceButton"; import RollDisplay from "./RollDisplay"; const theme = createMuiTheme({ typography: { allVariants: { color: "#FFFFFF", }, fontFamily: [ "Poppins", "sans-serif", '"Apple Color Emoji"', '"Segoe UI Emoji"', '"Segoe UI Symbol"', ].join(","), fontSize: 14, h1: { fontSize: 24, fontWeight: 700, }, }, }); function App() { const [diceRolls, setDiceRolls] = useState<number[]>([0, 0]); const [count, setCount] = useState(2); return ( <ThemeProvider theme={theme}> <Box height="100%" flex={1} display="flex" justifyContent="center" alignItems="center" flexDirection="column" bgcolor="#006d77" padding="16px" > <Box display="flex" justifyContent="center" alignItems="center" flexDirection="row" > <Button onClick={() => setCount(count > 1 ? count - 1 : 1)}> <Typography>-</Typography> </Button> <RollDisplay diceRolls={diceRolls}></RollDisplay>{" "} <Button onClick={() => setCount(count + 1)}> <Typography>+</Typography> </Button> </Box> <RollDiceButton setDiceRolls={setDiceRolls} count={count} ></RollDiceButton> </Box> </ThemeProvider> ); } export default App;
Вот и все, что касается простого расширения. Если вы где-то заблудились, не стесняйтесь заглянуть в репозиторий Github для этого проекта. Обновите его в chrome://extensions
и проверьте.
Добавление расширения в Интернет-магазин Google Chrome
Перед публикацией вы можете дважды проверить правильность работы расширения. Если все в порядке, вы готовы опубликовать его через Консоль разработчика Chrome Webstore.
Зарегистрируйтесь или войдите в консоль, нажмите + Новый элемент в правом верхнем углу, и вам будет предложено ввести файл .zip
. Просто заархивируйте build
папку вашего проекта и поместите ее в свой браузер.
Некоторая информация будет предварительно заполнена из вашего manifest.json
файла. Остальное зависит от тебя. После того, как все будет заполнено, загорится кнопка «Отправить на рассмотрение», и вы сможете отправить свое расширение на рассмотрение. Если он пройдет, вы увидите, что он добавлен в Интернет-магазин Chrome.
Поздравляю. Вы добрались до конца, и ваше расширение скоро появится в Интернет-магазине.
Обязательно дайте мне пару аплодисментов, если вы нашли это руководство полезным, и не стесняйтесь делиться им со всеми, кому оно может понадобиться.