开始
项目地址: https://github.com/zezeping/react-admin-starter
初始化项目
npx create-react-app react-admin-starter
npm run eject
npm start
参考文档
支持scss & less & antd
Scss
config/webpack.config.js
module.exports = {
resolve: {
alias: {
'@': path.join(__dirname, '../src')
}
}
}
解决 react test 无法找到 @/
// 在package.json找到jest.moduleNameMapper添加
"^@\/(.*)$": "<rootDir>/src/$1"
function getStyleLoaders
if (preProcessor) {
// begin +++
let preProcessorOptions = null
if (preProcessor === 'sass-loader') {
preProcessorOptions = {
additionalData: '@import "@/assets/stylesheets/globalInjectedData.scss";'
}
}
// end
loaders.push(
{
loader: require.resolve('resolve-url-loader'),
options: {
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
root: paths.appSrc,
},
},
{
loader: require.resolve(preProcessor),
options: {
sourceMap: true,
...preProcessorOptions // +++
},
}
);
}
Less
npm install less less-loader -D
config/webpack.config.js
// 1.
const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;
// 2. module.rules, 放在sassModuleRegex下面(不可放到最后!!!)
{
test: lessRegex,
exclude: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
mode: 'icss',
},
},
'less-loader'
),
sideEffects: true,
},
{
test: lessModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
mode: 'local',
getLocalIdent: getCSSModuleLocalIdent,
},
},
'less-loader'
),
},
// 3. function getStyleLoaders
if (preProcessor) {
let preProcessorOptions = null
if (preProcessor === 'sass-loader') {
preProcessorOptions = {
additionalData: '@import "@/assets/stylesheets/globalInjectedData.scss";'
}
} else if (preProcessor === 'less-loader') { // begin ++++
preProcessorOptions = {
lessOptions: {
javascriptEnabled: true,
modifyVars: {
'@primary-color': '#f00',
},
}
}
} // end
loaders.push(
{
loader: require.resolve('resolve-url-loader'),
options: {
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
root: paths.appSrc,
},
},
{
loader: require.resolve(preProcessor),
options: {
sourceMap: true,
...preProcessorOptions // +++
},
}
);
}
antd
npm i antd -S
// src/index.less
@import '~antd/dist/antd.less';
Api Proxy & MockData
npm install http-proxy-middleware -D
创建 src/setupProxy.js
const { createProxyMiddleware } = require('http-proxy-middleware')
const mockData = {
'GET /api/users': {
hello: 'world'
}
}
module.exports = function(app) {
app.use(
process.env.REACT_APP_API_BASE_URL,
// Mock middleware
(req, res, next) => {
const mockPath = `^${req.method} ${req.originalUrl}$`
console.log('Request Mock URL:', req.method, req.originalUrl)
for (const key in mockData) {
if (new RegExp(mockPath, 'i').test(key)) {
//res.json({hello: 'world'})
res.send(mockData[key])
return
}
}
next()
},
// Proxy middleware
createProxyMiddleware({
target: 'http://localhost:8800',
changeOrigin: true,
//ws: true, // 配置ws跨域
//secure: false, // https协议才设置
//loglevel: 'debug',
//rewrite: path => path.replace(/^\/api/, '')
})
)
}
React Router
npm i react-router-dom -S
src/routes/index.js
import { lazy, Suspense } from 'react'
import { Navigate } from 'react-router-dom'
import Home from '../views/home'
import NotFound from '../views/404'
import Login from '../views/login'
export default defineRoutes([
{ path: '404', element: <NotFound /> },
{ path: 'login', element: <Login /> },
{ path: 'home', element: <Home /> },
// 路由懒加载
{ path: 'settings', component: () => import('../views/settings'),
children: [
{ index: true, component: () => import('../views/settings/default') },
{ path: 'menus', component: () => import('../views/settings/menus') },
{ path: 'roles', component: () => import('../views/settings/roles') },
{ path: '*', element: <Navigate replace to="" /> },
]
},
{ path: '/', extract: true, element: <Navigate replace to="/home" /> },
{ path: '*', element: <Navigate replace to="/404" /> },
])
export function defineRoutes(routes) {
const iterateUseRoute = (route) => {
if (route.children) {
route.children = route.children.map(route => iterateUseRoute(route))
}
if (typeof route.component === 'function') {
const item = { component: lazy(route.component) }
//delete route.component
route.element = (
<Suspense fallback={ <div>路由加载中...</div> }>
<item.component />
</Suspense>
)
}
return route
}
return routes.map(route => iterateUseRoute(route))
}
app.js
import { BrowserRouter as Router, Routes, Route, Link } from 'react-router-dom'
<Router>
<Routes>
{ routes.map(route => (
<Route key={route.path} {...route}>
{ route.children?.map(route => <Route key={route.path || 'index'} {...route}></Route>) }
</Route>
)) },
</Routes>
</Router>
参考文档
路由懒加载
React Redux
npm i redux react-redux -S
持久化
参考文档
persist
开始
项目地址: https://github.com/zezeping/react-admin-starter
初始化项目
参考文档
支持
scss&less&antdScss
Less
antd
Api Proxy & MockData
创建
src/setupProxy.jsReact Router
react-router-dom参考文档
React Redux
react-redux持久化
参考文档