├── .babelrc
├── .eslintrc
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── index.html
├── package.json
├── site
├── bundle.js
├── bundle.js.map
└── src
│ ├── Root.js
│ └── index.js
├── src
├── LinkContainer.js
├── Sidebar.js
├── SidebarItem.js
├── SidebarSelector.js
└── index.js
├── tools
├── build.sh
└── devServer.js
├── webpack.config.js
└── webpack.config.prod.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "react", "stage-0"],
3 | "env": {
4 | "development": {
5 | "plugins": ["react-hot-loader/babel"]
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /dist
3 | npm-debug.log
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | /example
2 | /node_modules
3 | /src
4 | /config
5 | /site
6 | .babelrc
7 | webpack.config.js
8 | .gitignore
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2016 Gregory Chamberlain
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5 |
6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7 |
8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-responsive-sidebar [](https://badge.fury.io/js/react-responsive-sidebar)
2 |
3 | A simple and elegant responsive sidebar component for react
4 |
5 | [Sidebar](#sidebar)
6 | [SidebarItem](#sidebaritem)
7 |
8 | ## Getting Started
9 | This component works best as the outer most visual component in your app. You may wrap it in data container components, but it is not suggested to nest it within other visual elements for the time being.
10 |
11 | ```javascript
12 | import React from 'react';
13 | import { render } from 'react-dom';
14 | import { Sidebar, SidebarItem } from 'react-responsive-sidebar';
15 | import YourAppContent from 'path/to/your/app/content'
16 |
17 | const items = [
18 | Dashboard,
19 | Profile,
20 | Settings,
21 | ];
22 |
23 | render (
24 |
25 |
26 |
27 | , document.findElementById("render-target"))
28 | ```
29 |
30 | ## Sidebar
31 |
32 | |Property |Type |Default|Description|
33 | | -------- | ---- | ----- | --------- |
34 | |background|string|#009688|background color of the sidebar|
35 | |color|string|#fff|text color for sidebar items|
36 | |backdrop|bool|true|show a backdrop when sidebar is opened from collapsed state|
37 | |closeOnBackdropClick|bool|true|closes the sidebar when the backdrop is clicked|
38 | |width|number|300|width of sidebar|
39 | |breakPoint|number|980|breakpoint where the sidebar collapses (px)|
40 | |toggleIconSize|number|28|size of the toggle icon (px)|
41 | |toggleIconColor|string|background|color of the icon that toggles the sidebar|
42 | |content|array|n/a|content to fill the sidebar with (SidebarItem, SidebarSelector)|
43 | |onCollapse|func|n/a|A function to call when the sidebar collapses/expands. Provides a boolean, true if collapsed, false if expanded.|
44 | |onOpen|func|n/a|A function to call when the sidebar is toggle. Provides a boolean, true of opened, false if closed.|
45 | |onItemSelected|func|n/a|A function to call when an item is selected. will provide selected items props.|
46 | |closeOnItemSelect|bool|true|Sets if the sidebar close when an item is selected|
47 | |hoverHighlight|string|rgba(255,255,255,0.15)|Sets hoverHighlight prop on each item, unless directly specified on the item|
48 | |activeHightlight|string|rgba(255,255,255,0.2)|Sets activeHightlight prop on each item, unless directly specified on the item|
49 |
50 | ## SidebarItem
51 |
52 | |Property |Type |Default|Description|
53 | | -------- |:----:|:-----:| --------- |
54 | |background|string|sidebar.background|background color, inherited from sidebar if not set manually|
55 | |color|string|white|text and icon color|
56 | |href|string|n/a|where to go on click, react-router compatible but not required|
57 | |leftIcon|element|n/a|Icon used for the left side of the item. (react-icons is a great package for this)|
58 | |rightIcon|element|n/a|Icon used for the right side of the item. (react-icons is a great package for this)|
59 | |textAlign|string|left|alignment of the title within the item|
60 | |hoverHighlight|string|rgba(255,255,255,0.15)|Background color of the item when hovered over|
61 | |activeHightlight|string|rgba(255,255,255,0.2)|Background color of the item when in the active state (At its href)|
62 | |onClick|func|n/a|a function to call when the item is clicked|
63 |
64 |
68 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | React Responsive Sidebar
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-responsive-sidebar",
3 | "version": "0.1.16",
4 | "description": "A simple responsive sidebar component for React",
5 | "keywords": [
6 | "react",
7 | "react-component",
8 | "sidebar",
9 | "responsive"
10 | ],
11 | "main": "lib/index.js",
12 | "scripts": {
13 | "start": "node tools/devServer.js",
14 | "build": "NODE_ENV=production ./tools/build.sh",
15 | "buildSite": "NODE_ENV=production webpack --config webpack.config.prod.js --progress",
16 | "prepublish": "npm run build"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "git+https://github.com/gregchamberlain/react-responsive-sidebar.git"
21 | },
22 | "author": "Greg Chamberlain (https://gregchamberlain.github.io)",
23 | "license": "ISC",
24 | "bugs": {
25 | "url": "https://github.com/gregchamberlain/react-responsive-sidebar/issues"
26 | },
27 | "homepage": "https://github.com/gregchamberlain/react-responsive-sidebar#readme",
28 | "devDependencies": {
29 | "babel-core": "^6.5.2",
30 | "babel-eslint": "^6.1.2",
31 | "babel-loader": "^6.2.3",
32 | "babel-preset-es2015": "^6.5.0",
33 | "babel-preset-react": "^6.5.0",
34 | "babel-preset-react-hmre": "^1.1.0",
35 | "babel-preset-stage-0": "^6.5.0",
36 | "eslint": "^3.3.0",
37 | "eslint-config-airbnb": "^10.0.1",
38 | "eslint-plugin-babel": "^3.3.0",
39 | "eslint-plugin-import": "^1.13.0",
40 | "eslint-plugin-jsx-a11y": "^2.1.0",
41 | "eslint-plugin-react": "^6.0.0",
42 | "express": "^4.14.0",
43 | "hjs-webpack": "^7.2.1",
44 | "react-dom": "^15.3.0",
45 | "react-hot-loader": "^3.0.0-beta.6",
46 | "react-router": "^2.6.1",
47 | "webpack": "^1.14.0",
48 | "webpack-dev-middleware": "^1.8.4",
49 | "webpack-hot-middleware": "^2.13.2"
50 | },
51 | "dependencies": {
52 | "color": "^0.11.3",
53 | "radium": "^0.18.1",
54 | "react": "^15.3.0",
55 | "react-icons": "^2.2.1"
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/site/bundle.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"bundle.js","sources":["webpack:///bundle.js"],"mappings":"AAAA;AAmvIA;;;;;;;;;;;;;;AAsvHA;AAsmGA;AA8tIA;;;;;;AAioBA;AAokFA;;;;;AA6mDA;;;;;AAu0BA;AAkkEA;AAszHA;AAwvHA;AAmiIA","sourceRoot":""}
--------------------------------------------------------------------------------
/site/src/Root.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Dashboard from 'react-icons/lib/fa/dashboard';
3 | import User from 'react-icons/lib/fa/user';
4 | import Gear from 'react-icons/lib/fa/cog';
5 | import { Sidebar, SidebarItem } from '../../src';
6 | import { Router, Route, browserHistory } from 'react-router'
7 |
8 | let items = [
9 | }
11 | href="https://gregchamberlain.github.io" >
12 | Test
13 | ,
14 | }
16 | href="/dashboard" >
17 | Dashboard
18 | ,
19 | } href="/profile">
20 | Profile
21 | ,
22 | } href="/settings">
23 | Settings
24 | ,
25 | ];
26 |
27 | let toolbarStyle = {
28 | display: "absolute",
29 | top: 0,
30 | left: 0,
31 | right: 0,
32 | height: 56,
33 | background: '#444',
34 | }
35 |
36 | const App = (props) => {props.children};
37 | const DashPage = (props) => ;
38 | const ProfilePage = (props) => Profile
;
39 | const SettingsPage = (props) => Settings
;
40 |
41 | const Root = () => (
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | );
50 |
51 | export default Root;
52 |
--------------------------------------------------------------------------------
/site/src/index.js:
--------------------------------------------------------------------------------
1 | import { AppContainer } from 'react-hot-loader';
2 | import React from 'react';
3 | import { render } from 'react-dom';
4 |
5 | import Root from './Root';
6 |
7 | const rootEl = document.getElementById('root');
8 | render(
9 |
10 |
11 | ,
12 | rootEl
13 | );
14 |
15 | if (module.hot) {
16 | module.hot.accept('./Root', () => {
17 | // If you use Webpack 2 in ES modules mode, you can
18 | // use here rather than require() a .
19 | const NextRoot = require('./Root').default;
20 | render(
21 |
22 |
23 | ,
24 | rootEl
25 | );
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/src/LinkContainer.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import Radium from 'radium';
3 |
4 | class LinkContainer extends Component {
5 |
6 | constructor(props) {
7 | super(props)
8 | this.state = {
9 | active: true,
10 | }
11 | }
12 |
13 | onClick = () => {
14 | this.props.onClick(this.props);
15 | if (!this.props.href) { return }
16 | if (this.props.href.indexOf("http") === 0) {
17 | window.location = this.props.href;
18 | return;
19 | }
20 | if (this.context.router) {
21 | this.context.router.push(this.props.href);
22 | } else {
23 | window.location = this.props.href;
24 | }
25 | }
26 |
27 | render() {
28 |
29 | const active = window.location.pathname === this.props.href
30 |
31 | const styles = getStyles(this.props, active)
32 |
33 | return (
34 |
35 |
36 | {this.props.children}
37 |
38 |
39 | );
40 | }
41 | }
42 |
43 | LinkContainer.propTypes = {
44 | href: PropTypes.string,
45 | onClick: PropTypes.func,
46 | style: PropTypes.object,
47 | hoverHighlight: PropTypes.string,
48 | activeHightlight: PropTypes.string,
49 | };
50 |
51 | LinkContainer.defaultProps = {
52 | onClick: () => {},
53 | style: {},
54 | };
55 |
56 | LinkContainer.contextTypes = {
57 | router: React.PropTypes.object,
58 | };
59 |
60 | const getStyles = (props, active) => {
61 | return {
62 | container: {
63 | cursor: 'pointer',
64 | width: '100%',
65 | height: '100%',
66 | background: active ? props.activeHighlight || 'rgba(0, 0, 0, 0.2)' : null,
67 | ':hover': {
68 | background: props.hoverHighlight || 'rgba(0, 0, 0, 0.15)'
69 | },
70 | },
71 | }
72 | }
73 |
74 | export default Radium(LinkContainer);
75 |
--------------------------------------------------------------------------------
/src/Sidebar.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import Radium from 'radium';
3 | import Bars from 'react-icons/lib/fa/bars';
4 | import LeftArrow from 'react-icons/lib/fa/chevron-left';
5 |
6 | class Sidebar extends Component {
7 |
8 | constructor(props) {
9 | super(props);
10 | this.state = {
11 | collapsed: window.innerWidth <= this.props.breakPoint,
12 | open: false,
13 | };
14 | props.onCollapse(this.state.collapsed);
15 | window.onkeyup = this.onKeyUp
16 | this._toggle = this._toggle.bind(this);
17 | this._handleResize = this._handleResize.bind(this);
18 | this._close = this._close.bind(this);
19 | }
20 |
21 | onKeyUp = (e) => {
22 | let code = e.keyCode ? e.keyCode : e.which;
23 | if (code === 27 && this.state.collapsed && this.state.open) {
24 | this._close();
25 | }
26 | }
27 |
28 | componentDidMount() {
29 | window.addEventListener('resize', this._handleResize);
30 | }
31 |
32 | componentWillUnmount() {
33 | window.removeEventListener('resize', this._handleResize);
34 | }
35 |
36 | _handleResize(e) {
37 | if (window.innerWidth <= this.props.breakPoint && !this.state.collapsed) {
38 | this.props.onCollapse(true)
39 | this.setState({collapsed: true});
40 | }else if(window.innerWidth > this.props.breakPoint && this.state.collapsed){
41 | this.props.onCollapse(false)
42 | this.setState({collapsed: false});
43 | }
44 | }
45 |
46 | onItemSelected = (props) => {
47 | this.props.onItemSelected(props)
48 | if (this.props.closeOnItemSelect) { this._close() };
49 | }
50 |
51 | _close() {
52 | this.setState({open: false});
53 | this.props.onToggle(false);
54 | }
55 |
56 | _toggle() {
57 | const open = !this.state.open;
58 | this.setState({open: open});
59 | this.props.onToggle(open)
60 | }
61 |
62 | render() {
63 |
64 | const styles = getStyles(this.props, this.state);
65 | const _toggleIcon = this.state.open ? : ;
66 | const content = this.props.content.map((el, idx) => React.cloneElement(el, {
67 | key: idx,
68 | hoverHighlight: el.props.hoverHighlight || this.props.hoverHighlight,
69 | activeHighlight: el.props.activeHighlight || this.props.activeHighlight,
70 | onClick: this.onItemSelected,
71 | }));
72 | // const content = React.Children.map(this.props.content, React.cloneElement(item, {
73 | // hoverHighlight: item.props.hoverHighlight || this.props.hoverHighlight,
74 | // activeHighlight: item.props.activeHighlight || this.props.activeHighlight,
75 | // }));
76 |
77 | return (
78 |
79 | {/*Renders the children as the main content*/}
80 |
{this.props.children}
81 | {/*Renders the Backdrop when the drawn is collapsed and opened*/}
82 | {this.props.backdrop ?
83 |
: ""
84 | }
85 | {/*Renders the Sidebar with given input array children*/}
86 |
{content}
87 |
{_toggleIcon}
88 |
89 | );
90 | }
91 | }
92 |
93 | let iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
94 |
95 | Sidebar.propTypes = {
96 | background: PropTypes.string,
97 | color: PropTypes.string,
98 | backdrop: PropTypes.bool,
99 | closeOnBackdropClick: PropTypes.bool,
100 | width: PropTypes.number,
101 | breakPoint: PropTypes.number,
102 | toggleIconSize: PropTypes.number,
103 | toggleIconColor: PropTypes.string,
104 | content: PropTypes.arrayOf(PropTypes.element),
105 | textAlign: PropTypes.string,
106 | hoverHighlight: PropTypes.string,
107 | activeHightlight: PropTypes.string,
108 | onItemSelected: PropTypes.func,
109 | onCollapse: PropTypes.func,
110 | onToggle: PropTypes.func,
111 | closeOnItemSelect: PropTypes.bool,
112 | };
113 |
114 | Sidebar.defaultProps = {
115 | width: 300,
116 | background: '#009688',
117 | color: '#fff',
118 | breakPoint: 980,
119 | toggleIconSize: 28,
120 | content: [],
121 | backdrop: true,
122 | closeOnBackdropClick: true,
123 | closeOnItemSelect: true,
124 | onItemSelected: () => {},
125 | onCollapse: () => {},
126 | onToggle: () => {},
127 | };
128 |
129 | let getStyles = (props, state) => {
130 | return {
131 | sidebar: {
132 | position: 'absolute',
133 | left: !state.collapsed || state.open ? 0 : -props.width,
134 | top: 0,
135 | bottom: 0,
136 | overflowX: 'hidden',
137 | overflowY: iOS ? 'scroll' : 'auto',
138 | WebkitOverflowScrolling: "touch",
139 | textAlign: props.textAlign,
140 | width: props.width,
141 | background: props.background,
142 | color: props.color,
143 | transition: 'left .25s ease-in',
144 | },
145 | content: {
146 | position: 'absolute',
147 | left: state.collapsed ? 0 : props.width,
148 | top: 0,
149 | right: 0,
150 | bottom: 0,
151 | overflow: iOS ? 'scroll' : 'auto',
152 | WebkitOverflowScrolling: "touch",
153 | transition: 'left .25s ease-in',
154 | },
155 | toggle: {
156 | position: 'absolute',
157 | display: "flex",
158 | alignItems: "center",
159 | justifyContent: "center",
160 | fontSize: props.toggleIconSize,
161 | width: (props.toggleIconSize * 2),
162 | height: (props.toggleIconSize * 2),
163 | top: state.collapsed ? 0 : -999,
164 | left: state.open ? props.width : 0,
165 | opacity: state.collapsed ? 1 : 0,
166 | cursor: 'pointer',
167 | color: props.toggleIconColor || props.background,
168 | transition: 'left .25s ease-in,opacity .5s .5s ease-in',
169 | },
170 | backdrop: {
171 | position: 'absolute',
172 | visibility: state.collapsed && state.open ? "visible" : "hidden",
173 | background: 'black',
174 | opacity: state.collapsed && state.open ? 0.3 : 0,
175 | left: 0,
176 | top: 0,
177 | right: 0,
178 | bottom: 0,
179 | overflow: 'hidden',
180 | transition: 'left .25s ease-in,opacity .5s ease-in, visibility .5s',
181 | },
182 | };
183 | };
184 |
185 |
186 |
187 | export default Radium(Sidebar);
188 |
--------------------------------------------------------------------------------
/src/SidebarItem.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import LinkContainer from './LinkContainer';
3 | import color from 'color';
4 | import Radium from 'radium'
5 |
6 | class SidebarItem extends Component {
7 |
8 | render() {
9 |
10 | const styles = getStyles(this.props);
11 |
12 | const { leftIcon, rightIcon, children, onClick, href } = this.props
13 |
14 | return (
15 |
21 |
22 | {leftIcon}
23 |
{children}
24 | {rightIcon}
25 |
26 |
27 | )
28 | }
29 | }
30 |
31 | SidebarItem.propTypes = {
32 | background: PropTypes.string,
33 | color: PropTypes.string,
34 | href: PropTypes.string,
35 | leftIcon: PropTypes.element,
36 | rightIcon: PropTypes.element,
37 | textAlign: PropTypes.string,
38 | hoverHighlight: PropTypes.string,
39 | activeHightlight: PropTypes.string,
40 | onClick: PropTypes.func,
41 | }
42 |
43 | SidebarItem.contextTypes = {
44 | router: React.PropTypes.object
45 | }
46 |
47 | const getStyles = (props) => {
48 | return {
49 | container: {
50 | background: props.background,
51 | color: props.color,
52 | fontSize: props.type === "header" ? '14px' : '18px',
53 | fontWeight: 700,
54 | },
55 | content: {
56 | display: 'flex',
57 | alignItems: 'center',
58 | padding: 15,
59 | boxSizing: 'border-box',
60 | },
61 | text: {
62 | flexGrow: 1,
63 | margin: '0px 15px',
64 | textAlign: props.textAlign,
65 | },
66 | }
67 | }
68 |
69 | export default Radium(SidebarItem);
70 |
--------------------------------------------------------------------------------
/src/SidebarSelector.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import SidebarItem from './SidebarItem'
3 | import CaretDown from 'react-icons/lib/fa/caret-down'
4 | import CaretUp from 'react-icons/lib/fa/caret-up'
5 |
6 | export default class SidebarSelector extends Component {
7 |
8 | constructor(props) {
9 | super(props)
10 | this.state = {
11 | open: false
12 | }
13 | }
14 |
15 | _select = () => {
16 | this.props.onSelect()
17 | this.setState({open: false})
18 | }
19 |
20 | _toggle = () => {
21 | const open = this.state.open
22 | this.setState({open: !open})
23 | }
24 |
25 | render() {
26 |
27 | const { selected, options } = this.props
28 |
29 | const collapse = options.map((option) => {
30 | if (option.id === selected.id) {
31 | return
32 | }
33 | return (
34 |
40 | )
41 | })
42 |
43 | const icon = this.state.open ? :
44 |
45 | return (
46 |
47 | 1 ? icon : null}
52 | onClick={this._toggle} />
53 | { this.state.open ? collapse : null}
54 |
55 | )
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import SidebarItem from './SidebarItem';
2 | import SidebarSelector from './SidebarSelector';
3 | import Sidebar from './Sidebar';
4 | export {
5 | Sidebar,
6 | SidebarItem,
7 | SidebarSelector,
8 | };
9 |
--------------------------------------------------------------------------------
/tools/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # build minified standalone version in dist
4 | # rm -rf dist
5 | # ./node_modules/.bin/webpack --output-filename=dist/ReactDnD.js
6 | # ./node_modules/.bin/webpack --output-filename=dist/ReactDnD.min.js --optimize-minimize
7 |
8 | # build ES5 modules to lib
9 | rm -rf lib
10 | ./node_modules/.bin/babel src --out-dir lib
11 |
--------------------------------------------------------------------------------
/tools/devServer.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var webpack = require('webpack');
3 | var express = require('express');
4 | var devMiddleware = require('webpack-dev-middleware');
5 | var hotMiddleware = require('webpack-hot-middleware');
6 | var config = require('../webpack.config');
7 |
8 | var app = express();
9 | var compiler = webpack(config);
10 |
11 | app.use(devMiddleware(compiler, {
12 | publicPath: config.output.publicPath,
13 | historyApiFallback: true,
14 | noInfo: true
15 | }));
16 |
17 | app.use(hotMiddleware(compiler));
18 |
19 | app.get('*', function (req, res) {
20 | res.sendFile(path.join(__dirname, '../index.html'));
21 | });
22 |
23 | app.listen(3000, function (err) {
24 | if (err) {
25 | return console.error(err);
26 | }
27 |
28 | console.log('Listening at http://localhost:3000/');
29 | });
30 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var webpack = require('webpack');
3 |
4 | module.exports = {
5 | devtool: 'cheap-module-source-map',
6 | entry: [
7 | 'react-hot-loader/patch',
8 | 'webpack-hot-middleware/client',
9 | './site/src/index.js'
10 | ],
11 | output: {
12 | path: path.join(__dirname, 'site'),
13 | filename: 'bundle.js',
14 | publicPath: '/site/'
15 | },
16 | plugins: [
17 | new webpack.optimize.OccurenceOrderPlugin(),
18 | new webpack.HotModuleReplacementPlugin(),
19 | new webpack.NoErrorsPlugin(),
20 | ],
21 | module: {
22 | loaders: [{
23 | test: /\.js?$/,
24 | loaders: ['babel'],
25 | exclude: /node_modules/
26 | }]
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/webpack.config.prod.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var webpack = require('webpack');
3 |
4 | module.exports = {
5 | devtool: 'cheap-module-source-map',
6 | entry: './site/src/index.js',
7 | output: {
8 | path: path.join(__dirname, 'site'),
9 | filename: 'bundle.js',
10 | },
11 | plugins: [
12 | new webpack.optimize.OccurenceOrderPlugin(),
13 | new webpack.NoErrorsPlugin(),
14 | new webpack.DefinePlugin({
15 | 'process.env':{
16 | 'NODE_ENV': JSON.stringify('production')
17 | }
18 | }),
19 | new webpack.optimize.UglifyJsPlugin({
20 | compress:{
21 | warnings: false
22 | }
23 | })
24 | ],
25 | module: {
26 | loaders: [{
27 | test: /\.js?$/,
28 | loaders: ['babel'],
29 | exclude: /node_modules/
30 | }]
31 | }
32 | };
33 |
--------------------------------------------------------------------------------