{"id":18470859,"url":"https://github.com/xrian/react-slim","last_synced_at":"2025-05-12T13:34:43.757Z","repository":{"id":143932485,"uuid":"167146400","full_name":"xrian/react-slim","owner":"xrian","description":"配置了react全家桶的Demo","archived":false,"fork":false,"pushed_at":"2019-05-07T18:43:59.000Z","size":485,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-02-16T18:43:50.497Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xrian.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-01-23T08:30:31.000Z","updated_at":"2019-05-07T18:44:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"17656096-e8d9-4cc0-b3be-86fdbede8978","html_url":"https://github.com/xrian/react-slim","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xrian%2Freact-slim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xrian%2Freact-slim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xrian%2Freact-slim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xrian%2Freact-slim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xrian","download_url":"https://codeload.github.com/xrian/react-slim/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253748287,"owners_count":21957900,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T10:15:04.780Z","updated_at":"2025-05-12T13:34:43.712Z","avatar_url":"https://github.com/xrian.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"一个基于[Create React App](https://github.com/facebook/create-react-app)搭建的**React全家桶**项目模板.\u003cbr /\u003e\n使用react-app-rewired增加自定义配置.\n\n## TODO List\n- [x] babel 自定义配置\n- [x] 开发模式代理API请求\n- [x] 项目目录别名(webpack alias)\n- [x] redux\n- [x] redux-saga(redux中间件)\n- [x] css预处理(sass,less)\n- [x] CSS模块样式\n- [x] react router\n- [x] 国际化(react-intl-universal)\n- [x] redux开发工具(redux-devtools-extension浏览器插件)\n- [x] 代码规范(eslint)\n- [x] UI库(antd)\n- [x] 装饰器\n- [ ] 代码分析\n- [ ] 服务器渲染\n- [ ] 代码拆分\n\n## 为什么会有这个仓库\n当你新开始一个项目react时,虽然有Create React App可以创建一个项目模板,但是它只是一个基础框架,并不能满足我们的实际开发需求 \u003cbr /\u003e\n如果想要完成一个大型项目,你需要不断的往项目里添加你需要的插件以实现你的需求.\u003cbr /\u003e\n但是,如果你一开始就知道你将来可能遇到什么困难,需要那些插件,在项目前期就配置在你的项目中,然后再进行开发,是否能加快你的开发速度呢? \u003cbr /\u003e\n\n## 前置条件\n- node version\u003e=8.0\n- 掌握HTML,CSS,JS相关基本知识\n- 了解React,ES2015\n\n## 使用\n\n#### 1) 克隆仓库代码到本地\n#### 2) 安装依赖\n``` bash\n$ npm i\n```\nor\n```\n$ yarn\n```\n#### 3) 启动开发服务器\n```\n$ npm start\n```\n#### 4) 打包生产环境代码\n```\n$ npm run build\n```\n\u003e 如果你有需要,可以在package.json中添加`homepage`字段,[详细说明](https://facebook.github.io/create-react-app/docs/deployment)\n\u003e ```\n\u003e \"homepage\": \"http://mywebsite.com/relativepath\",\n\u003e ```\n\n## 开发指南\n\n### 自定义babel配置\n在项目跟目录下有个`babel.config.js`,只需要修改文件中的内容,就能实现自定义babel配置\n\n### 开发模式代理API请求\n在package.json文件中新增`proxy`字段\n```\n\"proxy\": \"http://localhost:4000\",\n```\n手动配置代理功能随`react-scripts@2.0.0`更高版本提供,[详细使用文档](https://facebook.github.io/create-react-app/docs/proxying-api-requests-in-development);\n\n### 项目目录别名设置\n项目根目录下有个`config-overrides.js`文件,在`addWebpackAlias`函数中增加你想配置的别名即可\n注意: 如果新增了项目别名,记得修改eslint配置文件,添加新的别名配置.\n\u003e 目前已经配置为`src`的别名.如果你要引用src下面的文件夹,不需要使用../的方式层层返回再引用其他文件,你只需要直接从src开始调用即可\n\n比如:\n你当前文件为`src/views/index.js`,如果想引用`src/config/index.js`,在未配置别名前的写法是\n```\nimport Config from '../config/index';\n```\n在配置别名后的写法是\n```\nimport Config from 'src/config/index';\n```\n别名的好处就是,**无论你目前处于项目的哪个文件**,你都可以使用`src/config/index`引用到src/config/index.js\n\n### Redux\n我在src/reducers文件夹下写了一个index.js,该js文件会自动读取src/reducers下面夹下的全部文件,然后合并.当然,前提是你reducers文件夹下的文件默认导出Object具有以下格式\n```\n{\n  namespace: 'user',\n  initState,\n  actions,\n  reducer: {\n    [actions.setState]: (state, data) =\u003e ({\n      ...state,\n      ...data,\n    }),\n  },\n}\n```\nnamespace的值是redux的store中的key \u003cbr /\u003e\ninitState的值是redux中store的初始状态值 \u003cbr /\u003e\nactions是将要改变store的事件名 \u003cbr /\u003e\nreducer是响应action并且表示如何改变state的函数.**建议在reducer对象中使用方括号命名法,保证actions和reducer数据一致性** \u003cbr /\u003e\n[更多资料](https://redux.js.org/) \u003cbr/\u003e\n如果你不喜欢这样的写法,你可以使用更适合你的写法,不过,要记得修改`src/index.js`中`createStore()`的参数\n\n### [redux-saga](https://redux-saga.js.org/)\nredux-saga主要是用来处理异步更新redux的情况.可以使用你自己想要的方式使用redux-saga或者按照我已完成的功能来更新state \u003cbr /\u003e\n我编写了一个工具类`src/utils/sagaDecorator.js`,主要实现了,可以通过装饰器的写法,将函数注入到redux-saga中. \u003cbr /\u003e\n使用方法如下: \u003cbr /\u003e\n在src/services目录下新建一个js文件,文件默认导出一个class类\n```\nexport default class Class {}\n```\n然后导入`src/utils/sagaDecorator.js`文件,在class类的函数上使用sagaDecorator中提供的装饰器函数即可\n```\nimport { TakeEvery, TakeLatest, TakeLeading, Throttle } from 'src/utils/sagaDecorator';\n\nexport default class Class {\n  @TakeEvery('TEST_ACTIONS')\n  static* test(){\n  }\n}\n```\n\u003e 上面的代码,会产生下面的效果. \u003cbr/\u003e\n\u003e 项目启动后,会自动使用takeEvery函数监视所有`TEST_ACTIONS`操作,并执行test函数中的内容\n\n项目启动时,会执行`src/services/index.js`中的forkByDecorator函数,只要是src/services目录下的文件,默认导出的class中如果包含有被sagaDecorator文件中函数装饰过的方法,则会自动加载到redux-saga任务中.\u003cbr/\u003e\n\u003e 我基于antd的Modal组件,实现了一个promise模态框,src/components/alert文件夹下,在saga函数中,可以使用`yield call(Modal.success, 'success');`的形式弹出模态框,给予用户提示\n\n如果想自己实现saga的功能,你也可以按照你自己的写法实现,只需要最后在src/index.js中`sagaMiddleware.run();`你的自己都代码即可\n\n### CSS预处理\n项目已经配置了scss以及less插件,只需要在创建css文件时以`.scss`或者`.less`为后缀名即可\n\n### CSS模块样式\n\u003e 在`react-scripts@2.0.0`更高版本已经自带css module功能,只需要在创建css文件时采用`[name].module.css`类似的命名格式即可. \u003cbr /\u003e\n\n如果你在使用scss或者less,并且想使用css模块功能,那么文件命名应该是`[name].module.scss或[name].module.sass或[name].module.less`.\n示例:\n```\nimport React, { Component } from 'react';\nimport styles from './Button.module.css'; // Import css modules stylesheet as styles\n\nclass Button extends Component {\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cbutton className={styles.error}\u003e单个class类名\u003c/button\u003e\n        \u003cbutton className={`${styles.success} ${styles.button}`}\u003e拥有多个class类名\u003c/button\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n```\n\n### react router\n在src/config文件下有个routerConfig.js,里面的代码表示各个页面对应的参数.\n如果你不喜欢,你可以自己定义路由信息.\n\u003e 建议❗: 将各个页面对应的URL作为变量导出,当其他地方需要用到跳转时,直接使用该URL变量,而不是在代码中使用URL字符串常量.\u003cbr/\u003e\n\u003e ❌如果跳转页面的时候使用字符串常量,那么后期在维护或者重构的时候,需要修改URL,那么则需要一个个文件去查找引用.\n\n在`src/views/index.js`中,使用率Switch标签和Route标签,将每个页面都遍历出来,当有匹配的URL时,则跳转到对应的页面.\u003cbr/\u003e\n你也可以按照你喜欢的方式控制路由展示,具体使用方法请参考[react-router](https://reacttraining.com/react-router/core/guides/philosophy)\n\n\u003e 因为已经配置了connected-react-router, 如果要在redux中进行页面跳转,可以参考下面的代码.\n\u003e ```\n\u003e import { put, call } from 'redux-saga/effects';\n\u003e import { push } from 'connected-react-router';\n\u003e import { loginPage } from 'src/config/routerConfig';\n\u003e import UserReducer from 'src/reducers/user';\n\u003e\n\u003e const { actions } = UserReducer;\n\u003e\n\u003e export default class Class {\n\u003e   @TakeEvery(actions.gotoLogin)\n\u003e   static* gotoLogin({ data }) {\n\u003e     // 跳转登录页面\n\u003e      yield put(push(loginPage.url));\n\u003e   }\n\u003e }\n\u003e ```\n\n### 代码规范(eslint)\n在项目根目录下,有个`.eslintrc.js`文件,该文件是eslint的配置文件.\u003cbr/\u003e\n目前已配置的功能:\n1. 使用babel-eslint作为解析规则\n2. 在eslint中使用`import/resolver`插件,用来忽略webpack配置的别名,\n3. 配置了airbnb的代码风格,如果你不喜欢(可以修改为其他的代码规范或者自定义代码检查规则)\n\u003e 如果在代码中,你要单独忽略某些eslint提示的错误,可以使用下面写法\n\u003e ```\n\u003e /* eslint 规则名:0 */\n\u003e 你的代码;\n\u003e ```\n\u003e 示例:\n\u003e ```\n\u003e /* eslint no-underscore-dangle:0 */ // 忽略不能使用_命名的报错\n\u003e const _id = '';\n\u003e ```\n\n### 国际化(react-intl-universal)\n国际化插件使用react-intl-universal实现.\n如果需要使用国际化功能,在页面显示前,需要执行初始化操作\n```\nimport intl from 'react-intl-universal';\n\n// 国际化数据对象\nconst locales = {\n  \"en-US\": require('./locales/en-US.js'),\n  \"zh-CN\": require('./locales/zh-CN.js'),\n};\n\n// 初始化操作\nintl.init({ // init返回的是一个promise对象,初始化成功后会resolve返回.\n  currentLocale: 'en-US', // 当前使用的语言\n  locales,\n}).then((res)=\u003e {\n  // 初始化完成后,就可以使用intl.get方法获取国际化对象中的值,并且可以使用defaultMessage函数设置默认值.\n  intl.get('message').defaultMessage('hello');\n});\n```\n如果需要切换当前使用语言,只需要重新执行`intl.init({currentLocale: '需要切换到语言',locales})`方法就行 \u003cbr/\u003e\n[具体使用文档](https://github.com/alibaba/react-intl-universal)\n\n### redux开发工具\n在项目中配置了redux-devtools-extension插件,只需要在浏览器中安装Redux DevTools插件,就可以在F12开发者工具栏看到一个新的TAB标签栏`redux`.\n![Redux DevTools](https://lh3.googleusercontent.com/wfhSnnYEQc3TCXbRTpTloa-XZesgDt0xAogzGoLF1BUCU04aYhdwAjueJYTtDxfRiqjUfC539g=w640-h400-e365)\n\n\n### UI库(antd)\n因为已经配置了babel-plugin-import插件,所以,你只需要直接引用antd的组件就行\n```\nimport { Button } from 'antd';\n```\nantd 组件的 js 和 css 代码只都会按需加载.\n[antd使用文档](https://ant.design/docs/react/getting-started-cn)\n\n### 装饰器\n目前该项目已经配置了`@babel/plugin-proposal-decorators`插件和`@babel/plugin-proposal-class-properties`插件,你可以自由的使用装饰器\n1. 类装饰\n2. 类属性装饰器\n3. 类方法装饰器\n装饰器具体使用方式,可以参考[阮一峰的ES6入门](http://es6.ruanyifeng.com/#docs/decorator)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxrian%2Freact-slim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxrian%2Freact-slim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxrian%2Freact-slim/lists"}