React项目开发过程中的利器们DevTools
古话说的好,工欲善其事,必先利其器。意思是说:工匠想要使他的工作做好,一定要先让工具锋利。比喻要做好一件事,准备工作非常重要,项目开发也是一样。接下来就对React全家桶开发过程用到的“利器”进行用法及原理说明。
项目源码:https://github.com/wlc534/react-r3-saga
React Developer Tools
首先要介绍的是最常见React Developer Tools,只要打算用React技术栈进行项目开发的developers都应该安装了这款插件。
用已经安装插件的浏览器去打开不同网页,会呈现三种不同的状态,看到熟悉的图标了吧。
从上到下依次是:【蓝色】生成环境中的react、【红色+小虫子】开发环境中的react、【灰色】没用react技术开发。我们知道React是在内存中生成virtual DOM,之后挂载到真实的DOM中,在chrome 开发者工具中Elements标签中只能看到普通的html结构。
对于刚接触这种开发模式同学是不是有这样的疑问,自定义的component被渲染到哪儿、或者是想调试自定义组件。这个问题Facebook的工程师也想到并开发出有用的 Chrome浏览器扩展。通过它我们可以查看应用程序的 React 组件分层结构,而不是更加神秘的浏览器 DOM 表示。说到调试,首先要明确现在浏览器还不能完全解析ES6,所以就有了Babel这样的compiler。
在React中有两次转换:ES6、7、8(TS)=>js react.element=> DOM Elements
关于调试要确保chrome及项目(Webpack中开启devtool: 'inline-source-map')是开启状态。
在react标签下能看见自定义的组件,选中不同的组件还能看到Props、State等信息并且可以编辑修改,结果会实时呈现到页面上。
设置好source-map后可以愉快的进行debug
redux-logger
大家都知道React只是纯V层的库,要想真正用于项目中,就必须结合其他的库如:redux、react-router、redux-saga、redux-logger、redux-thunk、redux-promise、MobX等,才能发挥它的威力。接下来对redux-logger进行讲解。
Install
npm install --save redux-logger |
Tips:如果NPM安装慢,试试国内的CNPM 执行
npm config set registry=http://registry.npm.taobao.org |
淘宝 NPM 镜像:https://npm.taobao.org/
最近升级node版本,在进行 npm install 时 ,有时候node_modules下出现.staging相关字样
尝试以下解决方法:
- 删除 node_modules安装yarn,然后使用yarn安装npm包
- 强制清除npm指令 npm cache clean –f 再npm install
- 在windows系统下尝试以管理员运行命令行
Usage
import { applyMiddleware, createStore } from 'redux';
// Logger 用默认设置 import logger from 'redux-logger' const store = createStore( reducer, applyMiddleware(logger) ) |
效果图如上,展示redux中reducer【prev state+action=>next state】,老的state加action生成新的state,并能看到相应reducer中字段值,这样在开发过程中就能快速定位。
源码
redux-devtools
很多人都把redux-devtools与chrome 插件Redux DevTools搞混淆了。redux-devtools是要引入项目中的,具有侵入性。redux-devtools和Redux DevTools Extension也是不同的东西。
Install
npm install --save-dev redux-devtools redux-devtools-log-monitor redux-devtools-dock-monitor |
Usage
- redux-devtools:redux的开发工具包,而且DevTools支持自定义的 monitor 组件,所以我们可以完全自定义一个我们想要的 monitor 组件的UI展示风格,以下两个是我们示例中用到的。
- redux-devtools-log-monitor: 这是Redux Devtools 默认的 monitor ,它可以展示state 和 action 的一系列信息,而且我们还可以在monitor改变它们的值。
- redux-devtools-dock-monitor:这monitor支持键盘的快捷键来轻松的改变tree view在浏览器中的展示位置,比如不断的按‘ctrl + q’组合键可以让展示工具停靠在浏览器的上下左右不同的位置,按“ctrl+h”组合键则可以控制展示工具在浏览器的显示或隐藏的状态。
接下来我们在containers目录新增一个DevTools.js文件,并且设置monitor。
react-r3-saga /containers/DevTools.js
import React from 'react'; import { createDevTools } from 'redux-devtools'; import LogMonitor from 'redux-devtools-log-monitor'; import DockMonitor from 'redux-devtools-dock-monitor';
export default createDevTools( <DockMonitor toggleVisibilityKey='ctrl-h' changePositionKey='ctrl-q'> <LogMonitor /> </DockMonitor> ); |
在Store.js中
// 把多个 store 增强器从右到左来组合起来,依次执行 // 这个地方完全可以不用compose,演示一下compose的使用 const enhancer = compose( applyMiddleware(sagaMiddleware,thunk,logger), DevTools.instrument() );
const store=createStore(reducer,enhancer) |
一定记得在index.js文件引入这个容器组件<DevTools/>
import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import './index.css'; import DevTools from './containers/DevTools' import App from './App'; import store from './Store'
ReactDOM.render( <Provider store={store}> <div> <DevTools/> <App /> </div> </Provider>, document.getElementById('root') ); |
注意:在实际项目开发中时应该根据环境来确定<DevTools />组件的展示与否,示例中是在开发环境的演示,直接放在Provider里面。为什么说有侵入性从<DevTools> …</DevTools>
就能看出,直接在项目生成一个普通的div。此时并不需要 chrome 插件Redux DevTools配合。
更多操作:https://www.npmjs.com/package/redux-devtools
redux-devtools-extension
Install
npm install --save redux-devtools-extension chrome 插件(https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd ); Firefox 插件(https://addons.mozilla.org/en-US/firefox/addon/remotedev/ ) 从 v2.7, `window.devToolsExtension` 被命名`window.__REDUX_DEVTOOLS_EXTENSION__` / `window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__`. |
Usage
In case ESLint is configured to not allow using the underscore dangle, wrap it like so: ```diff + /* eslint-disable no-underscore-dangle */ const store = createStore( reducer, /* preloadedState, */ window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() ); + /* eslint-enable */ |
修改Store.js文件
import {createStore,combineReducers, applyMiddleware,compose} from 'redux' import createSagaMiddleware from 'redux-saga' import counter from './reducers/counter' import addInput from './reducers/addInput' import thunkReducer from './reducers/thunkReducer' import sagaReducer from './reducers/sagaReducer' import logger from 'redux-logger' import thunk from 'redux-thunk' import rootSaga from './sagas/sagas' import { composeWithDevTools } from 'redux-devtools-extension'
const sagaMiddleware =createSagaMiddleware() const reducer=combineReducers({ counter, addInput, thunkReducer, sagaReducer }) const store = createStore(reducer, /* preloadedState, */ composeWithDevTools( applyMiddleware(sagaMiddleware,thunk,logger) )); sagaMiddleware.run(rootSaga) export default store
|
此时页面自动刷新,chrome 插件Redux DevTools也自动高亮起来。与redux的Devtools模块不同,该工具主要依赖浏览器插件完成。模式也比Devtools简单点。由于是基于浏览器的,所以原生支持浏览器的右键菜单,窗口也是多样性,灵活性高很多,包含更多的功能。
Redux DevTools是一个非常棒的工具,它可以让你实时的监控Redux中唯一状态树的Store。支持Log monitor、Reset、Revert、Commit、Sweep、Inspector、Chart、‘时间旅行’、导入导出json等,以可视化的方式把抽象的store tree 清晰展示出来,提高开发效率。有兴趣的同学可以去看看这款插件的源码,里面也是用到了redux。
var compose = require('redux').compose;
exports.__esModule = true; exports.composeWithDevTools = ( typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : function() { if (arguments.length === 0) return undefined; if (typeof arguments[0] === 'object') return compose; return compose.apply(null, arguments); } );
exports.devToolsEnhancer = ( typeof window !== 'undefined' && window.__REDUX_DEVTOOLS_EXTENSION__ ? window.__REDUX_DEVTOOLS_EXTENSION__ : function() { return function(noop) { return noop; } } ); |
坑
一般的文章到此就该结束了。但这里还有一块要写。该用哪种方式要结合自己的项目去选择。我个人推荐用无侵入的插件。其实不然,chrome 插件是会注入到运行中的项目里。不然它怎么拿到项目整个的store tree呢。插件原理可以参看【动手做第一个Chrome插件】。就在写这篇文章的几个小时前,正常的运行的项目加上composeWithDevTools代码chrome控制台是报错的,在vscode中转义打包是没问题。这就是不按套路出牌。报错信息如下:
Uncaught TypeError: Cannot read property 'state' of undefined |
自己一直在找代码的问题,但用插件查看跑在本地antd pro是没有任何问题的,打消怀疑chrome插件是否有问题的想法。这很有欺骗性。毕竟antd pro 中用的是Dva进行状态管理。搜遍互联网也没找到问题所在。因为公司内网对部分网站进行屏蔽。邻座同事说 Firefox可以在内部安装插件,就尝试去装了最新版的插件,键入项目地址,在Firefox中没报错,跑起来。这样从侧面证明代码没问题。然后放在IE里也能跑起来。再次让我坚信问题出在chrome插件上。因为chrome浏览器中Redux DevTools有很长一段时间没更新,加上react-r3-saga是基于最新版本搭建的,出现不兼容情况。知道问题后通过手机共享热点找到最新Redux DevTools crx 安装到chrome,打开网页完美。
性能优化 webpack-bundle-analyzer可视化工具
Webpack进行打包,到底打了多少包,每个包有多大?webpack-bundle-analyzer这款插件可以帮助我们清晰展示。针对多余的包文件过大,剔除首次影响加载的效率问题进行剔除修改。
模块功能:
- 意识到你的文件打包压缩后中真正的内容
- 找出哪些模块组成最大的大小
- 找到错误的模块
- 优化它!
- 最好的事情是它支持缩小捆绑!它解析它们以获得实际大小的捆绑模块。它也显示他们的gzipped大小!
安装和使用
npm install --save-dev webpack-bundle-analyzer |
在webpack.config.js中:
let BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { plugins: [new BundleAnalyzerPlugin()] } |
默认的可选配置对象:
new BundleAnalyzerPlugin({ // 可以是`server`,`static`或`disabled`。 // 在`server`模式下,分析器将启动HTTP服务器来显示软件包报告。 // 在“静态”模式下,会生成带有报告的单个HTML文件。 // 在`disabled`模式下,你可以使用这个插件来将`generateStatsFile`设置为`true`来生成Webpack Stats JSON文件。 analyzerMode: 'server', // 将在“服务器”模式下使用的主机启动HTTP服务器。 analyzerHost: '127.0.0.1', // 将在“服务器”模式下使用的端口启动HTTP服务器。 analyzerPort: 8888, // 路径捆绑,将在`static`模式下生成的报告文件。 // 相对于捆绑输出目录。 reportFilename: 'report.html', // 模块大小默认显示在报告中。 // 应该是`stat`,`parsed`或者`gzip`中的一个。 // 有关更多信息,请参见“定义”一节。 defaultSizes: 'parsed', // 在默认浏览器中自动打开报告 openAnalyzer: true, // 如果为true,则Webpack Stats JSON文件将在bundle输出目录中生成 generateStatsFile: false, // 如果`generateStatsFile`为`true`,将会生成Webpack Stats JSON文件的名字。 // 相对于捆绑输出目录。 statsFilename: 'stats.json', // stats.toJson()方法的选项。 // 例如,您可以使用`source:false`选项排除统计文件中模块的来源。 // 在这里查看更多选项:https: //github.com/webpack/webpack/blob/webpack-1/lib/Stats.js#L21 statsOptions: null, logLevel: 'info' 日志级别。可以是'信息','警告','错误'或'沉默'。 })
|
启动服务
生产环境查看:npm run build --report 或 正常build 即可启动查看器
开发环境查看:webpack -p --progress 或启动正常devServer服务即可启动查看器!
以上就是开发项目过程中的可视化工具们。
发现问题、分析问题,解决问题、总结经验,希望这篇文章能帮到遇到同样问题的小伙伴!
项目源码:https://github.com/wlc534/react-r3-saga