├── .gitignore ├── README.md ├── index.html ├── package.json ├── server.js ├── src ├── .babelrc ├── actions │ └── index.js ├── components │ ├── dashboard.js │ ├── navigation.js │ └── table.js ├── containers │ ├── app.js │ ├── dev-tools.js │ ├── page-dashboard.js │ ├── page-not-found.js │ ├── page-table.js │ ├── root.dev.js │ ├── root.js │ └── root.prod.js ├── index.js ├── middleware │ └── index.js ├── reducers │ └── index.js ├── routes.js ├── store │ ├── configure-store.dev.js │ ├── configure-store.js │ └── configure-store.prod.js └── styles │ ├── foundation.scss │ └── index.css └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React-Redux-Foundation Boilerplate 2 | 3 | Minimal Boilerplate for Redux + React + React-Router-Redux and Foundation 4 | 5 | ## Usage 6 | 7 | ``` 8 | npm i 9 | npm start 10 | ``` 11 | 12 | Open [localhost:3000](http://localhost:3000) 13 | 14 | Use `CTRL + H` to toggle the Redux Dock Monitor 15 | 16 | ## What's in it? 17 | 18 | Everything what you need to build an awesome Single Page Application: 19 | 20 | - [x] [Redux](http://redux.js.org/) 21 | - [x] [React](https://facebook.github.io/react/) 22 | - [x] [react-router-redux](https://github.com/rackt/react-router-redux) (formerly known as redux-simple-router) 23 | - no [rackt/history](https://github.com/rackt/history) included anymore! 24 | - [x] [redux-devtools](https://github.com/gaearon/redux-devtools) 25 | - [x] [Webpack](https://webpack.github.io/) 26 | - [x] [PostCSS](http://postcss.org/) with [Autoprefixer](https://github.com/postcss/autoprefixer) 27 | - [x] [Babel](http://babeljs.io/) 28 | - [x] [Foundation Sites](http://foundation.zurb.com/sites/docs/) 29 | - Sass version 30 | 31 | ## Content 32 | 33 | - responsive menu with a subnav 34 | - button to create a callout (formerly known as as alert) 35 | - implemented in redux ([action](./src/actions/index.js), [reducer](./src/reducers/index.js), store) 36 | - [3 routes](./src/routes.js) 37 | - `/` Dashboard 38 | - `/table` just a scrollable foundation table 39 | - `/*` 404 Catching Page 40 | - each container which is mapped to a route is wrapped by the [App](./src/containers/app.js) container 41 | - __App__ loads all important things in a clean way and the proper scope: 42 | - Font Awesome 43 | - jQuery 44 | - what-input 45 | - Foundation Styles and JavaScript 46 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | r³ foundation boilerplate 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "r3-foundation", 3 | "version": "1.0.0", 4 | "description": "redux-react-router and foundation boilerplate", 5 | "keywords": [ 6 | "redux", 7 | "react", 8 | "router", 9 | "routing", 10 | "frontend", 11 | "client", 12 | "webpack", 13 | "babel", 14 | "sass", 15 | "foundation", 16 | "postcss" 17 | ], 18 | "main": "index.js", 19 | "scripts": { 20 | "start": "node server" 21 | }, 22 | "author": "Anton Wilhelm", 23 | "license": "ISC", 24 | "dependencies": { 25 | "classnames": "^2.2.0", 26 | "font-awesome": "^4.3.0", 27 | "foundation-sites": "^6.1.2", 28 | "jquery": "^1.12.4", 29 | "react": "^0.14.5", 30 | "react-addons-update": "^0.14.7", 31 | "react-dom": "^0.14.7", 32 | "react-redux": "^4.4.5", 33 | "react-router": "2.0.0-rc5", 34 | "react-router-redux": "^2.1.0", 35 | "redux": "^3.2.1", 36 | "redux-logger": "^2.5.2", 37 | "redux-thunk": "^1.0.3", 38 | "what-input": "^1.1.4" 39 | }, 40 | "optionalDependencies": {}, 41 | "devDependencies": { 42 | "autoprefixer": "^6.3.2", 43 | "babel-core": "^6.3.15", 44 | "babel-loader": "^6.2.0", 45 | "babel-plugin-transform-runtime": "^6.5.0", 46 | "babel-preset-es2015": "^6.3.13", 47 | "babel-preset-react": "^6.3.13", 48 | "babel-preset-react-hmre": "^1.0.1", 49 | "babel-preset-stage-0": "^6.5.0", 50 | "babel-runtime": "^6.9.2", 51 | "css-loader": "^0.23.1", 52 | "express": "^4.13.3", 53 | "extract-text-webpack-plugin": "^1.0.1", 54 | "file-loader": "^0.8.5", 55 | "node-sass": "^3.4.2", 56 | "postcss-loader": "^0.8.0", 57 | "redux-devtools": "^3.1.0", 58 | "redux-devtools-dock-monitor": "^1.0.1", 59 | "redux-devtools-log-monitor": "^1.0.3", 60 | "sass-loader": "^3.1.2", 61 | "script-loader": "^0.6.1", 62 | "serve-static": "^1.11.1", 63 | "style-loader": "^0.13.0", 64 | "url-loader": "^0.5.7", 65 | "webpack": "^1.9.11", 66 | "webpack-dev-middleware": "^1.2.0", 67 | "webpack-hot-middleware": "^2.2.0" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack') 2 | var webpackDevMiddleware = require('webpack-dev-middleware') 3 | var webpackHotMiddleware = require('webpack-hot-middleware') 4 | var config = require('./webpack.config') 5 | var serveStatic = require('serve-static'); 6 | 7 | var app = new (require('express'))() 8 | var port = process.env.WEBPACK_PORT || 3000 9 | 10 | var compiler = webpack(config) 11 | app.use(webpackDevMiddleware(compiler, { noInfo: true, publicPath: config.output.publicPath })) 12 | app.use(webpackHotMiddleware(compiler)) 13 | 14 | app.use(function(req, res) { 15 | res.sendFile(__dirname + '/index.html') 16 | }) 17 | 18 | app.listen(port, function(error) { 19 | if (error) { 20 | console.error(error) 21 | } else { 22 | console.info("==> 🌎 Listening on port %s. Open up http://localhost:%s/ in your browser.", port, port) 23 | } 24 | }) 25 | -------------------------------------------------------------------------------- /src/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-0", "react"], 3 | "plugins": ["transform-runtime"], 4 | "env": { 5 | "development": { 6 | "presets": ["react-hmre"] 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/actions/index.js: -------------------------------------------------------------------------------- 1 | export const CREATE_CALLOUT = 'CREATE_CALLOUT' 2 | export function createCallout(type) { 3 | const types = ['primary', 'secondary', 'success', 'warning', 'alert'] 4 | if (type == null) { 5 | type = types[parseInt(Math.random() * types.length)] 6 | } 7 | const id = Math.random().toString().substr(2) 8 | return { 9 | type: CREATE_CALLOUT, 10 | payload: { 11 | message: 'Lorem ipsum ' + id, 12 | type: type, 13 | id: id 14 | } 15 | } 16 | } 17 | 18 | export const REMOVE_CALLOUT = 'REMOVE_CALLOUT' 19 | export function removeCallout(id) { 20 | return { 21 | type: REMOVE_CALLOUT, 22 | payload: { 23 | id: id 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/components/dashboard.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | import ReactDOM from 'react-dom' 3 | import { Link } from 'react-router' 4 | 5 | export default class Dashboard extends Component { 6 | 7 | renderCalout(data) { 8 | const refName = `callout-${data.id}` 9 | return ( 10 |
11 |
{data.header}
12 |

