分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

react看这篇就够了(react+webpack+redux+reactRouter+sass)

发布时间:2023-09-06 01:34责任编辑:郭大石关键词:webpack

本帖将对一下内容进行分享:

1、webpack环境搭建;

2、如何使用react-router;

3、引入sass预编译;

4、react 性能优化方案;

5、redux结合react使用;

6、fetch使用;

7、项目目录结构;

一、webpack配置,代码如下:

1、在根目录下新建一个webpack.config.js,这个为开发环境的webpack配置;因为得区分开发跟生产环境,所以还得新建一个webpack.production.config.js作为生产环境使用的配置文档,

webpack.config.js代码如下:

var path = require(‘path‘)var webpack = require(‘webpack‘)var HtmlWebpackPlugin = require(‘html-webpack-plugin‘);var ExtractTextPlugin = require(‘extract-text-webpack-plugin‘);var OpenBrowserPlugin = require(‘open-browser-webpack-plugin‘);// var nodeModulesPath = path.resolve(__dirname, ‘node_modules‘)// console.log(process.env.NODE_ENV)module.exports = { ???entry: path.resolve(__dirname, ‘app/index.jsx‘), ???output: { ???????path: __dirname + "/build", ???????filename: "bundle.js" ???}, ???resolve:{ ???????extensions:[‘‘, ‘.js‘,‘.jsx‘] ???}, ???module: { ???????// preLoaders: [ ???????// ????// 报错 ????? ???????// ????{test: /\.(js|jsx)$/, loader: "eslint-loader", exclude: /node_modules/} ???????// ], ???????loaders: [ ???????????{ test: /\.(js|jsx)$/, exclude: /node_modules/, loader: ‘babel‘ }, ???????????{ test: /\.scss$/, exclude: /node_modules/, loader: ‘style!css!postcss!sass‘ }, ???????????{ test: /\.css$/, exclude: /node_modules/, loader: ‘style!css!postcss‘ }, ???????????{ test:/\.(png|gif|jpg|jpeg|bmp)$/i, loader:‘url-loader?limit=10000‘ }, ?// 限制大小10kb ???????????{ test:/\.(png|woff|woff2|svg|ttf|eot)($|\?)/i, loader:‘url-loader?limit=10000‘} // 限制大小小于10k ???????] ???}, ???eslint: { ???????configFile: ‘.eslintrc‘ // Rules for eslint ???}, ???postcss: [ ???????require(‘autoprefixer‘) //调用autoprefixer插件,例如 display: flex ???], ???plugins: [ ???????// html 模板插件 ???????new HtmlWebpackPlugin({ ???????????template: __dirname + ‘/app/index.tmpl.html‘ ???????}), ???????// 热加载插件 ???????new webpack.HotModuleReplacementPlugin(), ???????// 打开浏览器 ???????new OpenBrowserPlugin({ ?????????url: ‘http://localhost:8888‘ ???????}), ???????// 可在业务 js 代码中使用 __DEV__ 判断是否是dev模式(dev模式下可以提示错误、测试报告等, production模式不提示) ???????new webpack.DefinePlugin({ ?????????__DEV__: JSON.stringify(JSON.parse((process.env.NODE_ENV == ‘dev‘) || ‘false‘)) ???????}) ???], ???devServer: { ???????/*proxy: { ?????????// 凡是 `/api` 开头的 http 请求,都会被代理到 localhost:3000 上,由 koa 提供 mock 数据。 ?????????// koa 代码在 ./mock 目录中,启动命令为 npm run mock ?????????‘/api‘: { ???????????target: ‘http://localhost:3000‘, ???????????secure: false ?????????} ???????},*/ ???????port: 8888, ???????contentBase: "./public", //本地服务器所加载的页面所在的目录 ???????colors: true, //终端中输出结果为彩色 ???????historyApiFallback: true, //不跳转 ???????inline: true, //实时刷新 ???????hot: true ?// 使用热加载插件 HotModuleReplacementPlugin ???}}

webpack.production.config.js代码如下:

