mirror of
https://github.com/mdn/webextensions-examples.git
synced 2026-04-16 06:18:35 +02:00
Example using React / ES6 (#155)
This commit is contained in:
11
react-es6-popup/.babelrc
Normal file
11
react-es6-popup/.babelrc
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"presets": [
|
||||
"es2015",
|
||||
"stage-2",
|
||||
"react"
|
||||
],
|
||||
"plugins": [
|
||||
"transform-class-properties",
|
||||
"transform-es2015-modules-commonjs"
|
||||
]
|
||||
}
|
||||
5
react-es6-popup/.gitignore
vendored
Normal file
5
react-es6-popup/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# Ignore build artifacts and other files.
|
||||
.DS_Store
|
||||
yarn.lock
|
||||
extension/dist
|
||||
node_modules
|
||||
1
react-es6-popup/.npmrc
Normal file
1
react-es6-popup/.npmrc
Normal file
@@ -0,0 +1 @@
|
||||
save-prefix=''
|
||||
54
react-es6-popup/README.md
Normal file
54
react-es6-popup/README.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# React / ES6 Popup Example
|
||||
|
||||
## What it does
|
||||
|
||||
This is an example of creating a browser action
|
||||
[popup](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Add_a_button_to_the_toolbar#Adding_a_popup)
|
||||
UI in [React][react] and [ES6](http://es6-features.org/) JavaScript.
|
||||
|
||||
## What it shows
|
||||
|
||||
* How to bundle [React][react] and any other [NodeJS][nodejs] module into an
|
||||
extension.
|
||||
* How to transpile code that is not supported natively in
|
||||
a browser such as
|
||||
[import / export](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import)
|
||||
syntax and [JSX](https://facebook.github.io/react/docs/jsx-in-depth.html).
|
||||
* How to continuously build code as you edit files.
|
||||
* How to customize [web-ext][web-ext] for your extension's specific needs.
|
||||
* How to structure your code in reusable ES6 modules.
|
||||
|
||||
## Usage
|
||||
|
||||
First, you need to change into the example subdirectory and install all
|
||||
[NodeJS][nodejs] dependencies with [npm](http://npmjs.com/) or
|
||||
[yarn](https://yarnpkg.com/):
|
||||
|
||||
npm install
|
||||
|
||||
Start the continuous build process to transpile the code into something that
|
||||
can run in Firefox or Chrome:
|
||||
|
||||
npm run build
|
||||
|
||||
This creates a WebExtension in the `extension` subdirectory.
|
||||
Any time you edit a file, it will be rebuilt automatically.
|
||||
|
||||
In another shell window, run the extension in Firefox using a wrapper
|
||||
around [web-ext][web-ext]:
|
||||
|
||||
npm start
|
||||
|
||||
Any time you edit a file, [web-ext][web-ext] will reload the extension
|
||||
in Firefox. To see the popup, click the watermelon icon from the browser bar.
|
||||
Here is what it looks like:
|
||||
|
||||

|
||||
|
||||
[react]: https://facebook.github.io/react/
|
||||
[nodejs]: https://nodejs.org/en/
|
||||
[web-ext]: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Getting_started_with_web-ext
|
||||
|
||||
## Icons
|
||||
|
||||
The icon for this extension is provided by [icons8](https://icons8.com/).
|
||||
BIN
react-es6-popup/extension/images/Watermelon-48.png
Normal file
BIN
react-es6-popup/extension/images/Watermelon-48.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
react-es6-popup/extension/images/Watermelon-96.png
Normal file
BIN
react-es6-popup/extension/images/Watermelon-96.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
17
react-es6-popup/extension/manifest.json
Executable file
17
react-es6-popup/extension/manifest.json
Executable file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "react-es6-popup-example",
|
||||
"version": "1.0",
|
||||
|
||||
"browser_action": {
|
||||
"browser_style": true,
|
||||
"default_icon": {
|
||||
"48": "images/Watermelon-48.png",
|
||||
"96": "images/Watermelon-96.png"
|
||||
},
|
||||
"default_title": "React Example",
|
||||
"default_popup": "popup.html"
|
||||
},
|
||||
|
||||
"permissions": ["activeTab"]
|
||||
}
|
||||
8
react-es6-popup/extension/popup.css
Executable file
8
react-es6-popup/extension/popup.css
Executable file
@@ -0,0 +1,8 @@
|
||||
body {
|
||||
width: 400px;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
11
react-es6-popup/extension/popup.html
Executable file
11
react-es6-popup/extension/popup.html
Executable file
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="popup.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script src="dist/popup.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
25
react-es6-popup/package.json
Normal file
25
react-es6-popup/package.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "react-es6-popup-example",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "webpack -w -v --display-error-details --progress --colors",
|
||||
"start": "web-ext run -s extension/"
|
||||
},
|
||||
"author": "",
|
||||
"license": "MPL-2.0",
|
||||
"devDependencies": {
|
||||
"babel-core": "6.20.0",
|
||||
"babel-loader": "6.2.9",
|
||||
"babel-plugin-transform-class-properties": "6.19.0",
|
||||
"babel-plugin-transform-object-rest-spread": "6.20.2",
|
||||
"babel-preset-es2015": "6.18.0",
|
||||
"babel-preset-react": "6.16.0",
|
||||
"babel-preset-stage-2": "6.18.0",
|
||||
"react": "15.4.1",
|
||||
"react-dom": "15.4.1",
|
||||
"web-ext": "1.6.0",
|
||||
"webpack": "1.14.0"
|
||||
}
|
||||
}
|
||||
BIN
react-es6-popup/screenshots/popup.png
Normal file
BIN
react-es6-popup/screenshots/popup.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 75 KiB |
15
react-es6-popup/src/nested-component.js
vendored
Normal file
15
react-es6-popup/src/nested-component.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
|
||||
export default class Nested extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<h2>Nested Component</h2>
|
||||
<p>
|
||||
This is an example of a nested component that was imported via
|
||||
import / export syntax.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
36
react-es6-popup/src/popup.js
vendored
Executable file
36
react-es6-popup/src/popup.js
vendored
Executable file
@@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import Nested from './nested-component';
|
||||
|
||||
class Popup extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {activeTab: null};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// Get the active tab and store it in component state.
|
||||
chrome.tabs.query({active: true}, tabs => {
|
||||
this.setState({activeTab: tabs[0]});
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const {activeTab} = this.state;
|
||||
return (
|
||||
<div>
|
||||
<h1>React Component</h1>
|
||||
<p>
|
||||
This is an example of a popup UI in React.
|
||||
</p>
|
||||
<p>
|
||||
Active tab: {activeTab ? activeTab.url : '[waiting for result]'}
|
||||
</p>
|
||||
<Nested />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(<Popup/>, document.getElementById('app'));
|
||||
48
react-es6-popup/webpack.config.js
Normal file
48
react-es6-popup/webpack.config.js
Normal file
@@ -0,0 +1,48 @@
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
// Each entry in here would declare a file that needs to be transpiled
|
||||
// and included in the extension source.
|
||||
// For example, you could add a background script like:
|
||||
// background: './src/background.js',
|
||||
popup: './src/popup.js',
|
||||
},
|
||||
output: {
|
||||
// This copies each source entry into the extension dist folder named
|
||||
// after its entry config key.
|
||||
path: 'extension/dist',
|
||||
filename: '[name].js',
|
||||
},
|
||||
module: {
|
||||
// This transpiles all code (except for third party modules) using Babel.
|
||||
loaders: [{
|
||||
exclude: /node_modules/,
|
||||
test: /\.js$/,
|
||||
// Babel options are in .babelrc
|
||||
loaders: ['babel'],
|
||||
}],
|
||||
},
|
||||
resolve: {
|
||||
// This allows you to import modules just like you would in a NodeJS app.
|
||||
extensions: ['', '.js', '.jsx'],
|
||||
root: [
|
||||
path.resolve(__dirname),
|
||||
],
|
||||
modulesDirectories: [
|
||||
'src',
|
||||
'node_modules',
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
// Since some NodeJS modules expect to be running in Node, it is helpful
|
||||
// to set this environment var to avoid reference errors.
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify('production'),
|
||||
}),
|
||||
],
|
||||
// This will expose source map files so that errors will point to your
|
||||
// original source files instead of the transpiled files.
|
||||
devtool: 'sourcemap',
|
||||
};
|
||||
Reference in New Issue
Block a user