基于webpack4搭建的react项目框架的方法
程序员文章站
2023-10-18 09:22:46
介绍
框架介绍,使用webpac构建的react单页面应用,集成antd。使用webpack-dev-server启动本地服务,加入热更新便于开发调试。使用bundl...
介绍
框架介绍,使用webpac构建的react单页面应用,集成antd。使用webpack-dev-server启动本地服务,加入热更新便于开发调试。使用bundle-loader进行代码切割懒加载
手动搭建,不使用cli,大量注释适合初学者对webpack的理解学习,对react项目的深入了解
启动
git clone https://gitee.com/wjj0720/react-demo.git cd react-demo yarn yarn start
打包
yarn build
目录结构
+node_modules -src +asset +layout +pages +redux +utils +app.js +index.html +index.js .babelrc package.json postcss.config.js webpack.config.js //webpack 配置
bundle-loader 懒加载使用
// webpack.config.js 配置 module: { rules: [ { test: /\.bundle\.js$/, use: { loader: 'bundle-loader', options: { name: '[name]', lazy: true } } } ] } // 页面引入组件 import home from "bundle-loader?lazy&name=[name]!./home"; // 组件使用 因为组件懒加载 是通过异步的形式引入 所以不能再页面直接以标签的形式使用 需要做使用封装 import react, {component} from 'react' import { withrouter } from 'react-router-dom' class lazyload extends component { state = { loadover: null } componentwillmount() { this.props.loading(c => { this.setstate({ loadover: withrouter(c.default) }) }) } render() { let {loadover} = this.state; return ( loadover ? <loadover/> : <div>加载动画</div> ) } } export default lazyload // 通过封装的懒加载组件过度 增加加载动画 <lazyload loading={home} />
路由配置
框架按照模块划分,pages文件夹下具有route.js 即为一个模块
// 通过require.context读取模块下路由文件 const files = require.context('./pages', true, /route\.js$/) let routers = files.keys().reduce((routers, route) => { let router = files(route).default return routers.concat(router) }, []) // 模块路由文件格式 import user from "bundle-loader?lazy&name=[name]!./user"; export default [ { path: '/user', component: user }, { path: '/user/:id', component: user } ]
redux 使用介绍
// ---------创建 -------- // 为了不免action、reducer 在不同文件 来回切换 对象的形式创建 // createreducer 将书写格式创建成rudex认识的reducer export function createreducer({state: initstate, reducer}) { return (state = initstate, action) => { return reducer.hasownproperty(action.type) ? reducer[action.type](state, action) : state } } // 创建页面级别的store const user_info_fetch_memo = 'user_info_fetch_memo' const store = { // 初始化数据 state: { memo: 9, test: 0 }, action: { async fetchmemo (params) { return { type: user_info_fetch_memo, callapi: {url: 'http://stage-mapi.yimifudao.com/statistics/cc/kpi', params, config: {}}, payload: params } }, ... }, reducer: { [user_info_fetch_memo] (prevstate = {}, {payload}) { console.log('reducer--->',payload) return { ...prevstate, memo: payload.memo } }, ... } } export default createreducer(store) export const action = store.action // 最终在模块界别组合 [当然模块也有公共的数据(见home模块下的demo写法)] import {combinereducers} from 'redux' import info from './info/store' export default combinereducers({ info, 。。。 }) // 最终rudex文件夹下的store.js 会去取所有模块下的store.js 组成一个大的store也就是我们最终仓库 // --------使用------ // 首先在app.js中将store和app关联 import { createstore } from 'redux' import { provider } from 'react-redux' // reducer即我们最终 import reducer from './redux/store.js' // 用户异步action的中间件 import middleware from './utils/middleware.js' let store = createstore(reducer, middleware) <provider store={store}> 。。。 </provider> // 然后组件调用 只需要在组件导出时候 使用connent链接即可 import react, {component} from 'react' import {connect} from 'react-redux' // 从页面级别的store中导出action import {action} from './store' class demo extends component { const handle = () => { // 触发action this.props.dispatch(action.fetchmemo({})) } render () { console.log(this.props.test) return <div onclick={this.handle}>ss</div> } } export default connect(state => ({ test: state.user.memo.test }) )(demo)
关于redux中间件
// 与其说redux中间件不如说action中间件 // 中间件执行时机 即每个action触发之前执行 // import { applymiddleware } from 'redux' import fetchproxy from './fetchproxy'; // 中间件 是三个嵌套的函数 第一个入参为整个store 第二个为store.dispatch 第三个为本次触发的action // 简单封装的中间件 没有对请求失败做过多处理 目的在与项错误处理机制给到页面处理 const middleware = ({getstate}) => next => async action => { // 此时的aciton还没有被执行 const {type, callapi, payload} = await action // 没有异步请求直接返回action if (!callapi) return next({type, payload}) // 请求数据 const res = await fetchproxy(callapi) // 请求数据失败 提示 if (res.status !== 200) return console.log('网络错误!') // 请求成功 返回data return next({type, payload: res.data}) } export default applymiddleware(middleware)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
基于vue框架手写一个notify插件实现通知功能的方法
-
EpiiAdmin 开源的php交互性管理后台框架, 让复杂的交互变得更简单!Phper快速搭建交互性平台的开发框架,基于Thinkphp5.1+Adminlte3.0+Require.js。
-
java实现分布式项目搭建的方法
-
tp5框架基于ajax实现异步删除图片的方法示例
-
基于Docker 搭建WordPress的方法
-
基于Windows 7(本地)和CentOS7.6(云端)的Minecraft服务器(无Forge/有Forge)搭建方法
-
如何搭建新的WPF项目框架
-
React项目动态设置title标题的方法示例
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之七使用JWT生成Token(个人见解)
-
从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之十一Swagger使用一