Merge pull request #198 from zuiidea/4.2-dev

4.2 dev
This commit is contained in:
zuiidea
2017-04-21 10:49:31 +08:00
committed by GitHub
37 changed files with 326 additions and 240 deletions
+4 -10
View File
@@ -7,6 +7,7 @@
"dva": "^1.1.0",
"dva-loading": "^0.2.0",
"lodash": "^4.17.4",
"nprogress": "^0.2.0",
"qs": "^6.2.0",
"react": "^15.4.1",
"react-countup": "1.3.0",
@@ -34,6 +35,7 @@
"jsonp": "^0.2.1",
"less-vars-to-js": "^1.1.2",
"mockjs": "^1.0.1-beta3",
"path-to-regexp": "^1.7.0",
"rc-tween-one": "^1.0.0",
"redbox-react": "^1.2.10"
},
@@ -41,16 +43,8 @@
"lint"
],
"scripts": {
"dev": "set BROWSER=none&&roadhog server",
"dev": "set BROWSER=none&&set HOST=0.0.0.0&&roadhog server",
"lint": "eslint --fix --ext .js src",
"build": "roadhog build"
},
"theme": "./src/theme.js",
"standard": {
"parser": "babel-eslint",
"globals": [
"location",
"localStorage"
]
"build": "roadhog build --analyze"
}
}
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { TweenOneGroup } from 'rc-tween-one'
const enterAnim = [
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Table } from 'antd'
import { request } from '../../utils'
import lodash from 'lodash'
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Dropdown, Button, Icon, Menu } from 'antd'
const DropOption = ({ onMenuClick, menuOptions = [], buttonStyle, dropdownProps }) => {
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import './iconfont.less'
const Iconfont = ({ type }) => <span
+32 -39
View File
@@ -1,47 +1,45 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Breadcrumb, Icon } from 'antd'
import { Link } from 'dva/router'
import styles from './Bread.less'
import { menu } from '../../utils'
import pathToRegexp from 'path-to-regexp'
import { queryArray } from '../../utils'
let pathSet = []
const getPathSet = function (menuArray, parentPath) {
parentPath = parentPath || '/'
menuArray.forEach(item => {
pathSet[(parentPath + item.key).replace(/\//g, '-').hyphenToHump()] = {
path: parentPath + item.key,
name: item.name,
icon: item.icon || '',
clickable: item.clickable === undefined,
const Bread = ({ location, menu }) => {
// 匹配当前路由
let pathArray = []
let current
for (let index in menu) {
if (menu[index].router && pathToRegexp(menu[index].router).exec(location.pathname)) {
current = menu[index]
break
}
if (item.child) {
getPathSet(item.child, `${parentPath}${item.key}/`)
}
})
}
getPathSet(menu)
}
function Bread ({ location }) {
let pathNames = []
location.pathname.substr(1).split('/').forEach((item, key) => {
if (key > 0) {
pathNames.push((`${pathNames[key - 1]}-${item}`).hyphenToHump())
} else {
pathNames.push((`-${item}`).hyphenToHump())
}
})
if (!current) {
return (<div className={styles.bread}>首页</div>)
}
const breadsArray = pathNames.filter(item => (item in pathSet))
const breads = breadsArray.map((item, key) => {
// 递归查找父级
const getPathArray = (item) => {
pathArray.unshift(item)
if (item.bpid) {
getPathArray(queryArray(menu, item.bpid, 'id'))
}
}
getPathArray(current)
const breads = pathArray.map((item, key) => {
const content = (
<span>{pathSet[item].icon
? <Icon type={pathSet[item].icon} style={{ marginRight: 4 }} />
: ''}{pathSet[item].name}</span>
<span>{item.icon
? <Icon type={item.icon} style={{ marginRight: 4 }} />
: ''}{item.name}</span>
)
return (
<Breadcrumb.Item key={key}>
{((breadsArray.length - 1) !== key && pathSet[item].clickable)
? <Link to={pathSet[item].path}>
{((pathArray.length - 1) !== key)
? <Link to={item.router}>
{content}
</Link>
: content}
@@ -52,12 +50,6 @@ function Bread ({ location }) {
return (
<div className={styles.bread}>
<Breadcrumb>
<Breadcrumb.Item >
<Link to="/dashboard">
<Icon type="home" />
<span>Home</span>
</Link>
</Breadcrumb.Item>
{breads}
</Breadcrumb>
</div>
@@ -65,6 +57,7 @@ function Bread ({ location }) {
}
Bread.propTypes = {
menu: PropTypes.array,
location: PropTypes.object,
}
+5 -2
View File
@@ -1,13 +1,15 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Menu, Icon, Popover } from 'antd'
import styles from './Header.less'
import Menus from './Menu'
const SubMenu = Menu.SubMenu
function Header ({ user, logout, switchSider, siderFold, isNavbar, menuPopoverVisible, location, switchMenuPopover, navOpenKeys, changeOpenKeys }) {
function Header ({ user, logout, switchSider, siderFold, isNavbar, menuPopoverVisible, location, switchMenuPopover, navOpenKeys, changeOpenKeys, menu }) {
let handleClickMenu = e => e.key === 'logout' && logout()
const menusProps = {
menu,
siderFold: false,
darkTheme: false,
isNavbar,
@@ -48,6 +50,7 @@ function Header ({ user, logout, switchSider, siderFold, isNavbar, menuPopoverVi
}
Header.propTypes = {
menu: PropTypes.array,
user: PropTypes.object,
logout: PropTypes.func,
switchSider: PropTypes.func,
+51 -27
View File
@@ -1,36 +1,59 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Menu, Icon } from 'antd'
import { Link } from 'dva/router'
import { menu } from '../../utils'
import { arrayToTree } from '../../utils'
const topMenus = menu.map(item => item.key)
const getMenus = function (menuArray, siderFold, parentPath = '/') {
return menuArray.map(item => {
const linkTo = parentPath + item.key
if (item.child) {
const Menus = ({ siderFold, darkTheme, location, handleClickNavMenu, navOpenKeys, changeOpenKeys, menu }) => {
// 生成树状
const menuTree = arrayToTree(menu.filter(_ => _.mpid !== -1), 'id', 'mpid')
const levelMap = {}
// 递归生成菜单
const getMenus = (menuTreeN, siderFoldN) => {
return menuTreeN.map(item => {
if (item.chindren) {
if (item.mpid) {
levelMap[item.id] = item.mpid
}
return (
<Menu.SubMenu
key={item.id}
title={<span>
{item.icon && <Icon type={item.icon} />}
{(!siderFoldN || menuTree.indexOf(item) < 0) && item.name}
</span>}
>
{getMenus(item.chindren, siderFoldN)}
</Menu.SubMenu>
)
}
return (
<Menu.SubMenu key={linkTo} title={<span>{item.icon ? <Icon type={item.icon} /> : ''}{siderFold && topMenus.indexOf(item.key) >= 0 ? '' : item.name}</span>}>
{getMenus(item.child, siderFold, `${linkTo}/`)}
</Menu.SubMenu>
<Menu.Item key={item.id}>
<Link to={item.router}>
{item.icon && <Icon type={item.icon} />}
{(!siderFoldN || menuTree.indexOf(item) < 0) && item.name}
</Link>
</Menu.Item>
)
}
return (
<Menu.Item key={linkTo}>
<Link to={linkTo}>
{item.icon ? <Icon type={item.icon} /> : ''}
{siderFold && topMenus.indexOf(item.key) >= 0 ? '' : item.name}
</Link>
</Menu.Item>
)
})
}
function Menus ({ siderFold, darkTheme, location, handleClickNavMenu, navOpenKeys, changeOpenKeys }) {
const menuItems = getMenus(menu, siderFold)
})
}
const menuItems = getMenus(menuTree, siderFold)
// 保持选中
const getAncestorKeys = (key) => {
const map = {
'/navigation/navigation2': ['/navigation'],
let map = {}
const getParent = (index) => {
const result = [String(levelMap[index])]
if (levelMap[result[0]]) {
result.unshift(getParent(result[0])[0])
}
return result
}
for (let index in levelMap) {
if ({}.hasOwnProperty.call(levelMap, index)) {
map[index] = getParent(index)
}
}
return map[key] || []
}
@@ -59,7 +82,7 @@ function Menus ({ siderFold, darkTheme, location, handleClickNavMenu, navOpenKey
mode={siderFold ? 'vertical' : 'inline'}
theme={darkTheme ? 'dark' : 'light'}
onClick={handleClickNavMenu}
defaultSelectedKeys={[location.pathname !== '/' ? location.pathname : '/dashboard']}
defaultSelectedKeys={[location.pathname !== '/' ? location.pathname : menuTree[0].router]}
>
{menuItems}
</Menu>
@@ -67,6 +90,7 @@ function Menus ({ siderFold, darkTheme, location, handleClickNavMenu, navOpenKey
}
Menus.propTypes = {
menu: PropTypes.array,
siderFold: PropTypes.bool,
darkTheme: PropTypes.bool,
location: PropTypes.object,
+5 -2
View File
@@ -1,11 +1,13 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Icon, Switch } from 'antd'
import styles from './Layout.less'
import { config } from '../../utils'
import Menus from './Menu'
function Sider ({ siderFold, darkTheme, location, changeTheme, navOpenKeys, changeOpenKeys }) {
function Sider ({ siderFold, darkTheme, location, changeTheme, navOpenKeys, changeOpenKeys, menu }) {
const menusProps = {
menu,
siderFold,
darkTheme,
location,
@@ -28,6 +30,7 @@ function Sider ({ siderFold, darkTheme, location, changeTheme, navOpenKeys, chan
}
Sider.propTypes = {
menu: PropTypes.array,
siderFold: PropTypes.bool,
darkTheme: PropTypes.bool,
location: PropTypes.object,
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import ReactDOM from 'react-dom'
import styles from './Search.less'
import { Input, Select, Button, Icon } from 'antd'
+2 -1
View File
@@ -3,13 +3,14 @@ import 'babel-polyfill'
import dva from 'dva'
import createLoading from 'dva-loading'
import { browserHistory } from 'dva/router'
import { message } from 'antd'
// 1. Initialize
const app = dva({
...createLoading(),
history: browserHistory,
onError (error) {
console.error('app onError -- ', error)
message.error(error.message)
},
})
-1
View File
@@ -133,7 +133,6 @@ export default {
}
},
handleNavOpenKeys (state, { payload: navOpenKeys }) {
console.log(navOpenKeys)
return {
...state,
...navOpenKeys,
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Router } from 'dva/router'
import App from './routes/app'
+11 -4
View File
@@ -1,7 +1,8 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'dva'
import { Layout } from '../components'
import { classnames, config } from '../utils'
import { classnames, config, menu } from '../utils'
import { Helmet } from 'react-helmet'
import '../themes/index.less'
@@ -11,6 +12,7 @@ const App = ({ children, location, dispatch, app }) => {
const { user, siderFold, darkTheme, isNavbar, menuPopoverVisible, navOpenKeys } = app
const headerProps = {
menu,
user,
siderFold,
location,
@@ -32,6 +34,7 @@ const App = ({ children, location, dispatch, app }) => {
}
const siderProps = {
menu,
siderFold,
darkTheme,
location,
@@ -45,6 +48,10 @@ const App = ({ children, location, dispatch, app }) => {
},
}
const breadProps = {
menu,
}
if (config.openPages && config.openPages.indexOf(location.pathname) > -1) {
return <div>{children}</div>
}
@@ -63,7 +70,7 @@ const App = ({ children, location, dispatch, app }) => {
</aside> : ''}
<div className={styles.main}>
<Header {...headerProps} />
<Bread location={location} />
<Bread {...breadProps} location={location} />
<div className={styles.container}>
<div className={styles.content}>
{children}
@@ -83,4 +90,4 @@ App.propTypes = {
app: PropTypes.object,
}
export default connect(({ app }) => ({ app }))(App)
export default connect(({ app, loading }) => ({ app, loading }))(App)
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import styles from './Container.less'
import { ResponsiveContainer } from 'recharts'
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Row, Col, Card, Button } from 'antd'
import Container from '../Container'
import {
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Row, Col, Card, Button } from 'antd'
import Container from '../Container'
import {
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Table, Tag } from 'antd'
import styles from './browser.less'
import { color } from '../../../utils'
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Table, Tag } from 'antd'
import styles from './comments.less'
import { color } from '../../../utils'
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import styles from './completed.less'
import classnames from 'classnames'
import { color } from '../../../utils'
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import styles from './cpu.less'
import { color } from '../../../utils'
import CountUp from 'react-countup'
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Icon, Card } from 'antd'
import CountUp from 'react-countup'
import styles from './numberCard.less'
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import styles from './quote.less'
function Quote ({ name, content, title, avatar }) {
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Table, Tag } from 'antd'
import styles from './recentSales.less'
import { color } from '../../../utils'
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import styles from './sales.less'
import classnames from 'classnames'
import { color } from '../../../utils'
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Button } from 'antd'
import styles from './user.less'
import CountUp from 'react-countup'
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import styles from './weather.less'
function Weather ({ city, icon, dateTime, temperature, name }) {
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'dva'
import { Row, Col, Card } from 'antd'
import { NumberCard, Quote, Sales, Weather, RecentSales, Comments, Completed, Browser, Cpu, User } from './components'
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'dva'
import { Button, Row, Form, Input } from 'antd'
import { config } from '../../utils'
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Form, Button, Row, Col, Switch } from 'antd'
import { Search } from '../../components'
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Table, Modal } from 'antd'
import styles from './UserList.less'
import classnames from 'classnames'
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Form, Input, InputNumber, Radio, Modal } from 'antd'
const FormItem = Form.Item
+2 -1
View File
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { routerRedux } from 'dva/router'
import { connect } from 'dva'
import UserList from './UserList'
+2 -2
View File
@@ -1,10 +1,10 @@
import { request, config } from '../utils'
const { api } = config
const { userInfo, userLogout } = api
const { userInfo, userLogout, userLogin } = api
export async function login (params) {
return request({
url: '/api/login',
url: userLogin,
method: 'post',
data: params,
})
+49
View File
@@ -3,6 +3,7 @@ import menu from './menu'
import request from './request'
import classnames from 'classnames'
import { color } from './theme'
import lodash from 'lodash'
// 连字符转驼峰
String.prototype.hyphenToHump = function () {
@@ -52,6 +53,52 @@ const queryURL = (name) => {
return null
}
/**
* 数组内查询
* @param {array} array
* @param {String} id
* @param {String} keyAlias
* @return {Array}
*/
const queryArray = (array, key, keyAlias = 'key') => {
if (!(array instanceof Array)) {
return null
}
const item = array.filter(_ => _[keyAlias] === key)
if (item.length) {
return item[0]
}
return null
}
/**
* 数组格式转树状结构
* @param {array} array
* @param {String} id
* @param {String} pid
* @param {String} children
* @return {Array}
*/
const arrayToTree = (array, id = 'id', pid = 'pid', chindren = 'chindren') => {
let data = lodash.cloneDeep(array)
let result = []
let hash = {}
data.forEach((item, index) => {
hash[data[index][id]] = data[index]
})
data.forEach((item) => {
let hashVP = hash[item[pid]]
if (hashVP) {
!hashVP[chindren] && (hashVP[chindren] = [])
hashVP[chindren].push(item)
} else {
result.push(item)
}
})
return result
}
module.exports = {
config,
menu,
@@ -59,4 +106,6 @@ module.exports = {
color,
classnames,
queryURL,
queryArray,
arrayToTree,
}
+115 -77
View File
@@ -1,102 +1,140 @@
module.exports = [
{
key: 'dashboard',
name: 'Dashboard',
id: 1,
icon: 'laptop',
name: 'Dashboard',
router: '/dashboard',
},
{
key: 'users',
id: 2,
bpid: 1,
name: 'User Manage',
icon: 'user',
router: '/users',
},
{
key: 'request',
id: 3,
bpid: 1,
name: 'Request',
icon: 'api',
router: '/request',
},
{
key: 'UIElement',
id: 4,
bpid: 1,
name: 'UI Element',
icon: 'camera-o',
clickable: false,
child: [
{
key: 'iconfont',
name: 'IconFont',
icon: 'heart-o',
},
{
key: 'dataTable',
name: 'DataTable',
icon: 'database',
},
{
key: 'dropOption',
name: 'DropOption',
icon: 'bars',
},
{
key: 'search',
name: 'Search',
icon: 'search',
},
{
key: 'editor',
name: 'Editor',
icon: 'edit',
},
{
key: 'layer',
name: 'layer (Function)',
icon: 'credit-card',
},
],
},
{
key: 'chart',
id: 41,
bpid: 4,
mpid: 4,
name: 'IconFont',
icon: 'heart-o',
router: '/UIElement/iconfont',
},
{
id: 42,
bpid: 4,
mpid: 4,
name: 'DataTable',
icon: 'database',
router: '/UIElement/dataTable',
},
{
id: 43,
bpid: 4,
mpid: 4,
name: 'DropOption',
icon: 'bars',
router: '/UIElement/dropOption',
},
{
id: 44,
bpid: 4,
mpid: 4,
name: 'Search',
icon: 'search',
router: '/UIElement/search',
},
{
id: 45,
bpid: 4,
mpid: 4,
name: 'Editor',
icon: 'edit',
router: '/UIElement/editor',
},
{
id: 46,
bpid: 4,
mpid: 4,
name: 'layer (Function)',
icon: 'credit-card',
router: '/UIElement/layer',
},
{
id: 5,
bpid: 1,
name: 'Recharts',
icon: 'code-o',
child: [
{
key: 'lineChart',
name: 'LineChart',
icon: 'line-chart',
},
{
key: 'barChart',
name: 'BarChart',
icon: 'bar-chart',
},
{
key: 'areaChart',
name: 'AreaChart',
icon: 'area-chart',
},
],
},
{
key: 'navigation',
id: 51,
bpid: 5,
mpid: 5,
name: 'LineChart',
icon: 'line-chart',
router: '/chart/lineChart',
},
{
id: 52,
bpid: 5,
mpid: 5,
name: 'BarChart',
icon: 'bar-chart',
router: '/chart/lineChart',
},
{
id: 53,
bpid: 5,
mpid: 5,
name: 'AreaChart',
icon: 'area-chart',
router: '/chart/areaChart',
},
{
id: 6,
bpid: 1,
name: 'Test Navigation',
icon: 'setting',
child: [
{
key: 'navigation1',
name: 'Test Navigation1',
},
{
key: 'navigation2',
name: 'Test Navigation2',
child: [
{
key: 'navigation21',
name: 'Test Navigation21',
},
{
key: 'navigation22',
name: 'Test Navigation22',
},
],
},
],
},
{
id: 61,
bpid: 6,
mpid: 6,
name: 'Test Navigation1',
router: '/navigation/navigation1',
},
{
id: 62,
bpid: 6,
mpid: 6,
name: 'Test Navigation2',
router: '/navigation/navigation2',
},
{
id: 621,
bpid: 62,
mpid: 62,
name: 'Test Navigation21',
router: '/navigation/navigation2/navigation1',
},
{
id: 622,
bpid: 62,
mpid: 62,
name: 'Test Navigation22',
router: '/navigation/navigation2/navigation2',
},
]
-50
View File
@@ -1,50 +0,0 @@
const webpack = require('atool-build/lib/webpack')
module.exports = function (webpackConfig, env) {
webpackConfig.babel.plugins.push('transform-runtime')
webpackConfig.babel.plugins.push(['import', {
libraryName: 'antd',
style: true,
}])
// Support hmr
if (env === 'development') {
webpackConfig.devtool = '#eval'
webpackConfig.babel.plugins.push(['dva-hmr', {
entries: [
'./src/index.js',
],
}])
} else {
webpackConfig.babel.plugins.push('dev-expression')
webpackConfig.entry = { index: './src/_index.js' }
}
// Don't extract common.js and common.css
webpackConfig.plugins = webpackConfig.plugins.filter((plugin) => {
return !(plugin instanceof webpack.optimize.CommonsChunkPlugin)
})
// Support CSS Modules
// Parse all less files as css module.
webpackConfig.module.loaders.forEach((loader) => {
if (typeof loader.test === 'function' && loader.test.toString().indexOf('\\.less$') > -1) {
loader.include = /node_modules/
loader.test = /\.less$/
}
if (loader.test.toString() === '/\\.module\\.less$/') {
loader.exclude = /node_modules/
loader.test = /\.less$/
}
if (typeof loader.test === 'function' && loader.test.toString().indexOf('\\.css$') > -1) {
loader.include = /node_modules/
loader.test = /\.css$/
}
if (loader.test.toString() === '/\\.module\\.css$/') {
loader.exclude = /node_modules/
loader.test = /\.css$/
}
})
return webpackConfig
}