├── .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 |
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 | This is the description! |
10 | One |
11 | Two |
12 | Three |
13 | Four |
14 | Five |
15 | Six |
16 | Seven |
17 | Eight |
18 | Nine |
19 | Ten |
20 | Eleven |
21 | Twelve |
22 |
23 |
24 |
25 |
26 | These are all the words that people use to describe Foundation 6! |
27 | Cool |
28 | Swag |
29 | Chill |
30 | Killer |
31 | Rad |
32 | Baller |
33 | OMG |
34 | Sweet |
35 | Awesome |
36 | Beast |
37 | Dope |
38 | Tubular |
39 |
40 |
41 | These are some words that people use to describe other web frameworks. |
42 | Whatevs |
43 | Ugh. |
44 | LOL |
45 | K |
46 | Aight |
47 | Eh. |
48 | Grrr... |
49 | Meh. |
50 | TTYL |
51 | Bleh. |
52 | Really? |
53 | Why? |
54 |
55 |
56 | Here are some great super heros. |
57 | Batman |
58 | Superman |
59 | Spiderman |
60 | Wonder Woman |
61 | Hulk |
62 | Nicolas Cage |
63 | Antman |
64 | Aquaman |
65 | Captain America |
66 | Wolverine |
67 | Thor |
68 | Iron Man |
69 |
70 |
71 |
72 |
73 | Here is a footer, just in case |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 |
87 |
88 |
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 |
--------------------------------------------------------------------------------