Skip to content

React项目搭建(create-react-app) #1

@wuyuedefeng

Description

@wuyuedefeng

开始

项目地址: https://github.com/zezeping/react-admin-starter

初始化项目

npx create-react-app react-admin-starter
npm run eject
npm start

参考文档

支持scss & less & antd

Scss

npm install sass -D
  • 配置@指向到src目录

config/webpack.config.js

module.exports = {
  resolve: {
    alias: {
      '@': path.join(__dirname, '../src')
    }
  }
}

解决 react test 无法找到 @/

// 在package.json找到jest.moduleNameMapper添加
"^@\/(.*)$": "<rootDir>/src/$1" 
  • 配置scss加载全局变量

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

  • 安装react-router-dom
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

  • 安装react-redux
npm i redux react-redux -S

持久化

npm i redux-persist -S

参考文档

persist

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions