Commit aa3739de authored by 前端-许佳敏's avatar 前端-许佳敏

init

parents
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab
# https://umijs.org/zh-CN/docs/env-variables
PORT=4396
\ No newline at end of file
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/npm-debug.log*
/yarn-error.log
/yarn.lock
/package-lock.json
# production
/dist
# misc
.DS_Store
# umi
/src/.umi
/src/.umi-production
/src/.umi-test
/.env.local
registry = "http://10.0.0.21:8081/repository/npm-group/"
\ No newline at end of file
**/*.md
**/*.svg
**/*.ejs
**/*.html
package.json
.umi
.umi-production
.umi-test
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 80,
"overrides": [
{
"files": ".prettierrc",
"options": { "parser": "json" }
}
]
}
## god-template
### 为数商云&醒电构建项目提供react脚手架模板
- god页面模板, 依赖于[umi](https://umijs.org/), 更多配置可以查看
- god组件库[文档](http://10.0.0.22:8080/)
\ No newline at end of file
import { defineConfig } from 'umi';
import routes from './router'
import proxy from './proxy'
import theme from './theme.config'
export default defineConfig({
title: 'God-Template',
layout: {},
locale: {
antd: true,
// 默认情况下,当前语言环境的识别按照:localStorage 中 umi_locale 值 > 浏览器检测 > default 设置的默认语言 > 中文
baseNavigator: true,
},
nodeModulesTransform: {
type: 'none',
},
routes,
extraBabelPlugins: [
['import', { libraryName: 'antd', libraryDirectory: 'es', style: true }],
['import', { libraryName: 'god', libraryDirectory: 'es', style: true }]
],
history: {
type: 'hash', // 'brower' | 'hash'
},
// 用于
analyze: {
analyzerMode: 'server',
analyzerPort: 8888,
openAnalyzer: true,
// generate stats file while ANALYZE_DUMP exist
generateStatsFile: false,
statsFilename: 'stats.json',
logLevel: 'info',
defaultSizes: 'parsed', // stat // gzip
},
// 自定义修改webpack配置
chainWebpack(memo, { env, webpack, createCSSRule }) {
},
cssLoader: {
localsConvention: 'camelCase', // 将style中的class由 .foo-body 转化为fooBody调用
},
cssModulesTypescriptLoader: {
mode: 'emit'
},
dynamicImport: {
loading: '@/components/Loading'
},
// icon
favicon: '',
hash: true,
/**
* 会自动添加到网页html的顶部
*/
metas: [],
plugins: [], // 配置项的名字通常是插件名去掉 umi-plugin- 或 @umijs/plugin 前缀。
proxy,
/**
* 配置 webpack 的 publicPath。当打包的时候,webpack 会在静态文件路径前面添加 publicPath 的值
* 当你需要修改静态文件地址时,比如使用 CDN 部署,把 publicPath 的值设为 CDN 的值就可以
*/
publicPath: '/',
/**
* https://umijs.org/zh-CN/config#theme
* 配置主题,实际上是配 less 变量。
*/
theme,
});
\ No newline at end of file
export default {
'/api': {
'target': 'http://jsonplaceholder.typicode.com/',
'changeOrigin': true,
'pathRewrite': { '^/api' : '' },
}
}
\ No newline at end of file
/**
* @description 路由配置页, 更多配置可查看 https://umijs.org/zh-CN/docs/routing#routes
*/
const router = [
{ path: '/', component: '@/pages/index' },
]
export default router
\ No newline at end of file
export default {
}
\ No newline at end of file
{
"name": "god-template",
"scripts": {
"start:analyze": "ANALYZE=1 umi dev",
"start": "umi dev",
"build": "umi build",
"build:analyze": "ANALYZE=1 umi build",
"postinstall": "umi generate tmp",
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
"test": "umi-test",
"test:coverage": "umi-test --coverage"
},
"lint-staged": {
"*.{js,jsx,less,md,json}": [
"prettier --write"
],
"*.ts?(x)": [
"prettier --parser=typescript --write"
]
},
"license": "MIT",
"dependencies": {
"@umijs/preset-react": "1.x",
"@umijs/test": "^3.2.0",
"god": "^1.1.21",
"lint-staged": "^10.0.7",
"mobx": "^5.15.4",
"mobx-react": "^6.2.2",
"prettier": "^1.19.1",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"umi": "^3.2.0",
"yorkie": "^2.0.0"
}
}
import { IRoutes } from '.';
import { history, RequestConfig } from 'umi';
import React from 'react'
import MobxProvider from './store'
import 'mobx-react-lite/batchingForReactDom'
let extraRoutes: never[] = []
/**
* @description 配置函数,对已配置的路由做修改, 一般与render函数一起结合可根据接口动态配置路由
* @author xjm
* @date 2020-05-20
* @export
* @param {IRoutes} { routes } 预先配置好的路由
* @example
* routes.unshift({
* path: '/foo',
* exact: true,
* component: require('/extraRoutes/foo').default,
* });
*
*/
// export function patchRoutes({ routes }: IRoutes) {
// routes.concat(extraRoutes as [])
// }
/**
* @description 用于渲染前所做的事, 比如动态路由,权限校验等
* @author xjm
* @date 2020-05-20
* @export
*/
// export function render(oldRender:Function) {
// // 做动态路由
// fetch('/api').then((res: any) => {
// extraRoutes = res.routes
// })
// // 做权限校验
// fetch('/auth').then((res: any) => {
// if (res.isLogin) {
// oldRender()
// } else {
// history.push('/login')
// }
// })
// }
/**
* @description 在初始加载和路由切换时做一些事情
* @author xjm
* @date 2020-05-20
* @export
* @param {*} { routes, matchedRoutes, location, action }
*/
// export function onRouteChange({ routes, matchedRoutes, location, action }) {
// console.log(routes, matchedRoutes, location, action)
// }
/**
* @description 可对最外层做容器包裹
* @borrows https://umijs.org/zh-CN/docs/runtime-config#onroutechange-routes-matchedroutes-location-action-
* @author xjm
* @date 2020-05-20
* @export
* @param {*} container
* @returns
*/
export function rootContainer(container) {
return React.createElement(MobxProvider, null, container);
}
/**
* 用于个性化接口数据返回格式
* @todo 由于要开启useRequest hooks 目前没找到应用该请求的最佳实践,建议不用开启这个配置
*/
// export const request: RequestConfig = {
// errorConfig: {
// adaptor(resData) {
// return {
// ...resData,
// code: resData.ok,
// }
// }
// },
// middlewares: [
// async function printRequest(ctx, next) {
// console.log('发起了请求')
// console.log(ctx)
// await next()
// }
// ],
// requestInterceptors: [],
// responseInterceptors: []
// }
\ No newline at end of file
import React, { Component } from 'react'
class Loading extends Component {
render() {
return (
<div>loading</div>
)
}
}
export default Loading
\ No newline at end of file
import { useRequest } from 'umi'
import React from 'react'
import AccountController from '@/services/account'
const RequestDemo:React.FC<{}> = (props) => {
const { data, loading } = useRequest(AccountController.add)
return <div>{loading ? 'loading' : data}</div>
}
export default RequestDemo
\ No newline at end of file
export const NOT_CHANGE_VALUE = 'hello, world'
\ No newline at end of file
/**
*
* 全局响应状态码定义
*
*/
const messages = {
200: '请求成功',
404: '接口不存在'
}
export default messages
\ No newline at end of file
export interface IRoutes {
routes: []
}
/**
* @todo
* @description 定义请求成功的接口模型
* @author xjm
* @date 2020-05-25
* @export
* @interface IRequest
*/
export interface IRequest {
}
/**
* @todo
* @description 定义请求失败时的接口模型
* @author xjm
* @date 2020-05-25
* @export
* @interface IRequestError
*/
export interface IRequestError {
}
\ No newline at end of file
export default {
'demo': 'hello'
}
\ No newline at end of file
export default {
'demo': '你好'
}
\ No newline at end of file
export interface IUserModule {
name: string;
age: number;
printNameAndAge: string;
setName(name: string):void;
getAsyncAge(): Promise<number>;
}
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>God-Template</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
\ No newline at end of file
.normal {
}
.title {
font-size: 24px;
color: #666;
}
import React, {Component, useState, useRef, useEffect} from 'react';
import { Button } from 'god';
import styles from './index.less';
import { inject, observer } from 'mobx-react'
import { IUserModule } from '@/module/userModule'
import { IStore } from '@/store';
import RequestDemo from '@/components/Request';
export interface IIndexProps {
userStore?: IUserModule
}
@inject((store: IStore) => ({
userStore: store.userStore
}))
@observer
class Index extends Component<IIndexProps, {}> {
render() {
const { name, setName, printNameAndAge, getAsyncAge } = this.props.userStore!
return <div>
<h3>{name}</h3>
<h3>{printNameAndAge}</h3>
<Button onClick={() => {setName('Jim')}}>change name</Button>
<Button onClick={() => {getAsyncAge()}}>async change name</Button>
<RequestDemo/>
</div>
}
}
export default Index
declare namespace API {
export interface currentUser {
name?: string;
age?: number;
}
}
\ No newline at end of file
import BaseService from "../baseService";
const mockData = () => {
return new Promise(resolve => {
setTimeout(() => {
resolve({
data: 10,
success: true
})
}, 2000)
})
}
class AccountController extends BaseService {
constructor() {
super()
}
async add() {
try {
const data = await mockData()
return data
} catch(err) {
return err
}
}
async delete() {
}
async update() {
}
async getList() {
}
}
export default new AccountController()
\ No newline at end of file
/**
* @todo
* @description 公共请求方法
* @author xjm
* @date 2020-05-25
* @class BaseService
*/
class BaseService {
protected success(data) {
return Promise.resolve(data)
}
protected error(err) {
return Promise.reject(err)
}
}
export default BaseService
\ No newline at end of file
import AccountCtroller from './account'
const Services = {
AccountCtroller
}
export default Services
\ No newline at end of file
import UserStore from './user'
import React from 'react';
import { Provider } from 'mobx-react'
import { IUserModule } from '@/module/userModule';
/**
*
* mobx使用说明
* @observable 只有被这个装饰后才能监听数据变化
* @computed 是根据@observable的数据计算属性
* @action 只能是同步处理数据,不能异步
* @action.bound 可以保证装饰的函数内部this永远指向当前store
* runInAction 是在action中做异步处理时需要调用的
*
* 官方文档:https://mobx.js.org/
* 中文文档:https://cn.mobx.js.org/
*
*
*/
export interface IStore {
userStore: IUserModule
}
const store = {
userStore: new UserStore
}
const MobxProvider:React.FC = (props) => {
return <Provider {...store}>{props.children}</Provider>
}
export default MobxProvider
\ No newline at end of file
import {action, computed, observable, runInAction} from 'mobx'
import { IUserModule } from '@/module/userModule';
const demoAsync = ():Promise<number> => new Promise(resolve => setTimeout(() => resolve(100), 2000))
class UserStore implements IUserModule {
@observable public name: string = 'Bob';
@observable public age: number = 0;
// 当有时需要拼接状态,但又不希望改变原有状态,可以采取如下, 类似vue中的computed
@computed
public get printNameAndAge(): string {
return `hello, ${this.name}, your age is ${this.age}`
}
// 可以改变存在name中的值
@action.bound
public setName(name: string) {
this.name = name;
}
// 异步修改数据, 需要使用bound,保持this指向当前store
@action.bound
public async getAsyncAge() {
try {
const result = await demoAsync()
runInAction(() => {
this.age = result
})
return result
} catch (error) {
return error
}
}
}
export default UserStore
\ No newline at end of file
function isArray(arr: any) {
return Array.isArray(arr)
}
function isObject(obj: any) {
return Object.prototype.toString.call(obj) === '[object Object]'
}
export default {
isArray,
isObject
}
\ No newline at end of file
import { extend } from 'umi-request';
import responseCode from '@/constants/responseCode'
/**
*
* umi-request文档 https://github.com/umijs/umi-request/blob/master/README_zh-CN.md
*
*/
/**
* 配置request请求时的默认参数, 底层使用fetch进行请求
*/
const request = extend({
timeout: 30 * 1000,
credentials: 'include', // 默认请求是否带上cookie
});
export default request;
\ No newline at end of file
{
"compilerOptions": {
"experimentalDecorators": true,
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"importHelpers": true,
"jsx": "react",
"noImplicitAny": false,
"esModuleInterop": true,
"sourceMap": true,
"baseUrl": "./",
"strict": true,
"paths": {
"@/*": ["src/*"],
"@@/*": ["src/.umi/*"]
},
"allowSyntheticDefaultImports": true
},
"include": [
"mock/**/*",
"src/**/*",
"config/**/*",
".umirc.ts",
"typings.d.ts"
],
"exclude": [
"node_modules/**/*"
]
}
declare module '*.css';
declare module '*.less';
declare module "*.png";
declare module '*.svg' {
export function ReactComponent(props: React.SVGProps<SVGSVGElement>): React.ReactElement
const url: string
export default url
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment