├── .gitignore ├── LICENSE ├── README.md ├── basic-key ├── .babelrc ├── content │ ├── src │ │ └── scripts │ │ │ ├── components │ │ │ └── app │ │ │ │ └── App.jsx │ │ │ └── index.js │ └── webpack.config.js ├── event │ ├── src │ │ └── index.js │ └── webpack.config.js ├── gulpfile.babel.js ├── manifest.json ├── package-lock.json ├── package.json └── popup │ ├── src │ ├── index.html │ └── scripts │ │ ├── components │ │ └── app │ │ │ └── App.jsx │ │ └── index.js │ └── webpack.config.js └── clicker-key ├── .babelrc ├── content ├── src │ └── scripts │ │ ├── components │ │ └── app │ │ │ └── App.jsx │ │ └── index.js └── webpack.config.js ├── event ├── src │ ├── index.js │ └── reducers │ │ ├── count.js │ │ └── index.js └── webpack.config.js ├── gulpfile.babel.js ├── manifest.json ├── package-lock.json ├── package.json └── popup ├── src ├── index.html └── scripts │ ├── components │ └── app │ │ └── App.jsx │ └── index.js └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | 35 | build/ 36 | 37 | .DS_Store 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Tyler Shaddix 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # webext-redux-examples 2 | Examples using webext-redux from [SoCal ReactJS meetup](https://www.youtube.com/watch?v=k88OIWJENgE). 3 | 4 | ## To Run An Example 5 | Clone or download this repo. 6 | 7 | Navigate to an example's root folder, then run 8 | 9 | ``` 10 | npm install 11 | ``` 12 | 13 | To build the project, run 14 | 15 | ``` 16 | npm start 17 | ``` 18 | 19 | And webpack bundle will be created. 20 | 21 | In the root project directory, you will find a `build` folder. To install the extension in chrome, go to chrome://extensions on your browser, make sure developer mode is enabled, and click on "Load unpacked extension...". Select the `build` directory and you're on you're way! 22 | -------------------------------------------------------------------------------- /basic-key/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"] 3 | } -------------------------------------------------------------------------------- /basic-key/content/src/scripts/components/app/App.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | 3 | class App extends Component { 4 | constructor(props) { 5 | super(props); 6 | 7 | this.state = { 8 | count: 0 9 | }; 10 | } 11 | 12 | componentDidMount() { 13 | document.addEventListener('click', () => { 14 | this.setState({ 15 | count: this.state.count + 1 16 | }); 17 | }); 18 | } 19 | 20 | render() { 21 | return ( 22 |
23 | Count: {this.state.count} 24 |
25 | ); 26 | } 27 | } 28 | 29 | export default App; 30 | -------------------------------------------------------------------------------- /basic-key/content/src/scripts/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {render} from 'react-dom'; 3 | 4 | import App from './components/app/App'; 5 | 6 | const anchor = document.createElement('div'); 7 | anchor.id = 'rcr-anchor'; 8 | 9 | document.body.insertBefore(anchor, document.body.childNodes[0]); 10 | 11 | render(, document.getElementById('rcr-anchor')); 12 | -------------------------------------------------------------------------------- /basic-key/content/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | 5 | entry: [ 6 | './content/src/scripts/index.js' 7 | ], 8 | 9 | output: { 10 | filename: 'content.js', 11 | path: path.join(__dirname, '../', 'build'), 12 | publicPath: '/' 13 | }, 14 | 15 | resolve: { 16 | extensions: ['.js', '.jsx', '.scss', '.json'], 17 | modules: ['node_modules'] 18 | }, 19 | 20 | module: { 21 | loaders: [ 22 | { 23 | test: /\.(jsx|js)?$/, 24 | loader: 'babel-loader', 25 | exclude: /(node_modules)/, 26 | include: path.join(__dirname, 'src'), 27 | query: { 28 | presets: ['es2015', 'react'] 29 | } 30 | } 31 | ] 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /basic-key/event/src/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tshaddix/webext-redux-examples/b68cf0ed9fad55ca196864cc1ebaa1c7ee5d6f02/basic-key/event/src/index.js -------------------------------------------------------------------------------- /basic-key/event/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | 5 | entry: [ 6 | './event/src/index.js' 7 | ], 8 | 9 | output: { 10 | filename: 'event.js', 11 | path: path.join(__dirname, '../', 'build') 12 | }, 13 | 14 | resolve: { 15 | extensions: ['.js', '.json'], 16 | modules: ['node_modules'] 17 | }, 18 | 19 | module: { 20 | loaders: [ 21 | { 22 | test: /\.(js)?$/, 23 | loader: 'babel-loader', 24 | exclude: /(node_modules)/, 25 | include: path.join(__dirname, 'src'), 26 | query: { 27 | presets: ['es2015', 'react'] 28 | } 29 | } 30 | ] 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /basic-key/gulpfile.babel.js: -------------------------------------------------------------------------------- 1 | import gulp from 'gulp'; 2 | import loadPlugins from 'gulp-load-plugins'; 3 | import webpack from 'webpack'; 4 | import rimraf from 'rimraf'; 5 | 6 | const plugins = loadPlugins(); 7 | 8 | import popupWebpackConfig from './popup/webpack.config'; 9 | import eventWebpackConfig from './event/webpack.config'; 10 | import contentWebpackConfig from './content/webpack.config'; 11 | 12 | gulp.task('popup-js', ['clean'], (cb) => { 13 | webpack(popupWebpackConfig, (err, stats) => { 14 | if(err) throw new plugins.util.PluginError('webpack', err); 15 | 16 | plugins.util.log('[webpack]', stats.toString()); 17 | 18 | cb(); 19 | }); 20 | }); 21 | 22 | gulp.task('event-js', ['clean'], (cb) => { 23 | webpack(eventWebpackConfig, (err, stats) => { 24 | if(err) throw new plugins.util.PluginError('webpack', err); 25 | 26 | plugins.util.log('[webpack]', stats.toString()); 27 | 28 | cb(); 29 | }); 30 | }); 31 | 32 | gulp.task('content-js', ['clean'], (cb) => { 33 | webpack(contentWebpackConfig, (err, stats) => { 34 | if(err) throw new plugins.util.PluginError('webpack', err); 35 | 36 | plugins.util.log('[webpack]', stats.toString()); 37 | 38 | cb(); 39 | }); 40 | }); 41 | 42 | gulp.task('popup-html', ['clean'], () => { 43 | return gulp.src('popup/src/index.html') 44 | .pipe(plugins.rename('popup.html')) 45 | .pipe(gulp.dest('./build')) 46 | }); 47 | 48 | gulp.task('copy-manifest', ['clean'], () => { 49 | return gulp.src('manifest.json') 50 | .pipe(gulp.dest('./build')); 51 | }); 52 | 53 | gulp.task('clean', (cb) => { 54 | rimraf('./build', cb); 55 | }); 56 | 57 | gulp.task('build', ['copy-manifest', 'popup-js', 'popup-html', 'event-js', 'content-js']); 58 | 59 | gulp.task('watch', ['default'], () => { 60 | gulp.watch('popup/**/*', ['build']); 61 | gulp.watch('content/**/*', ['build']); 62 | gulp.watch('event/**/*', ['build']); 63 | }); 64 | 65 | gulp.task('default', ['build']); 66 | -------------------------------------------------------------------------------- /basic-key/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "RCR", 4 | "description": "React, Chrome, and Redux example", 5 | "version": "0.0.0.1", 6 | "background": { 7 | "scripts": [ 8 | "event.js" 9 | ], 10 | "persistent": true 11 | }, 12 | "browser_action": { 13 | "default_title": "RCR Example", 14 | "default_popup": "popup.html" 15 | }, 16 | "content_scripts": [ 17 | { 18 | "matches": ["*://*/*"], 19 | "css": [], 20 | "js": ["content.js"] 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /basic-key/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rcr-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "description": "", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "./node_modules/.bin/gulp" 9 | }, 10 | "author": "Tyler Shaddix", 11 | "dependencies": { 12 | "react": "^15.5.0", 13 | "react-dom": "^15.5.0", 14 | "react-redux": "^4.0.0", 15 | "redux": "^3.0.4", 16 | "webext-redux": "^2.0.0" 17 | }, 18 | "devDependencies": { 19 | "babel-core": "^6.24.1", 20 | "babel-loader": "^7.0.0", 21 | "babel-preset-es2015": "^6.24.1", 22 | "babel-preset-react": "^6.24.1", 23 | "gulp": "^3.9.0", 24 | "gulp-load-plugins": "^1.2.0", 25 | "gulp-rename": "^1.2.2", 26 | "gulp-util": "^3.0.7", 27 | "rimraf": "^2.5.0", 28 | "webpack": "^2.6.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /basic-key/popup/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | RCR Example 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /basic-key/popup/src/scripts/components/app/App.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | 3 | class App extends Component { 4 | constructor(props) { 5 | super(props); 6 | 7 | this.state = { 8 | count: 0 9 | }; 10 | } 11 | 12 | componentDidMount() { 13 | setInterval(() => { 14 | this.setState({ 15 | count: this.state.count + 1 16 | }); 17 | }, 1000); 18 | } 19 | 20 | render() { 21 | return ( 22 |
23 | Hello World {this.state.count} 24 |
25 | ); 26 | } 27 | } 28 | 29 | export default App; 30 | -------------------------------------------------------------------------------- /basic-key/popup/src/scripts/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {render} from 'react-dom'; 3 | 4 | import App from './components/app/App'; 5 | 6 | render( 7 | 8 | , document.getElementById('app')); 9 | -------------------------------------------------------------------------------- /basic-key/popup/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | 5 | entry: [ 6 | './popup/src/scripts/index.js' 7 | ], 8 | 9 | output: { 10 | filename: 'popup.js', 11 | path: path.join(__dirname, '../', 'build'), 12 | publicPath: '/' 13 | }, 14 | 15 | resolve: { 16 | extensions: ['.js', '.jsx', '.scss', '.json'], 17 | modules: ['node_modules'] 18 | }, 19 | 20 | module: { 21 | loaders: [ 22 | { 23 | test: /\.(jsx|js)?$/, 24 | loader: 'babel-loader', 25 | exclude: /(node_modules)/, 26 | include: path.join(__dirname, 'src'), 27 | query: { 28 | presets: ['es2015', 'react'] 29 | } 30 | } 31 | ] 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /clicker-key/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"] 3 | } -------------------------------------------------------------------------------- /clicker-key/content/src/scripts/components/app/App.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {connect} from 'react-redux'; 3 | 4 | class App extends Component { 5 | constructor(props) { 6 | super(props); 7 | } 8 | 9 | componentDidMount() { 10 | document.addEventListener('click', () => { 11 | this.props.dispatch({ 12 | type: 'ADD_COUNT' 13 | }); 14 | }); 15 | } 16 | 17 | render() { 18 | return ( 19 |
20 | Count: {this.props.count} 21 |
22 | ); 23 | } 24 | } 25 | 26 | const mapStateToProps = (state) => { 27 | return { 28 | count: state.count 29 | }; 30 | }; 31 | 32 | export default connect(mapStateToProps)(App); 33 | -------------------------------------------------------------------------------- /clicker-key/content/src/scripts/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {render} from 'react-dom'; 3 | import {Provider} from 'react-redux'; 4 | import {Store} from 'webext-redux'; 5 | 6 | import App from './components/app/App'; 7 | 8 | const proxyStore = new Store(); 9 | 10 | const anchor = document.createElement('div'); 11 | anchor.id = 'rcr-anchor'; 12 | 13 | document.body.insertBefore(anchor, document.body.childNodes[0]); 14 | 15 | proxyStore.ready().then(() => { 16 | render( 17 | 18 | 19 | 20 | , document.getElementById('rcr-anchor')); 21 | }); 22 | -------------------------------------------------------------------------------- /clicker-key/content/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | 5 | entry: [ 6 | './content/src/scripts/index.js' 7 | ], 8 | 9 | output: { 10 | filename: 'content.js', 11 | path: path.join(__dirname, '../', 'build'), 12 | publicPath: '/' 13 | }, 14 | 15 | resolve: { 16 | extensions: ['.js', '.jsx', '.scss', '.json'], 17 | modules: ['node_modules'] 18 | }, 19 | 20 | module: { 21 | loaders: [ 22 | { 23 | test: /\.(jsx|js)?$/, 24 | loader: 'babel-loader', 25 | exclude: /(node_modules)/, 26 | include: path.join(__dirname, 'src'), 27 | query: { 28 | presets: ['es2015', 'react'] 29 | } 30 | } 31 | ] 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /clicker-key/event/src/index.js: -------------------------------------------------------------------------------- 1 | import {createStore} from 'redux'; 2 | import rootReducer from './reducers'; 3 | 4 | import {wrapStore} from 'webext-redux'; 5 | 6 | const store = createStore(rootReducer, {}); 7 | 8 | wrapStore(store); 9 | -------------------------------------------------------------------------------- /clicker-key/event/src/reducers/count.js: -------------------------------------------------------------------------------- 1 | const initialState = 0; 2 | 3 | export default (state = initialState, action) => { 4 | switch (action.type) { 5 | case 'ADD_COUNT': 6 | return state + (action.payload || 1); 7 | default: 8 | return state; 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /clicker-key/event/src/reducers/index.js: -------------------------------------------------------------------------------- 1 | import {combineReducers} from 'redux'; 2 | 3 | import count from './count'; 4 | 5 | export default combineReducers({ 6 | count 7 | }); 8 | -------------------------------------------------------------------------------- /clicker-key/event/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | 5 | entry: [ 6 | './event/src/index.js' 7 | ], 8 | 9 | output: { 10 | filename: 'event.js', 11 | path: path.join(__dirname, '../', 'build') 12 | }, 13 | 14 | resolve: { 15 | extensions: ['.js', '.json'], 16 | modules: ['node_modules'] 17 | }, 18 | 19 | module: { 20 | loaders: [ 21 | { 22 | test: /\.(js)?$/, 23 | loader: 'babel-loader', 24 | exclude: /(node_modules)/, 25 | include: path.join(__dirname, 'src'), 26 | query: { 27 | presets: ['es2015', 'react'] 28 | } 29 | } 30 | ] 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /clicker-key/gulpfile.babel.js: -------------------------------------------------------------------------------- 1 | import gulp from 'gulp'; 2 | import loadPlugins from 'gulp-load-plugins'; 3 | import webpack from 'webpack'; 4 | import rimraf from 'rimraf'; 5 | 6 | const plugins = loadPlugins(); 7 | 8 | import popupWebpackConfig from './popup/webpack.config'; 9 | import eventWebpackConfig from './event/webpack.config'; 10 | import contentWebpackConfig from './content/webpack.config'; 11 | 12 | gulp.task('popup-js', ['clean'], (cb) => { 13 | webpack(popupWebpackConfig, (err, stats) => { 14 | if(err) throw new plugins.util.PluginError('webpack', err); 15 | 16 | plugins.util.log('[webpack]', stats.toString()); 17 | 18 | cb(); 19 | }); 20 | }); 21 | 22 | gulp.task('event-js', ['clean'], (cb) => { 23 | webpack(eventWebpackConfig, (err, stats) => { 24 | if(err) throw new plugins.util.PluginError('webpack', err); 25 | 26 | plugins.util.log('[webpack]', stats.toString()); 27 | 28 | cb(); 29 | }); 30 | }); 31 | 32 | gulp.task('content-js', ['clean'], (cb) => { 33 | webpack(contentWebpackConfig, (err, stats) => { 34 | if(err) throw new plugins.util.PluginError('webpack', err); 35 | 36 | plugins.util.log('[webpack]', stats.toString()); 37 | 38 | cb(); 39 | }); 40 | }); 41 | 42 | gulp.task('popup-html', ['clean'], () => { 43 | return gulp.src('popup/src/index.html') 44 | .pipe(plugins.rename('popup.html')) 45 | .pipe(gulp.dest('./build')) 46 | }); 47 | 48 | gulp.task('copy-manifest', ['clean'], () => { 49 | return gulp.src('manifest.json') 50 | .pipe(gulp.dest('./build')); 51 | }); 52 | 53 | gulp.task('clean', (cb) => { 54 | rimraf('./build', cb); 55 | }); 56 | 57 | gulp.task('build', ['copy-manifest', 'popup-js', 'popup-html', 'event-js', 'content-js']); 58 | 59 | gulp.task('watch', ['default'], () => { 60 | gulp.watch('popup/**/*', ['build']); 61 | gulp.watch('content/**/*', ['build']); 62 | gulp.watch('event/**/*', ['build']); 63 | }); 64 | 65 | gulp.task('default', ['build']); 66 | -------------------------------------------------------------------------------- /clicker-key/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "RCR", 4 | "description": "React, Chrome, and Redux example", 5 | "version": "0.0.0.1", 6 | "background": { 7 | "scripts": [ 8 | "event.js" 9 | ], 10 | "persistent": true 11 | }, 12 | "browser_action": { 13 | "default_title": "RCR Example", 14 | "default_popup": "popup.html" 15 | }, 16 | "content_scripts": [ 17 | { 18 | "matches": ["*://*/*"], 19 | "css": [], 20 | "js": ["content.js"] 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /clicker-key/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rcr-example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "description": "", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "./node_modules/.bin/gulp" 9 | }, 10 | "author": "Tyler Shaddix", 11 | "dependencies": { 12 | "react": "^15.5.0", 13 | "react-dom": "^15.5.0", 14 | "react-redux": "^4.0.0", 15 | "redux": "^3.0.4", 16 | "webext-redux": "^2.1.2" 17 | }, 18 | "devDependencies": { 19 | "babel-core": "^6.24.1", 20 | "babel-loader": "^7.0.0", 21 | "babel-preset-es2015": "^6.24.1", 22 | "babel-preset-react": "^6.24.1", 23 | "gulp": "^3.9.0", 24 | "gulp-load-plugins": "^1.2.0", 25 | "gulp-rename": "^1.2.2", 26 | "gulp-util": "^3.0.7", 27 | "rimraf": "^2.5.0", 28 | "webpack": "^2.6.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /clicker-key/popup/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | RCR Example 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /clicker-key/popup/src/scripts/components/app/App.jsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {connect} from 'react-redux'; 3 | 4 | class App extends Component { 5 | constructor(props) { 6 | super(props); 7 | } 8 | 9 | componentDidMount() { 10 | document.addEventListener('click', () => { 11 | this.props.dispatch({ 12 | type: 'ADD_COUNT' 13 | }); 14 | }); 15 | } 16 | 17 | render() { 18 | return ( 19 |
20 | Click Count: {this.props.count} 21 |
22 | ); 23 | } 24 | } 25 | 26 | const mapStateToProps = (state) => { 27 | return { 28 | count: state.count 29 | }; 30 | }; 31 | 32 | export default connect(mapStateToProps)(App); 33 | -------------------------------------------------------------------------------- /clicker-key/popup/src/scripts/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {render} from 'react-dom'; 3 | 4 | import App from './components/app/App'; 5 | 6 | import {Store} from 'webext-redux'; 7 | import {Provider} from 'react-redux'; 8 | 9 | const proxyStore = new Store(); 10 | 11 | proxyStore.ready().then(() => { 12 | render( 13 | 14 | ,document.getElementById('app')); 15 | }); 16 | 17 | -------------------------------------------------------------------------------- /clicker-key/popup/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | 5 | entry: [ 6 | './popup/src/scripts/index.js' 7 | ], 8 | 9 | output: { 10 | filename: 'popup.js', 11 | path: path.join(__dirname, '../', 'build'), 12 | publicPath: '/' 13 | }, 14 | 15 | resolve: { 16 | extensions: ['.js', '.jsx', '.scss', '.json'], 17 | modules: ['node_modules'] 18 | }, 19 | 20 | module: { 21 | loaders: [ 22 | { 23 | test: /\.(jsx|js)?$/, 24 | loader: 'babel-loader', 25 | exclude: /(node_modules)/, 26 | include: path.join(__dirname, 'src'), 27 | query: { 28 | presets: ['es2015', 'react'] 29 | } 30 | } 31 | ] 32 | } 33 | }; 34 | --------------------------------------------------------------------------------