Example using React / ES6 (#155)

This commit is contained in:
Kumar McMillan
2016-12-13 05:54:23 -10:00
committed by GitHub
parent 62cd6d0a12
commit d12e2847a6
14 changed files with 231 additions and 0 deletions

11
react-es6-popup/.babelrc Normal file
View 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
View 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
View File

@@ -0,0 +1 @@
save-prefix=''

54
react-es6-popup/README.md Normal file
View 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:
![popup screenshot](screenshots/popup.png "React popup screenshot")
[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/).

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View 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"]
}

View File

@@ -0,0 +1,8 @@
body {
width: 400px;
padding: 1em;
}
h1, h2 {
border-bottom: 1px solid;
}

View 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>

View 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"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

15
react-es6-popup/src/nested-component.js vendored Normal file
View 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
View 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'));

View 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',
};