{data.message}

13 | 23 |
24 | ) 25 | } 26 | 27 | render() { 28 | const calloutElements = this.props.callouts.map((data) => { 29 | return this.renderCalout(data); 30 | }) 31 | return ( 32 |
33 |

Notifications

34 | {[...calloutElements]} 35 |
36 | ) 37 | } 38 | } 39 | 40 | Dashboard.propTypes = { 41 | callouts: PropTypes.array.isRequired, 42 | removeCallout: PropTypes.func.isRequired 43 | } 44 | -------------------------------------------------------------------------------- /src/components/navigation.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | import { Link } from 'react-router' 3 | 4 | export default class Navigation extends Component { 5 | render() { 6 | const instance = this 7 | return ( 8 |
9 |
10 | 11 |
Menu
12 |
13 | 14 |
15 |
16 |
    {console.log(instance)}}> 17 |
  • 18 | 19 |
  • 20 |
  • Table
  • 21 |
  • Nowhere
  • 22 |
  • 23 | More 24 | 28 |
  • 29 |
  • 30 |
  • 31 | 34 |
  • 35 |
36 |
37 |
38 |
    39 |
  • 40 |
  • 41 |
42 |
43 |
44 | 45 |
46 | ) 47 | } 48 | } 49 | 50 | Navigation.propTypes = { 51 | createCallout: PropTypes.func.isRequired 52 | } 53 | -------------------------------------------------------------------------------- /src/components/table.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | 3 | export default class Table extends Component { 4 | render() { 5 | return ( 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 |
This is the description!OneTwoThreeFourFiveSixSevenEightNineTenElevenTwelve
These are all the words that people use to describe Foundation 6!CoolSwagChillKillerRadBallerOMGSweetAwesomeBeastDopeTubular
These are some words that people use to describe other web frameworks.WhatevsUgh.LOLKAightEh.Grrr...Meh.TTYLBleh.Really?Why?
Here are some great super heros.BatmanSupermanSpidermanWonder WomanHulkNicolas CageAntmanAquamanCaptain AmericaWolverineThorIron Man
Here is a footer, just in case
89 | ) 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/containers/app.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | import { connect } from 'react-redux' 3 | import Navigation from '../components/navigation' 4 | 5 | import { 6 | createCallout 7 | } from '../actions' 8 | 9 | import '../styles/index.css' 10 | import '../styles/foundation.scss' 11 | 12 | // load jquery and foundation in the window scope 13 | import 'script!jquery' 14 | import 'script!what-input' 15 | import 'script!foundation-sites' 16 | 17 | class App extends Component { 18 | constructor(props) { 19 | super(props) 20 | } 21 | 22 | render() { 23 | // children are components which defined in the routes as children of App 24 | const { children } = this.props 25 | return ( 26 |
27 | 28 |
29 |
30 | {this.props.children} 31 |
32 |
33 |
34 | ) 35 | } 36 | 37 | componentDidMount() { 38 | $(document).foundation() 39 | } 40 | } 41 | 42 | App.propTypes = { 43 | // Injected by React Router 44 | children: PropTypes.node 45 | } 46 | 47 | function mapStateToProps(state) { 48 | return { 49 | } 50 | } 51 | 52 | export default connect(mapStateToProps, { 53 | createCallout 54 | })(App) 55 | -------------------------------------------------------------------------------- /src/containers/dev-tools.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { createDevTools } from 'redux-devtools' 3 | import LogMonitor from 'redux-devtools-log-monitor' 4 | import DockMonitor from 'redux-devtools-dock-monitor' 5 | 6 | export default createDevTools( 7 | 9 | 10 | 11 | ) 12 | -------------------------------------------------------------------------------- /src/containers/page-dashboard.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | import { connect } from 'react-redux' 3 | 4 | import { 5 | removeCallout 6 | } from '../actions' 7 | 8 | import Dashboard from '../components/dashboard' 9 | 10 | class PageDashboard extends Component { 11 | 12 | render() { 13 | return ( 14 | 19 | ) 20 | } 21 | } 22 | 23 | PageDashboard.propTypes = { 24 | url: PropTypes.string.isRequired, 25 | callouts: PropTypes.array.isRequired, 26 | removeCallout: PropTypes.func.isRequired, 27 | } 28 | 29 | function mapStateToProps(state) { 30 | return { 31 | url: state.routing.location.pathname, 32 | callouts: state.notifications.callouts 33 | } 34 | } 35 | 36 | export default connect(mapStateToProps, { 37 | removeCallout 38 | })(PageDashboard) 39 | -------------------------------------------------------------------------------- /src/containers/page-not-found.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | import { connect } from 'react-redux' 3 | 4 | class PageNotFound extends Component { 5 | 6 | render() { 7 | return ( 8 |
9 |

Page not found

10 |
The page "{this.props.url}" does not exist.
11 |
12 | ) 13 | } 14 | } 15 | 16 | PageNotFound.propTypes = { 17 | url: PropTypes.string.isRequired 18 | } 19 | 20 | function mapStateToProps(state) { 21 | return { 22 | url: state.routing.location.pathname 23 | } 24 | } 25 | 26 | export default connect(mapStateToProps, { 27 | })(PageNotFound) 28 | -------------------------------------------------------------------------------- /src/containers/page-table.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import { connect } from 'react-redux' 3 | 4 | import Table from '../components/table' 5 | 6 | class PageTable extends Component { 7 | 8 | render() { 9 | return ( 10 | 11 | ) 12 | } 13 | 14 | } 15 | 16 | function mapStateToProps(state) { 17 | return { 18 | } 19 | } 20 | 21 | export default connect(mapStateToProps, { 22 | })(PageTable) 23 | -------------------------------------------------------------------------------- /src/containers/root.dev.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | import { Provider } from 'react-redux' 3 | import routes from '../routes' 4 | import DevTools from './dev-tools' 5 | import { Router, browserHistory } from 'react-router' 6 | 7 | export default class Root extends Component { 8 | render() { 9 | const { store } = this.props 10 | return ( 11 | 12 |
13 | 14 | 15 |
16 |
17 | ) 18 | } 19 | } 20 | 21 | Root.propTypes = { 22 | store: PropTypes.object.isRequired 23 | } 24 | -------------------------------------------------------------------------------- /src/containers/root.js: -------------------------------------------------------------------------------- 1 | if (process.env.NODE_ENV === 'production') { 2 | module.exports = require('./root.prod') 3 | } else { 4 | module.exports = require('./root.dev') 5 | } 6 | -------------------------------------------------------------------------------- /src/containers/root.prod.js: -------------------------------------------------------------------------------- 1 | import React, { Component, PropTypes } from 'react' 2 | import { Provider } from 'react-redux' 3 | import routes from '../routes' 4 | import { Router, browserHistory } from 'react-router' 5 | 6 | export default class Root extends Component { 7 | render() { 8 | const { store } = this.props 9 | return ( 10 | 11 | 12 | 13 | ) 14 | } 15 | } 16 | 17 | Root.propTypes = { 18 | store: PropTypes.object.isRequired 19 | } 20 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render } from 'react-dom' 3 | import Root from './containers/root' 4 | import configureStore from './store/configure-store' 5 | 6 | const store = configureStore() 7 | 8 | render( 9 | , 10 | document.getElementById('root') 11 | ) 12 | -------------------------------------------------------------------------------- /src/middleware/index.js: -------------------------------------------------------------------------------- 1 | import { UPDATE_LOCATION } from 'react-router-redux' 2 | 3 | // hook into any action without to use the reducer 4 | export default store => next => action => { 5 | if (action.type === UPDATE_LOCATION) { 6 | // console.log('page changed') 7 | } 8 | return next(action) 9 | } 10 | -------------------------------------------------------------------------------- /src/reducers/index.js: -------------------------------------------------------------------------------- 1 | import * as ActionTypes from '../actions' 2 | import { routeReducer } from 'react-router-redux' 3 | import { combineReducers } from 'redux' 4 | import update from 'react-addons-update' 5 | 6 | function notifications(state = {callouts: []}, action) { 7 | switch (action.type) { 8 | 9 | case ActionTypes.CREATE_CALLOUT: 10 | return update(state, {callouts: {$push: [action.payload]}}) 11 | 12 | case ActionTypes.REMOVE_CALLOUT: 13 | const { id } = action.payload 14 | const index = state.callouts.map(item => item.id).indexOf(id) 15 | return update(state, {callouts: {$splice: [[index, 1]]}}) 16 | 17 | default: 18 | return state 19 | } 20 | } 21 | 22 | const rootReducer = combineReducers({ 23 | routing: routeReducer, 24 | notifications 25 | }) 26 | 27 | export default rootReducer 28 | -------------------------------------------------------------------------------- /src/routes.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Route, IndexRoute, Redirect } from 'react-router' 3 | 4 | import App from './containers/app' 5 | import Table from './containers/page-table' 6 | import Dashboard from './containers/page-dashboard' 7 | import NotFound from './containers/page-not-found' 8 | 9 | export default ( 10 | 11 | 12 | 13 | 14 | 15 | ) 16 | -------------------------------------------------------------------------------- /src/store/configure-store.dev.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware, compose } from 'redux' 2 | import { syncHistory } from 'react-router-redux' 3 | import { browserHistory } from 'react-router' 4 | import DevTools from '../containers/dev-tools' 5 | import thunk from 'redux-thunk' 6 | import createLogger from 'redux-logger' 7 | import rootReducer from '../reducers' 8 | import customMiddleware from '../middleware' 9 | 10 | const reduxRouterMiddleware = syncHistory(browserHistory) 11 | 12 | export default function configureStore(initialState) { 13 | const store = createStore( 14 | rootReducer, 15 | initialState, 16 | compose( 17 | applyMiddleware(thunk, customMiddleware, reduxRouterMiddleware, createLogger()), 18 | DevTools.instrument() 19 | ) 20 | ) 21 | 22 | // Required for replaying actions from devtools to work 23 | reduxRouterMiddleware.listenForReplays(store) 24 | 25 | if (module.hot) { 26 | // Enable Webpack hot module replacement for reducers 27 | module.hot.accept('../reducers', () => { 28 | const nextRootReducer = require('../reducers').default 29 | store.replaceReducer(nextRootReducer) 30 | }) 31 | } 32 | 33 | return store 34 | } 35 | -------------------------------------------------------------------------------- /src/store/configure-store.js: -------------------------------------------------------------------------------- 1 | if (process.env.NODE_ENV === 'production') { 2 | module.exports = require('./configure-store.prod') 3 | } else { 4 | module.exports = require('./configure-store.dev') 5 | } 6 | -------------------------------------------------------------------------------- /src/store/configure-store.prod.js: -------------------------------------------------------------------------------- 1 | import { createStore, applyMiddleware } from 'redux' 2 | import { syncHistory } from 'react-router-redux' 3 | import { browserHistory } from 'react-router' 4 | import thunk from 'redux-thunk' 5 | import rootReducer from '../reducers' 6 | import customMiddleware from '../middleware' 7 | 8 | export default function configureStore(initialState) { 9 | return createStore( 10 | rootReducer, 11 | initialState, 12 | applyMiddleware(thunk, customMiddleware, syncHistory(browserHistory)) 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /src/styles/foundation.scss: -------------------------------------------------------------------------------- 1 | @import 'foundation-sites/scss/foundation'; 2 | 3 | /// include all modules of foundation 4 | @include foundation-everything; 5 | 6 | /// or use just particular mouldes 7 | // @include foundation-global-styles; 8 | // @include foundation-grid; 9 | // @include foundation-typography; 10 | // @include foundation-button; 11 | // @include foundation-forms; 12 | // @include foundation-visibility-classes; 13 | // @include foundation-float-classes; 14 | // @include foundation-accordion; 15 | // @include foundation-accordion-menu; 16 | // @include foundation-badge; 17 | // @include foundation-breadcrumbs; 18 | // @include foundation-button-group; 19 | // @include foundation-callout; 20 | // @include foundation-close-button; 21 | // @include foundation-drilldown-menu; 22 | // @include foundation-dropdown; 23 | // @include foundation-dropdown-menu; 24 | // @include foundation-flex-video; 25 | // @include foundation-label; 26 | // @include foundation-media-object; 27 | // @include foundation-menu; 28 | // @include foundation-off-canvas; 29 | // @include foundation-orbit; 30 | // @include foundation-pagination; 31 | // @include foundation-progress-bar; 32 | // @include foundation-slider; 33 | // @include foundation-sticky; 34 | // @include foundation-reveal; 35 | // @include foundation-switch; 36 | // @include foundation-table; 37 | // @include foundation-tabs; 38 | // @include foundation-thumbnail; 39 | // @include foundation-title-bar; 40 | // @include foundation-tooltip; 41 | // @include foundation-top-bar; 42 | -------------------------------------------------------------------------------- /src/styles/index.css: -------------------------------------------------------------------------------- 1 | @import "~font-awesome/css/font-awesome.css"; 2 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | var autoprefixer = require('autoprefixer') 4 | var ExtractTextPlugin = require('extract-text-webpack-plugin') 5 | 6 | var assetPath = '/assets/' 7 | var absolutePath = path.join(__dirname, 'build', assetPath) 8 | 9 | module.exports = { 10 | devtool: 'source-map', 11 | entry: [ 12 | 'webpack-hot-middleware/client', 13 | './src/index' 14 | ], 15 | output: { 16 | path: absolutePath, 17 | filename: 'bundle.js', 18 | publicPath: assetPath 19 | }, 20 | plugins: [ 21 | new webpack.DefinePlugin({ 22 | 'process.env':{ 23 | 'NODE_ENV': JSON.stringify(process.env.NODE_ENV) 24 | } 25 | }), 26 | new webpack.optimize.OccurenceOrderPlugin(), 27 | new webpack.HotModuleReplacementPlugin(), 28 | new webpack.NoErrorsPlugin(), 29 | new ExtractTextPlugin("bundle.css") 30 | ], 31 | module: { 32 | loaders: [ 33 | { 34 | test: /\.js$/, 35 | loaders: [ 'babel' ], 36 | exclude: /node_modules/, 37 | include: path.join(__dirname, 'src') 38 | }, 39 | // fonts and svg 40 | { test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff" }, 41 | { test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff" }, 42 | { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/octet-stream" }, 43 | { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file" }, 44 | { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=image/svg+xml" }, 45 | { 46 | // images 47 | test: /\.(ico|jpe?g|png|gif)$/, 48 | loader: "file" 49 | }, 50 | { 51 | // for some modules like foundation 52 | test: /\.scss$/, 53 | exclude: [/node_modules/], // sassLoader will include node_modules explicitly 54 | loader: ExtractTextPlugin.extract("style", "css?sourceMap!postcss!sass?sourceMap&outputStyle=expanded") 55 | }, 56 | { 57 | test: /\.css$/, 58 | loader: ExtractTextPlugin.extract("style", "css?sourceMap!postcss") 59 | } 60 | ] 61 | }, 62 | postcss: function(webpack) { 63 | return [ 64 | autoprefixer({browsers: ['last 2 versions', 'ie >= 9', 'and_chr >= 2.3']}) 65 | ] 66 | }, 67 | sassLoader: { 68 | includePaths: [path.resolve(__dirname, "node_modules")] 69 | } 70 | } 71 | --------------------------------------------------------------------------------