var path = require(‘path‘)var webpack = require(‘webpack‘);var HtmlWebpackPlugin = require(‘html-webpack-plugin‘);var ExtractTextPlugin = require(‘extract-text-webpack-plugin‘);module.exports = { ?entry: { ???app: path.resolve(__dirname, ‘app/index.jsx‘), ???// 将 第三方依赖 单独打包 ???vendor: [ ?????‘react‘, ??????‘react-dom‘, ??????‘react-redux‘, ??????‘react-router‘, ??????‘redux‘, ??????‘es6-promise‘, ??????‘whatwg-fetch‘, ??????‘immutable‘ ???] ?}, ?output: { ???path: __dirname + "/build", ???filename: "[name].[chunkhash:8].js", ???publicPath: ‘/‘ ?}, ?resolve:{ ?????extensions:[‘‘, ‘.js‘,‘.jsx‘] ?}, ?module: { ???loaders: [ ???????{ test: /\.(js|jsx)$/, exclude: /node_modules/, loader: ‘babel‘ }, ???????{ test: /\.less$/, exclude: /node_modules/, loader: ExtractTextPlugin.extract(‘style‘, ‘css!postcss!less‘) }, ???????{ test: /\.css$/, exclude: /node_modules/, loader: ExtractTextPlugin.extract(‘style‘, ‘css!postcss‘) }, ???????{ test:/\.(png|gif|jpg|jpeg|bmp)$/i, loader:‘url-loader?limit=5000&name=img/[name].[chunkhash:8].[ext]‘ }, ???????{ test:/\.(png|woff|woff2|svg|ttf|eot)($|\?)/i, loader:‘url-loader?limit=5000&name=fonts/[name].[chunkhash:8].[ext]‘} ???] ?}, ?postcss: [ ???require(‘autoprefixer‘) ?], ?plugins: [ ???// webpack 内置的 banner-plugin ???new webpack.BannerPlugin("Copyright by wangfupeng1988@github.com."), ???// html 模板插件 ???new HtmlWebpackPlugin({ ???????template: __dirname + ‘/app/index.tmpl.html‘ ???}), ???// 定义为生产环境,编译 React 时压缩到最小 ???new webpack.DefinePlugin({ ?????‘process.env‘:{ ???????‘NODE_ENV‘: JSON.stringify(process.env.NODE_ENV) ?????} ???}), ???// 为组件分配ID,通过这个插件webpack可以分析和优先考虑使用最多的模块,并为它们分配最小的ID ???new webpack.optimize.OccurenceOrderPlugin(), ???????new webpack.optimize.UglifyJsPlugin({ ???????compress: { ?????????//supresses warnings, usually from module minification ?????????warnings: false ???????} ???}), ???????// 分离CSS和JS文件 ???new ExtractTextPlugin(‘[name].[chunkhash:8].css‘), ????????// 提供公共代码 ???new webpack.optimize.CommonsChunkPlugin({ ?????name: ‘vendor‘, ?????filename: ‘[name].[chunkhash:8].js‘ ???}), ???// 可在业务 js 代码中使用 __DEV__ 判断是否是dev模式(dev模式下可以提示错误、测试报告等, production模式不提示) ???new webpack.DefinePlugin({ ?????__DEV__: JSON.stringify(JSON.parse((process.env.NODE_ENV == ‘dev‘) || ‘false‘)) ???}) ?]}

在开发环境中跑webpack.config.js,打包的时候跑webpack.production.config.js的代码

所有在package.json中分别设置命令:

在window系统下:

"scripts": { ???"test": "echo \"Error: no test specified\" && exit 1", ???"dev": "set NODE_ENV=dev && webpack-dev-server --progress --colors", ???"build": "rd/s/q build && NODE_ENV=production && webpack --config ./webpack.production.config.js --progress --colors" ?},

在Mac系统下:

"scripts": { ???"dev": "NODE_ENV=dev webpack-dev-server --progress --colors", ???"build": "rm -rf ./build && NODE_ENV=production webpack --config ./webpack.production.config.js --progress --colors" ?},

所有当运行npm run dev 的时候就跑开发环境的代码,当运行指令npm run build 的时候就会跑webpack.production.config.js进行打包。

关于webpack的详细配置这里就不再详细说明,有兴趣的可以去看下文档。

二、使用react-router

1、安装依赖:npm install react-router --save

2、在根目录下新建router文件夹,然后新建一个routerMap.jsx文件

3、routerMap.jsx代码如下

import React from ‘react‘import { Router, Route, IndexRoute } from ‘react-router‘import App from ‘../containers/App‘import Home from ‘../containers/HomePage/Home‘import List from ‘../containers/ListPage/List‘import NotFound from ‘../containers/NotFound/Notfound‘class RouteMap extends React.Component{ ???render(){ ???????return( ???????????<Router history={this.props.history}> ???????????????<Route path=‘/‘ component={App}> ???????????????????<IndexRoute component={Home}/> ???????????????????<Route path=‘list‘ component={List}/> ???????????????????<Route path="*" component={NotFound}/> ???????????????</Route> ???????????</Router> ???????) ???}}export default RouteMap

4、在App.jsx里引用相应的路由切换组件{this.props.children}

import React from ‘react‘import Head from ‘../components/head/head‘import Menu from ‘../components/Menu/menu‘class App extends React.Component { ???render() { ???????return ( ???????????<div> ???????????????<Head/> ???????????????<div className="wrap"> ???????????????????<div className="menu"> ???????????????????????<Menu/> ???????????????????</div> ???????????????????<div>{this.props.children}</div> ???????????????</div> ???????????????????????????</div> ???????????????????) ???}}export default App

5、在根目录下的入口文件index.jsx引入routerMap,

import React from ‘react‘;import ReactDOM from ‘react-dom‘;import RouteMap from ‘./router/routerMap‘import {hashHistory} from ‘react-router‘import ?‘./static/index.scss‘ReactDOM.render( ?<RouteMap history={hashHistory}/>, ?document.getElementById(‘root‘));

6、使用菜单链接进行路由跳转

import React from ‘react‘import { Link } from ‘react-router‘class Menu extends React.Component{ ???render(){ ???????return( ???????????<div className="menu"> ???????????????<ul> ???????????????????<li> ???????????????????????<Link to="/">Home</Link> ???????????????????</li> ???????????????????<li> ???????????????????????<Link to="/list" activeClassName="active">List</Link> ???????????????????</li> ???????????????</ul> ???????????</div> ???????) ???}}export default Menu

react-router的使用基本就是这样,详细的参数配置可以具体看下文档

三、使用sass编译

如果想引入sass预编译处理,需要安装两个依赖,node-sass以及sass-loader,然后在webpack中配置相应的加载器

loaders: [ ???????????{ test: /\.scss$/, exclude: /node_modules/, loader: ‘style!css!postcss!sass‘ }, ???????]

 这样就能编译sass了,可以加快编码速度。

四、react 性能优化方案

这里将介绍两种比较常用的性能优化方案

1、性能检测react-addons-perf

安装react 性能检测工具 npm install react-addons-perf --save,然后在./app/index.jsx中使用依赖:

// 性能测试import Perf from ‘react-addons-perf‘if (__DEV__) { ???window.Perf = Perf}

if(__DEV__)是指在Dev环境下使用这个性能检测,然后把他赋到widow对象下。

使用方法:

在操作程序之前先在控制台中输入Perf.start()开始监听,启动检测;然后操作程序,在进行若干操作之后输入Perf.stop()停止检测,然后再跑Perf.printWasted()然后打印出浪费性能的组件列表,如下图所示:

在开发中很有必要检测组件中的性能情况,如果是浪费几毫秒或者十几毫秒,感觉没有必要再去优化他,毕竟十几毫秒是很难感觉得出来的。当浪费时间比较多的话,比如几十毫秒以上,这就有必要值得去优化他了。

2、PureRenderMixin优化

    React最基本的优化方案就是用PureRenderMixin,安装依赖:npm install react-addons-pure-render-mixin --save;

    PureRenderMixin使用原理:

react有一个生命周期函数叫做shouldComponentUpdata,为此组件更新之前,这个函数都会返回true,默认情况下都是返回true,当返回false则组件不更新,所以,当组件的state或者props变化的时候应该返回true,但这两个值不变化的时候则返回false,所以我们不能一直让这个函数返回true,实际的开发中组件会受一些其他因素的影响当state或者props不变化的时候也更新,这是需要我们去阻止的,所以要重写shouldComponentUpdata这个函数,每次更新的时候判断props和state这两个属性,有变化则返回true,无变化则返回false;

使用方法:

import PureRenderMixin from ‘react-addons-pure-render-mixin‘constructor(props, context) { ???????super(props, context); ???????this.shouldComponentUpdate = PureRenderMixin.shouldComponentUpdate.bind(this); ???????this.state = { ???????????todos: [] ???????} ???}

3、Immutable.js优化

Immutable.js主要是处理数据的,用的不多,这里不详细介绍

五、react-redux使用

redux使用分为5步:

1、定义计算规则,即reducers

在根目录下新建一个reducers的文件夹,里边新建一个index.js的文件用来放全部的规则文件,比如我需要定义userinfo部分的返回规则,则新建一个userinfo.js文件

然后在userinfo.js里边定义相应的规则:

这里通过 actionTypes来统一管理这些变量的名称,一是两个地方用到,二是为了统一管理,所以单独起的一个constants的文件,然后里边有一个userinfo.js的文件

userinfo代码如下:

然后reducers文件夹下index.js代码如下

reducers文件夹下index.js就是为了统一管理各个模块的数据,当有多个js时就可以把他们全部注册进combineReducers然后统一输出rootReducer。

 2、生成store

在根目录下新建一个store文件夹,里边新建一个文件configureStore.js,代码如下:

import { createStore } from ‘redux‘import rootReducer from ‘../reducers‘ ?//引入第一步生成的规则export default function configureStore(initialState) { ???const store = createStore(rootReducer, initialState, ???????// 触发 redux-devtools ???????window.devToolsExtension ? window.devToolsExtension() : undefined ???) ???return store}

3、引用store,监听变化

在根目录下入口文件index.jsx中引入store,然后用provide包裹着组件:

import React from ‘react‘import { render } from ‘react-dom‘import { Provider } from ‘react-redux‘import configureStore from ‘./store/configureStore‘import Hello from ‘./containers/Hello‘const store = configureStore()render( ???<Provider store={store}> ???????<Hello/> ???</Provider>, ???document.getElementById(‘root‘))

4、组件中把state值赋予到props,看hello.jsx的代码:

import React from ‘react‘import { connect } from ‘react-redux‘import { bindActionCreators } from ‘redux‘import * as userinfoActions from ‘../actions/userinfo‘import A from ‘../components/A‘import B from ‘../components/B‘import C from ‘../components/C‘class Hello extends React.Component { ???render() { ???????return ( ???????????<div> ???????????????<p>hello world</p> ???????????????<hr/> ???????????????<A userinfo={this.props.userinfo}/> ???????????????<hr/> ???????????????<B userinfo={this.props.userinfo}/> ???????????????<hr/> ???????????????<C actions={this.props.userinfoActions}/> ???????????</div> ???????) ???} ???componentDidMount() { ???????// 模拟登陆 ???????this.props.userinfoActions.login({ ???????????userid: ‘abc‘, ???????????city: ‘beijing‘ ???????}) ???}}//把state赋予到props->userinfofunction mapStateToProps(state) { ???return { ???????userinfo: state.userinfo ???}}//第五步:定义事件,触发action或者更改state的值,然后把事件赋予到propsfunction mapDispatchToProps(dispatch) { ???return { ???????userinfoActions: bindActionCreators(userinfoActions, dispatch) ???}}//通过connect函数把两个方法跟组件联系到一起然后输出export default connect( ???mapStateToProps, ???mapDispatchToProps)(Hello)

5.如果想改变reduce里边state的值,那么就需要通过事件去dispatch action;

这里定义了一些action事件:

然后在组件中通过import * as userinfoActions from ‘../actions/userinfo‘进来,接着通过函数

function mapDispatchToProps(dispatch) {
return {
userinfoActions: bindActionCreators(userinfoActions, dispatch)
}
}

 赋予到props userinfoActions 中;

接着就是使用:

componentDidMount() { ???????// 模拟登陆 ???????this.props.userinfoActions.login({ ???????????userid: ‘abc‘, ???????????city: ‘beijing‘ ???????}) ???}

这里reduce的5步就总结完了,说的有点笼统,具体的方法建议还是先看下文档,这里将不进行细节方法介绍。

reduce代码已经方法GitHub上边:https://github.com/huangjia727461876/react-reduce.git,不明白的可以看下源码。

 六、fetch使用

1、安装依赖

npm install whatwg-fetch --save

npm install es6-promise --save

在目录下起一个fetch的文件夹

然后建两个文件,一个get.js和post.js分别定义这两个方法

get.js代码如下:

import ‘whatwg-fetch‘import ‘es6-promise‘export function get(url) { ?var result = fetch(url, { ?????credentials: ‘include‘, ?????headers: { ?????????‘Accept‘: ‘application/json, text/plain, */*‘ ?????} ?}); ?return result;}

post.js代码如下:

import ‘whatwg-fetch‘import ‘es6-promise‘// 将对象拼接成 key1=val1&key2=val2&key3=val3 的字符串形式function obj2params(obj) { ???var result = ‘‘; ???var item; ???for (item in obj) { ???????result += ‘&‘ + item + ‘=‘ + encodeURIComponent(obj[item]); ???} ???if (result) { ???????result = result.slice(1); ???} ???return result;}// 发送 post 请求export function post(url, paramsObj) { ???var result = fetch(url, { ???????method: ‘POST‘, ???????credentials: ‘include‘, ???????headers: { ???????????‘Accept‘: ‘application/json, text/plain, */*‘, ???????????‘Content-Type‘: ‘application/x-www-form-urlencoded‘ ???????}, ???????body: obj2params(paramsObj) ???}); ???return result;}

用法:

import { get } from ‘./get.js‘import { post } from ‘./post.js‘export function getData() { ???// ‘/api/1‘ 获取字符串 ???var result = get(‘/api/1‘) ???result.then(res => { ???????return res.text() ???}).then(text => { ???????console.log(text) ???}) ???// ‘/api/2‘ 获取json ???var result1 = get(‘/api/2‘) ???result1.then(res => { ???????return res.json() ???}).then(json => { ???????console.log(json) ???})}export function postData() { ???// ‘/api/post‘ 提交数据 ???var result = post(‘/api/post‘, { ???????a: 100, ???????b: 200 ???}) ???result.then(res => { ???????return res.json() ???}).then(json => { ???????console.log(json) ???})}

七、项目目录结构

react看这篇就够了(react+webpack+redux+reactRouter+sass)

原文地址:https://www.cnblogs.com/superSmile/p/8195040.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved