- 使用 customize-cra 在不 eject 配置的情况下自定义配置 - postcss-px2rem css 的 px 转换 rem - TerserPlugin 生产环境关闭 console - externals 构建的时候不打包 dependencies - CopyWebpackPlugin 通过拷贝的方式在 html 中引入源码 - CompressionPlugin 构建生产环境的 gzip 包 - 在 html 中使用 nodejs fs 模块添加 loading.html - react-transition-group + react-router-dom 实现路由进出场动画 - 抽取 dependencies 主要的依赖,webpack-bundle-analyzer 分析就 1kb(gzip)- dependencies:
"react": "^16.10.2", "react-dom": "^16.10.2",
"react-router-dom": "^5.1.2""react-transition-group": "^4.3.0"- 基于create-react-app脚手架在ejetc的情况下自定义配置
customize-cra 自定义配置webpackwebpackbar 开发的时候构建进度条
webpack-bundle-analyzer 生成环境构建分析webpack-build-notifier 构建提示插件postcss-px2rem px 转换 rem插件terser-webpack-plugin 处理js插件 比如关闭生成环境console输出compression-webpack-plugin 构建gzip压缩包 防止后端没有开启压缩copy-webpack-plugin 拷贝代码- 如果做到webpack-bundle-analyzer 分析插件只有1kb方案
config.externals = { ...config.externals, react: 'React', 'react-dom': 'ReactDOM', 'react-router-dom': 'ReactRouterDOM', 'react-transition-group': 'ReactTransitionGroup' };将所有的依赖抽离出来不再构建,使用拷贝插件将源码拷贝至打包目录
new CopyWebpackPlugin( [ './node_modules/react/umd/react.production.min.js', './node_modules/react-dom/umd/react-dom.production.min.js', './node_modules/react-router-dom/umd/react-router-dom.min.js', './node_modules/react-transition-group/dist/react-transition-group.min.js', './src/assets/js/flexible.min.js' ].map(item => ({ from: path.resolve(__dirname, item), to: './static/js' })) ),在index.html 页面通过环境判断
<% if(process.env.NODE_ENV === "production"){ %> <script src="./static/js/react.production.min.js"></script> <script src="./static/js/react-dom.production.min.js"></script> <script src="./static/js/react-router-dom.min.js"></script> <script src="./static/js/react-transition-group.min.js"></script> <script src="./static/js/flexible.min.js"></script> <% } else {%> <script src="./static/js/flexible.min.js" defer></script> <% } %>在首屏加载loading 挂载在root下 能在立即加载loading 当代码一旦加载开始渲染也就关闭了
<div id="root"> <%= require('fs').readFileSync('loading.html') %> </div>关闭sw
config.plugins = config.plugins.filter(item => item.constructor.name !== 'ManifestPlugin' && item.constructor.name !== 'GenerateSW');使用useReducer, createContext管理状态
import React, { useReducer, createContext } from 'react';const initialState = { count: 0};const reducer = (state, action) => { switch (action.type) { case 'INCREMENT': return { count: state.count + 1 }; case 'DECREMENT': return { count: state.count - 1 }; default: throw new Error('action 错误'); }};export const GlobalContext = createContext();export const ContextProvider = ({ children }) => ( <GlobalContext.Provider value={useReducer(reducer, initialState)}> {children} </GlobalContext.Provider>);路由的出入场动画,app 中可以使用内存路由MemoryRouter
<MemoryRouter initialEntries={config.map(item => item.path)} initialIndex={0}> <Transition> {config.map(item => ( <Route key={item.path} {...item} /> ))} </Transition> </MemoryRouter>import React from 'react';import { TransitionGroup, CSSTransition } from 'react-transition-group';import { withRouter, Switch } from 'react-router-dom';import './style.css';const ANIMATION_MAP = { PUSH: 'forward', // 前进 POP: 'back' //后退};const Transtion = props => ( <TransitionGroup className={'router-wrapper'} childFactory={child => React.cloneElement(child, { classNames: ANIMATION_MAP[props.history.action] }) } > <CSSTransition key={props.location.pathname} classNames="fade" timeout={300} > <View {...props} /> </CSSTransition> </TransitionGroup>);const View = React.memo(({ location, children }) => ( <Switch location={location}>{children}</Switch>));export default withRouter(Transtion);利用路由中的action 使用前进后退,使用css动画
.router-wrapper { height: 100%; width: 100%;}/* 路由前进时的入场/离场动画 */.forward-enter { z-index: 1; opacity: 0.7; transform: translateX(100%);}.forward-enter-active { z-index: 1; opacity: 1; transform: translateX(0); transition: all 350ms;}.forward-exit { transform: translateX(0); opacity: 1;}.forward-exit-active { opacity: 0.7; transform: translateX(-100%); transition: all 350ms;}/* 路由后退时的离场动画/入场 */.back-enter { z-index: 1; opacity: 0.7; transform: translateX(-100%);}.back-enter-active { z-index: 1; opacity: 1; transform: translateX(0); transition: all 350ms;}.back-exit { transform: translateX(0); opacity: 1;}.back-exit-active { opacity: 0.7; transform: translate(100%); transition: all 350ms;}