这是一个非常不错的脚手架,支持目前非常主流的一些特性
webpack4 + react + react-router-dom + react-redux + rematch + antd-moblie + less + typescript + axios + autoprefixer + 按需加载 + 报错处理 + loading + lazy + precommit + tslint
Step 1. 确保你的机器全局安装 Node.js
, yarn
Step 2. 克隆这个库来启动你的项目
yarn
yarn start
Step 3. 本地地址 http://localhost:8888
yarn start
- VSCode
- VSCode 扩展: EditorConfig, Prettier, TSLint
- Chrome 扩展工具:
Redux DevTools
&React Developer Tools
由于一些外部因素前端代码中需要用硬代码或者非常规处理方式时需要在相应代码中添加注释 // APOLLOHACK
以便于之后全局查找替换
import { request, Api } from '../api'
export const demo = {
state: {
data: 0,
},
reducers: {
getData(state, payload) {
return { data: state.data + 1 }
},
},
effects: dispatch => ({
getByAsync: async params => {
const data = request.post(Api.test)
dispatch.demo.getData(data)
},
}),
}
import { connect } from 'react-redux'
import * as React from 'react'
const MyFallbackComponent = props => <pre>{props.error.message}</pre>
const connectRedux = (key: string, component: any) => {
const mapState = (state: any) => ({
data: state[key],
})
const mapDispatch = data => ({ ...data[key] })
return connect(
mapState,
mapDispatch,
)(component)
}
export const mConnect = (key: string, Component: any) => {
class WithErrorHandler extends React.Component<any, any> {
constructor(props) {
super(props)
this.state = {
hasError: false,
error: null,
errorInfo: null,
}
}
componentDidCatch(error, info) {
this.setState({ hasError: true, error, errorInfo: info })
}
render() {
if (this.state.hasError) {
const { error, errorInfo } = this.state
return <MyFallbackComponent {...this.props} error={error} errorInfo={errorInfo} />
}
return <Component {...this.props} />
}
}
return connectRedux(key, WithErrorHandler)
}
import * as React from 'react'
import { Route, Switch } from 'react-router-dom'
const lazy = React.lazy
const Suspense = React.Suspense
const Status = ({ code, children }: any) => (
<Route
render={({ staticContext }: any) => {
if (staticContext) {
staticContext.status = code
}
return children
}}
/>
)
const NotFound = (): any => (
<Status code={404}>
<div>
<h1>抱歉,页面消失了</h1>
</div>
</Status>
)
export default class Router extends React.PureComponent {
render() {
return (
<Suspense fallback="loading...">
<Switch>
<Route exact path="/" render={() => 'start'} />
<Route path="/test" component={lazy(() => import('./Demo'))} />
<Route component={NotFound} />
</Switch>
</Suspense>
)
}
}
{
"tslint.autoFixOnSave": true,
"tslint.configFile": "../ts-react.json",
"editor.formatOnSave": true,
"prettier.semi": false,
"prettier.trailingComma": "all",
"prettier.singleQuote": true,
"prettier.printWidth": 120
}
{
test: /.less$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
{
loader: 'less-loader',
options: {
modifyVars: {
'@brand-primary': '#FF9000',
'@color-text-base': '#FF9000',
'@primary-button-fill': '#FF9000',
'@primary-button-fill-tap': '#FF9000',
},
javascriptEnabled: true,
},
},
],
},
Version: webpack 4.28.2
Time: 1733ms
Built at: 2018-12-27 16:42:44
Asset Size Chunks Chunk Names
./index.html 1000 bytes [emitted]
0.js 360 KiB 0 [emitted]
1.js 15.1 KiB 1 [emitted]
2.js 6.12 KiB 2 [emitted]
main.js 630 KiB main [emitted] main
vendor.js 971 KiB vendor [emitted] vendor
Entrypoint main = vendor.js main.js
[./node_modules/axios/lib/adapters/xhr.js] 6.03 KiB {main} [built]
[./node_modules/axios/lib/axios.js] 1.34 KiB {main} [built]
[./node_modules/axios/lib/cancel/Cancel.js] 385 bytes {main} [built]
[./node_modules/axios/lib/cancel/CancelToken.js] 1.21 KiB {main} [built]
[./node_modules/axios/lib/cancel/isCancel.js] 102 bytes {main} [built]
[./node_modules/axios/lib/core/Axios.js] 2.14 KiB {main} [built]
[./node_modules/axios/lib/core/InterceptorManager.js] 1.22 KiB {main} [built]
[./node_modules/axios/lib/core/dispatchRequest.js] 2.15 KiB {main} [built]
[./node_modules/axios/lib/defaults.js] 2.38 KiB {main} [built]
[./node_modules/axios/lib/helpers/bind.js] 256 bytes {main} [built]
[./node_modules/axios/lib/helpers/normalizeHeaderName.js] 357 bytes {main} [built]
[./node_modules/axios/lib/helpers/spread.js] 564 bytes {main} [built]
[./node_modules/axios/lib/utils.js] 7.36 KiB {main} [built]
[./src/models/demo.ts] 1.64 KiB {main} [built]
[./src/models/index.ts] 47 bytes {main} [built]
+ 310 hidden modules
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint undefined = ./index.html
4 modules
ℹ 「wdm」: Compiled successfully.
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
},
{
loader: 'postcss-loader',
options: {
plugins: [
require('autoprefixer')({
browsers: [
'iOS >= 7',
'Android >= 4.1',
'last 10 Chrome versions',
'last 10 Firefox versions',
'Safari >= 6',
'ie > 8',
],
}),
],
},
},
],
effects: dispatch => ({
getByAsync: async params => {
const data = request.post(Api.test)
dispatch.demo.getData(data)
},
}),