Skip to content

Commit

Permalink
Example using React / ES6 (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
kumar303 committed Dec 13, 2016
1 parent 62cd6d0 commit d12e284
Show file tree
Hide file tree
Showing 14 changed files with 231 additions and 0 deletions.
11 changes: 11 additions & 0 deletions react-es6-popup/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"presets": [
"es2015",
"stage-2",
"react"
],
"plugins": [
"transform-class-properties",
"transform-es2015-modules-commonjs"
]
}
5 changes: 5 additions & 0 deletions react-es6-popup/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Ignore build artifacts and other files.
.DS_Store
yarn.lock
extension/dist
node_modules
1 change: 1 addition & 0 deletions react-es6-popup/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
save-prefix=''
54 changes: 54 additions & 0 deletions react-es6-popup/README.md
Original file line number Diff line number Diff line change
@@ -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/).
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions react-es6-popup/extension/manifest.json
Original file line number Diff line number Diff line change
@@ -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 changes: 8 additions & 0 deletions react-es6-popup/extension/popup.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
body {
width: 400px;
padding: 1em;
}

h1, h2 {
border-bottom: 1px solid;
}
11 changes: 11 additions & 0 deletions react-es6-popup/extension/popup.html
Original file line number Diff line number Diff line change
@@ -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 changes: 25 additions & 0 deletions react-es6-popup/package.json
Original file line number Diff line number Diff line change
@@ -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 added react-es6-popup/screenshots/popup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions react-es6-popup/src/nested-component.js
Original file line number Diff line number Diff line change
@@ -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 changes: 36 additions & 0 deletions react-es6-popup/src/popup.js
Original file line number Diff line number Diff line change
@@ -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 changes: 48 additions & 0 deletions react-es6-popup/webpack.config.js
Original file line number Diff line number Diff line change
@@ -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',
};

0 comments on commit d12e284

Please sign in to comment.