├── src
├── index.js
├── reducers
│ ├── index.js
│ └── sample.js
├── component.js
├── dev.js
└── redux-setup.js
├── .gitignore
├── .npmignore
├── .babelrc
├── test
└── test.spec.js
├── .gitconfig
├── index.tpl.html
├── devserver.js
├── README.md
├── .webpack.config.js
├── webpack.config.js
├── customize.js
├── .package.json
└── package.json
/src/index.js:
--------------------------------------------------------------------------------
1 | export BaseComponent from './component'
2 |
--------------------------------------------------------------------------------
/src/reducers/index.js:
--------------------------------------------------------------------------------
1 | export sample from './sample'
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.sw*
2 | node_modules
3 | dist
4 | lib
5 | es
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | *.sw*
2 | .gitconfig
3 | .package.json
4 | .webpack.config.js
5 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react", "babel-preset-stage-0"]
3 | }
4 |
--------------------------------------------------------------------------------
/test/test.spec.js:
--------------------------------------------------------------------------------
1 | import expect from 'expect'
2 |
3 | describe('Test should run', ()=>{
4 | it('should add 1 and 1', ()=>{
5 | expect(1+1).toBe(2);
6 | });
7 | });
8 |
--------------------------------------------------------------------------------
/src/component.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | class BaseComponent extends React.Component {
4 | render(){
5 | return
Hello, world!
6 | }
7 | }
8 |
9 | export default BaseComponent;
10 |
--------------------------------------------------------------------------------
/src/reducers/sample.js:
--------------------------------------------------------------------------------
1 | import { handleActions } from 'redux-actions'
2 |
3 | export default handleActions({
4 | 'sample': (state, action)=>{
5 | return state;
6 | }
7 | }, 'this is only a sample reducer!');
8 |
--------------------------------------------------------------------------------
/.gitconfig:
--------------------------------------------------------------------------------
1 | [core]
2 | repositoryformatversion = 0
3 | filemode = true
4 | bare = false
5 | logallrefupdates = true
6 | ignorecase = true
7 | precomposeunicode = true
8 | [remote "origin"]
9 | url = https://github.com/calvinfroedge/react-redux-workbench.git
10 | fetch = +refs/heads/*:refs/remotes/origin/*
11 | [branch "master"]
12 | remote = origin
13 | merge = refs/heads/master
14 |
--------------------------------------------------------------------------------
/src/dev.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import { BaseComponent } from './index';
4 |
5 | //Redux
6 | import {DevTools, store} from './redux-setup.js';
7 | import { Provider } from 'react-redux';
8 |
9 | ReactDOM.render(
10 |
11 |
12 |
13 |
14 |
15 |
16 | , document.getElementById('root')
17 | );
18 |
--------------------------------------------------------------------------------
/index.tpl.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | react-kickstart
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/redux-setup.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | //Redux DevTools
4 | import { createDevTools } from 'redux-devtools';
5 | import LogMonitor from 'redux-devtools-log-monitor';
6 | import DockMonitor from 'redux-devtools-dock-monitor';
7 |
8 | //Redux
9 | import { applyMiddleware, compose, createStore, combineReducers } from 'redux';
10 |
11 | //Reducers
12 | import * as reducers from './reducers/index';
13 |
14 | //Set up Redux Middleware
15 | const reducer = combineReducers({
16 | ...reducers
17 | })
18 |
19 | //Set up Dev Tools
20 | const DevTools = createDevTools(
21 |
23 |
24 |
25 | )
26 |
27 | //Create the store
28 | const finalCreateStore = compose(
29 | DevTools.instrument()
30 | )(createStore);
31 |
32 | const store = finalCreateStore(reducer);
33 |
34 | //Exports
35 | export default store;
36 | export {DevTools, store}
37 |
--------------------------------------------------------------------------------
/devserver.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import express from 'express';
3 | import webpack from 'webpack';
4 | import webpackMiddleware from 'webpack-dev-middleware';
5 | import webpackHotMiddleware from 'webpack-hot-middleware';
6 | import config from './webpack.config.js';
7 |
8 | const port = process.env.PORT ? process.env.PORT : 3000;
9 | const app = express();
10 | const compiler = webpack(config);
11 | const middleware = webpackMiddleware(compiler, {
12 | publicPath: config.output.publicPath,
13 | contentBase: 'src',
14 | stats: {
15 | colors: true,
16 | hash: false,
17 | timings: true,
18 | chunks: false,
19 | chunkModules: false,
20 | modules: false
21 | }
22 | });
23 |
24 | app.use(middleware);
25 | app.use(webpackHotMiddleware(compiler));
26 | app.get('*', (req, res)=>{
27 | res.write(middleware.fileSystem.readFileSync(path.join(__dirname, 'dist/index.html')));
28 | res.end();
29 | });
30 |
31 | app.listen(port, '0.0.0.0', (err)=>{
32 | if (err) {
33 | console.log(err);
34 | }
35 | console.info('==> 🌎 Listening on port %s. Open up http://0.0.0.0:%s/ in your browser.', port, port);
36 | });
37 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Motivation
2 |
3 | This project was borne out of the need to quickly spin up a new environment for authoring React + Redux components.
4 |
5 | The hope is that you can essentially run `npm install && npm run development` and have a work panel with hot reloading for building your component interactively.
6 |
7 | `react`, `webpack`, and `redux` are all used. Running `npm run development` starts a webpack dev server, and you can get to work building out your component!
8 |
9 | When you're ready to run tests, you can run `npm test`.
10 |
11 | If you want to customize the project to point at your github / npm repo, after `npm install` just customize this readme, clear out git commits from this project:
12 |
13 | ```
14 | rm -rf .git
15 | git init
16 | git add .
17 | ```
18 |
19 | ...and
20 |
21 | ```
22 | npm install
23 | ```
24 |
25 | and run...
26 |
27 | ```js
28 | PROJECT_NAME=foo-bar PROJECT_DESCRIPTION='A really cool project' GITHUB_USERNAME=foo AUTHOR_NAME="Calvin Froedge" AUTHOR_EMAIL=calvinfroedge@gmail.com npm run customize
29 | ```
30 |
31 | # Important Commands
32 |
33 | ## `npm test`
34 |
35 | Run tests (files in test folder named `TESTNAME.spec.js`) using mocha / expect.
36 |
37 | ## `npm build`
38 |
39 | Builds for es, commonjs, umd. This is ignored in git, but will be included in npm package.
40 |
41 | ## `npm run development`
42 |
43 | Starts the dev server. Go to `localhost:3000` to see your new component with live reload. You can pass `PORT` environment variable to customize this.
44 |
45 | # When you're ready to publish...
46 |
47 | Make sure you clean up the files you don't need! Here's a quick command:
48 |
49 | `rm .gitconfig .webpack.config.js .package.json`
50 |
--------------------------------------------------------------------------------
/.webpack.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var webpack = require('webpack')
4 | var path = require('path')
5 | var HtmlWebpackPlugin = require('html-webpack-plugin')
6 |
7 | var env = process.env.NODE_ENV;
8 |
9 | var config = {
10 | module: {
11 | loaders: [
12 | { test: /\.js$/, loaders: ['babel-loader'], exclude: /node_modules/ },
13 | { test: /\.json?$/, loader: 'json' },
14 | { test: /\.css$/, loader: 'style!css?modules&localIdentName=[name]---[local]---[hash:base64:5]' },
15 | { test: /\.less$/, loader: "style!css!less" }
16 | ]
17 | },
18 | plugins: [
19 | new webpack.optimize.OccurenceOrderPlugin(),
20 | new webpack.DefinePlugin({
21 | 'process.env.NODE_ENV': JSON.stringify(env)
22 | })
23 | ]
24 | };
25 |
26 | if(env === 'build'){
27 | config.output = {
28 | library: 'ReactReduxWorkbench',
29 | libraryTarget: 'umd'
30 | }
31 | } else if(env === 'development'){
32 | config.devtool = 'eval-source-map';
33 |
34 | config.entry = [
35 | 'webpack-hot-middleware/client?reload=true',
36 | path.join(__dirname, 'src/dev.js')
37 | ];
38 |
39 | config.output = {
40 | path: path.join(__dirname, '/dist/'),
41 | filename: 'react-redux-workbench.js',
42 | publicPath: '/'
43 | };
44 |
45 | config.plugins = config.plugins.concat([
46 | new HtmlWebpackPlugin({
47 | template: 'index.tpl.html',
48 | inject: 'body',
49 | filename: 'index.html'
50 | }),
51 | new webpack.HotModuleReplacementPlugin(),
52 | new webpack.NoErrorsPlugin()
53 | ]);
54 | } else if (env === 'production') {
55 | config.plugins.push(
56 | new webpack.optimize.UglifyJsPlugin({
57 | compressor: {
58 | pure_getters: true,
59 | unsafe: true,
60 | unsafe_comps: true,
61 | screw_ie8: true,
62 | warnings: false
63 | }
64 | })
65 | )
66 | }
67 |
68 | module.exports = config
69 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var webpack = require('webpack')
4 | var path = require('path')
5 | var HtmlWebpackPlugin = require('html-webpack-plugin')
6 |
7 | var env = process.env.NODE_ENV;
8 |
9 | var config = {
10 | module: {
11 | loaders: [
12 | { test: /\.js$/, loaders: ['babel-loader'], exclude: /node_modules/ },
13 | { test: /\.json?$/, loader: 'json' },
14 | { test: /\.css$/, loader: 'style!css?modules&localIdentName=[name]---[local]---[hash:base64:5]' },
15 | { test: /\.less$/, loader: "style!css!less" }
16 | ]
17 | },
18 | plugins: [
19 | new webpack.optimize.OccurenceOrderPlugin(),
20 | new webpack.DefinePlugin({
21 | 'process.env.NODE_ENV': JSON.stringify(env)
22 | })
23 | ]
24 | };
25 |
26 | if(env === 'build'){
27 | config.output = {
28 | library: 'ReactReduxWorkbench',
29 | libraryTarget: 'umd'
30 | }
31 | } else if(env === 'development'){
32 | config.devtool = 'eval-source-map';
33 |
34 | config.entry = [
35 | 'webpack-hot-middleware/client?reload=true',
36 | path.join(__dirname, 'src/dev.js')
37 | ];
38 |
39 | config.output = {
40 | path: path.join(__dirname, '/dist/'),
41 | filename: 'react-redux-workbench.js',
42 | publicPath: '/'
43 | };
44 |
45 | config.plugins = config.plugins.concat([
46 | new HtmlWebpackPlugin({
47 | template: 'index.tpl.html',
48 | inject: 'body',
49 | filename: 'index.html'
50 | }),
51 | new webpack.HotModuleReplacementPlugin(),
52 | new webpack.NoErrorsPlugin()
53 | ]);
54 | } else if (env === 'production') {
55 | config.plugins.push(
56 | new webpack.optimize.UglifyJsPlugin({
57 | compressor: {
58 | pure_getters: true,
59 | unsafe: true,
60 | unsafe_comps: true,
61 | screw_ie8: true,
62 | warnings: false
63 | }
64 | })
65 | )
66 | }
67 |
68 | module.exports = config
69 |
--------------------------------------------------------------------------------
/customize.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 |
3 | let { PROJECT_NAME, PROJECT_DESCRIPTION, GITHUB_USERNAME, AUTHOR_NAME, AUTHOR_EMAIL } = process.env;
4 |
5 | if(!PROJECT_NAME || !PROJECT_DESCRIPTION || !GITHUB_USERNAME || !AUTHOR_NAME || !AUTHOR_EMAIL){
6 | console.error('Must provide PROJECT_NAME, PROJECT_DESCRIPTION, GITHUB_USERNAME, AUTHOR_NAME, AUTHOR_EMAIL as environment variables!');
7 | process.exit();
8 | }
9 |
10 | RegExp.quote = function(str) {
11 | return str.replace(/([.?*+^$[\]\\(){}-])/g, "\\$1");
12 | };
13 |
14 | String.prototype.replaceAll = function(search, replace)
15 | {
16 | var re = new RegExp(RegExp.quote(search),"g");
17 | return this.replace(re, replace);
18 | };
19 |
20 | let oldName = 'react-redux-workbench';
21 | let packageJSON = fs.readFileSync('./.package.json').toString();
22 | let oldVersion = '"version": "'+JSON.parse(packageJSON).version+'"';
23 | let newVersion = '"version": "0.0.1"';
24 | let gitConfig = fs.readFileSync('./.gitconfig').toString();
25 | let webpackConfig = fs.readFileSync('./.webpack.config.js').toString();
26 | let projectName = PROJECT_NAME;
27 | let repo = [GITHUB_USERNAME, `${projectName}`].join('/');
28 | let gitConfigNew = gitConfig.replaceAll(`calvinfroedge/${oldName}`, repo);
29 | let file = projectName.replaceAll(' ', '-').toLowerCase();
30 | let packageJSONNEW = packageJSON.replaceAll(oldName, file).replaceAll('Calvin Froedge', AUTHOR_NAME).replaceAll('calvinfroedge@gmail.com', AUTHOR_EMAIL).replaceAll('description-customize-me', PROJECT_DESCRIPTION).replaceAll(oldVersion, newVersion);
31 | let webpackConfigNEW = webpackConfig.replaceAll('ReactReduxWorkbench', projectName.replaceAll(' ', '')).replaceAll(oldName, file);
32 | fs.writeFileSync('./.git/config', gitConfigNew);
33 | fs.writeFileSync('./package.json', packageJSONNEW);
34 | fs.writeFileSync('./webpack.config.js', webpackConfigNEW);
35 | console.info('Wrote updates to package.json, .git/config, and wepback.config.js.\n');
36 |
--------------------------------------------------------------------------------
/.package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-redux-workbench",
3 | "version": "0.0.1",
4 | "description": "description-customize-me",
5 | "main": "lib/index.js",
6 | "jsnext:main": "es/index.js",
7 | "scripts": {
8 | "clean": "rimraf lib dist es",
9 | "test": "cross-env NODE_ENV=build BABEL_ENV=commonjs mocha --compilers js:babel-register --recursive",
10 | "build:commonjs": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=commonjs ./node_modules/babel-cli/bin/babel.js src --out-dir lib",
11 | "build:es": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=es ./node_modules/babel-cli/bin/babel.js src --out-dir es",
12 | "build:umd": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=commonjs NODE_ENV=build ./node_modules/webpack/bin/webpack.js src/index.js dist/react-redux-workbench.js",
13 | "build:umd:min": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=commonjs NODE_ENV=production ./node_modules/webpack/bin/webpack.js src/index.js dist/react-redux-workbench.min.js",
14 | "build": "NODE_ENV=build npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min",
15 | "customize": "./node_modules/babel-cli/bin/babel-node.js customize.js",
16 | "development": "NODE_ENV=development nodemon devserver.js --ignore src/ --exec ./node_modules/babel-cli/bin/babel-node.js",
17 | "prepublish": "npm run clean && npm run build"
18 | },
19 | "repository": {
20 | "type": "git",
21 | "url": "git+https://github.com/calvinfroedge/react-redux-workbench.git"
22 | },
23 | "keywords": [
24 | "react",
25 | "redux",
26 | "helpers",
27 | "state",
28 | "modifiers"
29 | ],
30 | "author": "Calvin Froedge ",
31 | "license": "MIT",
32 | "bugs": {
33 | "url": "https://github.com/calvinfroedge/react-redux-workbench/issues"
34 | },
35 | "homepage": "https://github.com/calvinfroedge/react-redux-workbench#readme",
36 | "dependencies": {
37 | "html-webpack-plugin": "^2.16.0",
38 | "webpack-hot-middleware": "^2.10.0"
39 | },
40 | "devDependencies": {
41 | "babel-cli": "^6.7.5",
42 | "babel-core": "^6.7.4",
43 | "babel-loader": "^6.2.4",
44 | "babel-plugin-transform-runtime": "^6.6.0",
45 | "babel-preset-es2015": "^6.6.0",
46 | "babel-preset-react": "^6.5.0",
47 | "babel-preset-stage-0": "^6.5.0",
48 | "babel-register": "^6.7.2",
49 | "cross-env": "^1.0.7",
50 | "expect": "^1.16.0",
51 | "express": "^4.13.4",
52 | "jsdom": "^8.1.0",
53 | "mocha": "^2.4.5",
54 | "mocha-jsdom": "^1.1.0",
55 | "react": "^15.0.1",
56 | "react-dom": "^15.0.1",
57 | "react-redux": "^4.4.5",
58 | "redux": "^3.4.0",
59 | "redux-actions": "^0.9.1",
60 | "redux-devtools": "^3.2.0",
61 | "redux-devtools-dock-monitor": "^1.1.1",
62 | "redux-devtools-log-monitor": "^1.0.11",
63 | "rimraf": "^2.5.2",
64 | "webpack": "^1.12.14",
65 | "webpack-dev-middleware": "^1.6.1"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-redux-workbench",
3 | "version": "0.0.5",
4 | "description": "Get your react + redux components off the ground faster",
5 | "main": "lib/index.js",
6 | "jsnext:main": "es/index.js",
7 | "scripts": {
8 | "clean": "rimraf lib dist es",
9 | "test": "cross-env NODE_ENV=build BABEL_ENV=commonjs mocha --compilers js:babel-register --recursive",
10 | "build:commonjs": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=commonjs ./node_modules/babel-cli/bin/babel.js src --out-dir lib",
11 | "build:es": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=es ./node_modules/babel-cli/bin/babel.js src --out-dir es",
12 | "build:umd": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=commonjs NODE_ENV=build ./node_modules/webpack/bin/webpack.js src/index.js dist/react-redux-workbench.js",
13 | "build:umd:min": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=commonjs NODE_ENV=production ./node_modules/webpack/bin/webpack.js src/index.js dist/react-redux-workbench.min.js",
14 | "build": "NODE_ENV=build npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min",
15 | "customize": "./node_modules/babel-cli/bin/babel-node.js customize.js",
16 | "development": "NODE_ENV=development nodemon devserver.js --ignore src/ --exec ./node_modules/babel-cli/bin/babel-node.js",
17 | "prepublish": "npm run clean && npm run build"
18 | },
19 | "repository": {
20 | "type": "git",
21 | "url": "git+https://github.com/calvinfroedge/react-redux-workbench.git"
22 | },
23 | "keywords": [
24 | "react",
25 | "redux",
26 | "helpers",
27 | "state",
28 | "modifiers"
29 | ],
30 | "author": "Calvin Froedge ",
31 | "license": "MIT",
32 | "bugs": {
33 | "url": "https://github.com/calvinfroedge/react-redux-workbench/issues"
34 | },
35 | "homepage": "https://github.com/calvinfroedge/react-redux-workbench#readme",
36 | "dependencies": {
37 | "html-webpack-plugin": "^2.16.0",
38 | "webpack-hot-middleware": "^2.10.0"
39 | },
40 | "devDependencies": {
41 | "babel-cli": "^6.7.5",
42 | "babel-core": "^6.7.4",
43 | "babel-loader": "^6.2.4",
44 | "babel-plugin-transform-runtime": "^6.6.0",
45 | "babel-preset-es2015": "^6.6.0",
46 | "babel-preset-react": "^6.5.0",
47 | "babel-preset-stage-0": "^6.5.0",
48 | "babel-register": "^6.7.2",
49 | "cross-env": "^1.0.7",
50 | "expect": "^1.16.0",
51 | "express": "^4.13.4",
52 | "jsdom": "^8.1.0",
53 | "mocha": "^2.4.5",
54 | "mocha-jsdom": "^1.1.0",
55 | "react": "^15.0.1",
56 | "react-dom": "^15.0.1",
57 | "react-redux": "^4.4.5",
58 | "redux": "^3.4.0",
59 | "redux-actions": "^0.9.1",
60 | "redux-devtools": "^3.2.0",
61 | "redux-devtools-dock-monitor": "^1.1.1",
62 | "redux-devtools-log-monitor": "^1.0.11",
63 | "rimraf": "^2.5.2",
64 | "webpack": "^1.12.14",
65 | "webpack-dev-middleware": "^1.6.1"
66 | }
67 | }
68 |
--------------------------------------------------------------------------------