Skip to content

Commit

Permalink
Release 1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ElForastero authored Oct 23, 2019
1 parent 90efd57 commit c468296
Show file tree
Hide file tree
Showing 31 changed files with 1,241 additions and 1,298 deletions.
4 changes: 2 additions & 2 deletions .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
"presets": ["@babel/preset-env", "@babel/preset-react"],
"plugins": [
[
"babel-plugin-react-css-modules",
"babel-plugin-styled-components",
{
"generateScopedName": "[hash:base64]"
"displayName": false
}
],
"@babel/plugin-proposal-class-properties"
Expand Down
1 change: 0 additions & 1 deletion .browserslistrc

This file was deleted.

12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
### 1.0.0

- Switched from CSS Modules to styled-components
- Removed postcss
- Added version sync between package.json and manifest.json
- Fixed auto reloading
- Added SVGR to load *.svg as React components
- Updated all dependencies
- Created an example of usage (see: [Framer ToDo](https://github.com/ElForastero/framer))
- Setup `src` directory as a modules source

### 0.0.2

- Added auto reloading with [webpack-extension-reloader](https://github.com/rubenspgcavalcante/webpack-extension-reloader)
- Fix: content.js tries to load background.css instead of content.css
51 changes: 28 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<h1 align="center">React (Preact) Browser Extension Boilerplate</h1>
<h1 align="center">React Web Extension Boilerplate</h1>
<p>
<img src="https://img.shields.io/badge/version-0.0.2-blue.svg?cacheSeconds=2592000" />
<img src="https://img.shields.io/badge/version-1.0.0-blue.svg?cacheSeconds=2592000" />
<a href="https://github.com/ElForastero/react-browser-extension-boilerplate#readme">
<img alt="Documentation" src="https://img.shields.io/badge/documentation-yes-brightgreen.svg" target="_blank" />
</a>
Expand All @@ -10,29 +10,29 @@
<a href="https://github.com/ElForastero/react-browser-extension-boilerplate/blob/master/LICENSE">
<img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-yellow.svg" target="_blank" />
</a>
<a href="https://twitter.com/el4astero">
<img alt="Twitter: el4astero" src="https://img.shields.io/twitter/follow/el4astero.svg?style=social" target="_blank" />
</a>
</p>

> This project aims to provide a simple boilerplate for writing browser extensions for the most popular browsers, such as Chrome, Firefox, Opera, new Edge and other Chromium-based browsers.
![React Web Extension Boilerplate](logo.png)

## 🎉 Features

- **Preact X or React** (by default Preact - lightweight React alternative)
- **Preact X or React** (you can switch them easily in webpack config)
- **Shadow DOM** for injected content
- **CSS Modules**
- **PostCSS** (preset-env and custom-properties)
- **Auto reloading**
- **Styled-Components**
- **Auto reloading** (there's no need to manually reload extension)
- Ready-to-go setup with **internationalization**

## 👨‍💻 Examples

You can look at [Framer](https://github.com/ElForastero/framer) todo list extension as an example of using this boilerplate. There's no straight instructions on how to use it, or any limitations on tools and technologies. Think of it as a regular react application with some special preperties.

## 📝 Description

It's built with `preact` and `preact-compat` which allows you to switch between `react` and `preact`.

Content and styles which are injected directly to the page, are isolated inside Shadow DOM. CSS modules are used to avoid class names collision.

![Example](screenshot.png)
Content and styles which are injected directly to the page, are isolated inside Shadow DOM.

## 🏁 Install

Expand All @@ -46,16 +46,28 @@ git clone [email protected]:ElForastero/react-browser-extension-boilerplate.git <YO
yarn watch
```

Runs webpack in watch mode. Automatically reloads the page after changes in files.
Runs webpack in watch mode. Automatically reloads the page after changes in files. Thanks to [webpack-extension-reloader](https://github.com/rubenspgcavalcante/webpack-extension-reloader).

```sh
yarn build
```

Builds the extension in production mode.
Builds the extension in production mode. This version can be shipped to the store.

## How to increment version

## ⚠️ Note on Content Security Policy (CSP)
"unsafe-eval" in directive 'script-src' is needed for auto reloading, and should be removed from production manifest.json.
Use [npm version](https://docs.npmjs.com/cli/version) cli command to bump a version of your package.json. The version of manifest will stay in sync with version specified in package.json.

For example:

```sh
npm version patch
```

This would increase you patch package.json version. During the next build output manifest file will have the same version.

## ⚠️ Content Security Policy (CSP)
"unsafe-eval" in directive "script-src" and "connect-src" are needed for auto reloading, and should be removed from production manifest.json.

## 💻 Useful links

Expand All @@ -68,13 +80,6 @@ Builds the extension in production mode.
- [webext-redux - a set o utilities to use redux in web extensions](https://github.com/tshaddix/webext-redux)
- [webpack-manifest-version-sync-plugin](https://github.com/ElForastero/webpack-manifest-version-sync-plugin)

## 👨‍💻 Author

👤 **Eugene Dzhumak**

* Twitter: [@el4astero](https://twitter.com/el4astero)
* Github: [@ElForastero](https://github.com/ElForastero)

## 🤝 Show your support

Give a ⭐️ if this project helped you!
Expand Down
Binary file added logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 25 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,44 +1,47 @@
{
"version": "0.0.2",
"name": "preact-browser-extension-boilerplate",
"license": "MIT",
"version": "1.0.0",
"name": "react-browser-extension-boilerplate",
"repository": {
"type": "git",
"url": "https://github.com/ElForastero/preact-browser-extension-boilerplate"
"url": "https://github.com/ElForastero/react-browser-extension-boilerplate"
},
"scripts": {
"build": "cross-env NODE_ENV=production yarn webpack -c webpack.config.js --mode production",
"watch": "cross-env NODE_ENV=development yarn webpack -c webpack.config.js --mode development -w"
},
"devDependencies": {
"@babel/core": "^7.6.0",
"@babel/core": "^7.6.4",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/preset-env": "^7.6.0",
"@babel/preset-react": "^7.0.0",
"@babel/preset-env": "^7.6.3",
"@babel/preset-react": "^7.6.3",
"@svgr/webpack": "^4.3.3",
"babel-loader": "^8.0.6",
"babel-plugin-react-css-modules": "^5.2.6",
"babel-plugin-styled-components": "^1.10.6",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^5.0.4",
"cross-env": "^5.2.1",
"css-loader": "^3.2.0",
"html-webpack-plugin": "^4.0.0-beta.5",
"incstr": "^1.2.3",
"mini-css-extract-plugin": "^0.8.0",
"postcss-custom-properties": "^9.0.2",
"postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.7.0",
"cross-env": "^6.0.3",
"html-webpack-plugin": "^4.0.0-beta.8",
"prettier": "^1.18.2",
"raw-loader": "^3.1.0",
"webpack": "^4.39.3",
"webpack-cli": "^3.3.8",
"webpack-extension-reloader": "^1.1.0"
"webpack": "^4.41.2",
"webpack-cli": "^3.3.9",
"webpack-extension-reloader": "^1.1.1",
"webpack-manifest-version-sync-plugin": "^0.0.2"
},
"dependencies": {
"@styled-system/prop-types": "^5.1.2",
"classnames": "^2.2.6",
"core-js": "^3.2.1",
"preact": "^10.0.0-beta.2",
"core-js": "^3.3.3",
"lodash.omit": "^4.5.0",
"preact": "^10.0.1",
"preact-shadow-root": "^1.0.2",
"prop-types": "^15.7.2",
"react-switch": "^5.0.1",
"regenerator-runtime": "^0.13.3",
"webextension-polyfill": "^0.4.0"
"styled-components": "^4.4.0",
"styled-system": "^5.1.2",
"use-click-outside": "^1.1.0",
"webextension-polyfill": "^0.5.0"
}
}
}
14 changes: 0 additions & 14 deletions postcss.config.js

This file was deleted.

Binary file removed screenshot.png
Binary file not shown.
4 changes: 2 additions & 2 deletions src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
"message": "Hello, World!"
},
"appName": {
"message": "Chromium extension boilerplate",
"message": "React Web Extension Boilerplate",
"description": "The title of the application, displayed in the web store."
},
"appShortName": {
"message": "Ext",
"message": "RWEB",
"description": "The short_name (maximum of 12 characters recommended) is a short version of the extension's name. "
},
"appDesc": {
Expand Down
4 changes: 2 additions & 2 deletions src/_locales/ru/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
"message": "Привет, Мир!"
},
"appName": {
"message": "Бойлерплейт для расширения",
"message": "React Web Extension Boilerplate",
"description": "Название расширения для магазина расширений."
},
"appShortName": {
"message": "Ext",
"message": "RWEB",
"description": "Короткая (рекомендовано максимум 12 символов) версия названия расширения."
},
"appDesc": {
Expand Down
4 changes: 0 additions & 4 deletions src/assets/css/palette.css

This file was deleted.

1 change: 1 addition & 0 deletions src/assets/icons/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/img/icon-128x128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/img/icon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/img/icon-48x48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions src/components/Box/Box.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import styled from 'styled-components';
import { space, layout, flexbox, position } from 'styled-system';
import propTypes from '@styled-system/prop-types';
import omitProps from 'libs/omitProps';

const propsToOmit = [
...Object.keys(propTypes.space),
...Object.keys(propTypes.layout),
...Object.keys(propTypes.flexbox),
...Object.keys(propTypes.position),
];

const Box = styled(omitProps('div', propsToOmit))`
box-sizing: border-box;
${layout}
${space}
${flexbox}
${position}
`;

export default Box;
3 changes: 3 additions & 0 deletions src/components/Box/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Box from './Box';

export default Box;
18 changes: 17 additions & 1 deletion src/components/Example/Example.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
import React from 'react';
import styled from 'styled-components';
import Box from 'components/Box';
import Logo from 'assets/icons/logo.svg';

const Example = styled.div`
color: ${props => props.theme.palette.primary};
font-size: 20px;
text-align: center;
`;

export default () => {
const greeting = chrome.i18n.getMessage('greeting');

return <div>{greeting}</div>;
return (
<Example>
<Box display="flex" alignItems="centeru">
<Logo width="50px" height="50px" />
{greeting}
</Box>
</Example>
);
};
47 changes: 28 additions & 19 deletions src/content.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,36 @@
import React, { useEffect, useState } from 'react';
import 'libs/polyfills';
import React from 'react';
import ReactDOM from 'react-dom';
import './content.module.css';
import browser from 'webextension-polyfill';
import { ThemeProvider, StyleSheetManager } from 'styled-components';
import Box from 'components/Box';
import Example from 'components/Example';
import defaultTheme from 'themes/default';

const BackgroundApp = () => {
const [css, updateCSS] = useState('');
const root = document.createElement('div');
const shadow = root.attachShadow({ mode: 'open' });

const styleContainer = document.createElement('div');
const appContainer = document.createElement('div');

useEffect(() => {
const url = browser.extension.getURL('assets/css/content.css');
fetch(url)
.then(response => response.text())
.then(updateCSS);
}, []);
shadow.appendChild(styleContainer);
shadow.appendChild(appContainer);

document.body.appendChild(root);

const App = () => {
return (
<div styleName="container">
<style>{css}</style>
</div>
<StyleSheetManager target={styleContainer}>
<ThemeProvider theme={defaultTheme}>
<Box
position="fixed"
bottom={3}
right={3}
>
<Example />
</Box>
</ThemeProvider>
</StyleSheetManager>
);
};

const root = document.createElement('div');
document.body.appendChild(root);
const shadow = root.attachShadow({ mode: 'open' });

ReactDOM.render(<BackgroundApp />, shadow);
ReactDOM.render(<App />, appContainer);
17 changes: 0 additions & 17 deletions src/content.module.css

This file was deleted.

21 changes: 21 additions & 0 deletions src/libs/omitProps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';
import PropTypes from 'prop-types';
import omit from 'lodash.omit';

/**
* @see https://github.com/styled-system/styled-system/issues/593#issuecomment-512350138
*/
export default function omitProps(Component, propsToOmit) {
function WithoutOmittedProps({ children, ...rest }) {
return <Component {...omit(rest, propsToOmit)}>{children}</Component>;
}

WithoutOmittedProps.propTypes = {
children: PropTypes.node,
};

WithoutOmittedProps.displayName = `WithoutOmittedProps(${Component.displayName ||
Component.name})`;

return WithoutOmittedProps;
}
2 changes: 2 additions & 0 deletions src/libs/polyfills.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import 'core-js/stable';
import 'regenerator-runtime/runtime';
Loading

0 comments on commit c468296

Please sign in to comment.