webpack构建react项目(一)
前言
下面是我们使用到技术栈:
webpack + react + redux + react-router + react-thunk + ES6 + ....
注意事项:
建议使用npm5.X 或者 yarn 包管理工具(最好不要使用cnpm,虽然安装包速度上很快,但是在文件关联上会有坑,之前用的时候被坑过)
一、新建项目目录

config : webpack 配置文件
dist: 打包后代码
src: 源码目录
二、基础配置
安装基础的包
// 生成默认package.josn 文件
npm init // 安装 webpack 和 webpack-dev-server
npm install webpack webpack-dev-server --save-dev // 安装 react react-dom
npm install react react-dom --save // 安装 babel-core 、babel-loader、babel-preset-env、babel-preset-react
npm install babel-core babel-loader babel-preset-env babel-preset-react --save-dev // html-webpack-plugin 生成html文件
npm install html-webpack-plugin --sav-dev
添加 webpack 配置
先添加部分基础文件:
config/webpack/file.path.js
const { resolve } = require('path')
// 项目根目录
const projectPath = process.cwd()
// 代码地址目录
const srcPath = resolve(projectPath, 'src')
// 入口文件目录
const mainPath = resolve(srcPath, 'main')
// 入口文件
const indexJsPath = resolve(mainPath, 'index.jsx')
const indexHtmlPath = resolve(mainPath, 'index.html')
module.exports = {
srcPath,
mainPath,
indexJsPath,
indexHtmlPath
}
config/webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { srcPath, indexJsPath, indexHtmlPath } = require('./file.path.js')
// 生成HTML文件
const generateIndex = new HtmlWebpackPlugin({
inject: 'body',
filename: 'index.html',
template: indexHtmlPath
})
module.exports = {
// 基础目录(绝对路径),用于从配置中解析入口点和加载程序
// 默认使用当前目录,但建议在配置中传递一个值。这使得您的配置独立于CWD(当前工作目录)
context: srcPath,
// 入口文件
entry: indexJsPath,
// 输入配置
output: {
},
// 模块配置
module: {
rules: [
{
test: /\.jsx?$/,
use: 'babel-loader'
}
]
},
// 插件配置
plugins: [
generateIndex
]
}
添加 babel 配置 .babelrc:
.babelrc
{
"presets": [
"env", // babel 启动插件
"react" // 编译react语法插件
]
}
添加入口文件 src/main/index.jsx:
import React from 'react'
import ReactDOM from 'react-dom' const render = () => {
ReactDOM.render(
<h1>Hello React</h1>,
document.getElementById('app-container')
)
} render()
添加 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webpack react配置</title>
</head>
<body> </body>
</html>
在package.json 中添加启动命令:
{
...
"scripts": {
"start": "webpack-dev-server --config config/webpack.config.js"
},
...
}
现在可以直接在cmd中运行:
npm run start
可以在浏览器打开 http://localhost:8080/ ,你可以看到一下效果:

完整代码地址:https://github.com/haozhaohang/library/tree/master/webpack%20react%E9%85%8D%E7%BD%AE/lessons%201
三、高级配置
1. 添加 react-router
// 安装 react-router-dom
npm install react-router-dom --save
添加 src/main/app.js
import React, { Component } from 'react'
import { BrowserRouter, Route, Link } from 'react-router-dom'
import Home from '../containers/Home'
import About from '../containers/About'
import Topics from '../containers/Topics'
// BrowserRouter 下只能有一个子元素
class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Topics</Link></li>
</ul>
<hr/>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
<Route path="/topics" component={Topics}/>
</div>
</BrowserRouter>
)
}
}
export default App
添加 containers/Home/index.js
import React, { Component } from 'react'
const Home = () => {
return (
<div>
Home
</div>
);
}
export default Home
添加 containers/About/index.js
import React from 'react' const About = () => (
<div>
about
</div>
) export default About
添加 containers/Topics/index.js
import React from 'react'
const Topics = () => {
return (
<div>
topics
</div>
);
}
export default Topics
修改 src/main/index.jsx 文件
import React from 'react'
import ReactDOM from 'react-dom' import App from './app.js' const render = Component => {
ReactDOM.render(
<Component />,
document.getElementById('app-container')
)
} render(App)
路由我们添加完了,可以运行项目, 在浏览器 http://localhost:8080/ 预览效果。
react-router路由有 BrowserRouter和HashRouter 两种路由,两者的区别:
BrowserRouter 使用HTML5 历史API, HashRouter 使用哈希值
例如:如果同一个修改用户信息路由,在BroserRouter下显示 user/edit,而在HashRouter 下显示为 #/user/edit
刷新页面BrowserRouter会向服务端发送请求,后台要做一定处理,而HashRouter 不会向服务端发送请求
在react-router 4.0 的文档中有这样一段话:
注意: 使用 hash 的方式记录导航历史不支持 location.key 和 location.state。 在以前的版本中,我们为这种行为提供了 shim,但是仍有一些问题我们无法解决。 任何依赖此行为的代码或插件都将无法正常使用。 由于该技术仅用于支持传统的浏览器,因此在用于浏览器时可以使用 <BrowserHistory> 代替。
完整代码地址:https://github.com/haozhaohang/library/tree/master/webpack%20react%E9%85%8D%E7%BD%AE/lessons2
2.配置redux 、react-thunk
// 安装redux react-redux
npm install redux react-redux react-thunk --save
添加 src/main/store.js
import { combineReducers, createStore, applyMiddleware } from 'redux'
import thunk from 'redux-thunk'
import rootReducers from '../reducers'
const middleware = [thunk]
const store = createStore(
combineReducers(rootReducers),
{},
applyMiddleware(...middleware)
)
export default store
添加 src/reduxcers/index.js
function userInfo(state = {}) {
return {
name: 'react'
}
}
export default {
userInfo
}
修改 src/main/app.js
import { Provider } from 'react-redux'
import store from './store'
...
render() {
return (
<Provider store={store}>
...
</Provider>
)
}
...
修改 src/tontainers/Home/index.js
import React, { Component } from 'react'
import { connect } from 'react-redux'
const Home = ({ userInfo }) => {
return (
<div>
Home
<div>
这是redux中的数据
{userInfo.name}
</div>
</div>
);
}
const mapStateToProps = ({ userInfo }) => {
return {
userInfo
}
}
const mapDispatchTopProps = {}
// 使用connect 关联redux
export default connect(mapStateToProps, mapDispatchTopProps)(Home)
redux我们添加完了,可以运行项目, 在浏览器 http://localhost:8080/ 预览效果。
完整代码地址:https://github.com/haozhaohang/library/tree/master/webpack%20react%E9%85%8D%E7%BD%AE/lessons3
3.配置 react 热加载
修改 config/webpack.config.js
const webpack = require('webpack')
...
// 插件配置
plugins: [
...
// 开启全局的模块热替换(HMR)
new webpack.HotModuleReplacementPlugin(),
// 热加载中可以输入更加友好的模块名
new webpack.NamedModulesPlugin()
]
...
devServer: {
hot: true
}
...
这样配置已经可以实现热加载了,但是并不算结束,还需要配置 react-hot-loader 的热加载插件,这是因为 webpack-dev-server只能即时的刷新页面,但是组件中的状态保存不住,因为React有一些自己的语法(jsx)是HotModuleReplacementPlugin处理不了。而react-hot-loader 在 --hot 基础上做了额外的处理,来保证状态可以存下来。
// 安装 react-hot-loader
npm install react-hot-loader --save
修改 .babelrc
{
"presets": [
["env", {
"modules": false
}],
"react"
],
"plugins": ["react-hot-loader/babel"]
}
添加 react-hot-loader/patch 和 publicPath 到 webpack.config.js,
...
module.exports = {
...
// 入口文件
entry: [
'react-hot-loader/patch',
indexJsPath
],
// 输入配置
output: {
publicPath: '/'
},
...
}
...
修改 src/main/index.jsx
import React from 'react'
import ReactDOM from 'react-dom'
import { AppContainer } from 'react-hot-loader'
import App from './app.js' const render = Component => {
ReactDOM.render(
<AppContainer>
<Component />
</AppContainer>,
document.getElementById('root'),
)
} render(App) // Webpack Hot Module Replacement API
if (module.hot) {
module.hot.accept('./containers/App', () => { render(App) })
}
react-hot-loader 就配置完成了,现在更改三个页面中的文件,就可以在页面中实时看到。
配置时注意事项:
- 必须将webpack配置中output下publicPath设置为"/",否则无法实现热加载
- 将.babelre 中设置babel env预设更改为不使用Babel转换成ES2015模块 [ "env": { "modules": false } ]
- react-hot-loader在webpack-dev-server的热加载基础上做了额外的处理,所以必须要打开webpack-dev-server的 hot模式 才可以实现热加载
react-hot-loader我们添加完了,可以运行项目, 在浏览器 http://localhost:8080/ 预览效果。
完整代码地址:https://github.com/haozhaohang/library/tree/master/webpack%20react%E9%85%8D%E7%BD%AE/lessons4
4. 配置各种资源的loader
css资源加载器
// 安装 style-loader css-loader postcss-loader
npm install style-loader css-loader postcss-loader --save-dev
下面是webpack.config.js 中的配置
...
// 模块配置
module: {
rules: [
...
{
test: /\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
{
loader: 'postcss-loader'
}
]
}
...
]
},
...
使用postcss需要添加postcss.config.js
module.exports = {
plugins: [
// 添加你需要的插件,这个后面会提到
]
}
之前一直使用sass,但是这里并没有选择sass、less等css预处理框架,个人认为postcss是一个平台,提供了丰富的插件,可以更好处理css。
图片资源的加载
// 安装 url-loader file-loader
npm install url-loader file-loader --save-dev
下面是webpack.config.js 中的配置
...
// 模块配置
module: {
rules: [
...
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
limit: 8192
}
}
]
},
...
]
},
...
url-loader: 可以将图片小于8192(根据limit设置而定)的图片装成base64和源码添加在一起,减少请求,提高加载速度。
file-loader: 对url-loader无法处理的图片资源(大于limit设置的值),使用此loader进行处理,当然这个loader还可以加载字体图标等文件,这里就不在详细添加了。
完整代码地址:https://github.com/haozhaohang/library/tree/master/webpack%20react%E9%85%8D%E7%BD%AE/lessons5
基本的配置都讲完了,后续系列中会讲到优化webpack配置、开发生成配置的拆分、构建优化和服务代理,mock数据等功能
如果本文对你有帮助,请给个 star,感谢^_^
webpack构建react项目(一)的更多相关文章
- 和我一起使用webpack构建react项目
第一步:初始化项目并创建package.json文件 第二步:创建webpack.config.js文件,并写入配置. 第三步:安装webpack以及创建es6语法环境,要将html作为模板文件解析的 ...
- 【转载】基于webpack构建react项目
第一部分链接:下载所需内容并构建基础的页面 第二部分链接:添加webpack中的一些常用babel和loader 第三部分链接:开发环境与生产环境的配置
- [react001] 使用webpack自动构建react 项目
1.react 简介 React 是一个Facebook出品的前端UI开发框架.react官方的tutorials 为了让人容易上手,并没有给在平常工作使用react的详细配置,随意学习的深入,你为了 ...
- 简述--构建React项目的几种方式
前言: 构建React项目的几种方式: 构建:create-react-app 快速脚手架 构建:generator-react-webpack 构建:webpack一步一步构建 1)构建:creat ...
- 基于webpack的React项目搭建(一)
前言 工欲善其事,必先利其器.为了更好的学习React,我们先简要的把开发环境搭建起来.本文主要介绍使用webpack搭建React项目,如果你对React或es6的基础语法还不了解,建议先去学习学习 ...
- 使用webpack搭建react项目 webpack-react-project
webpack-react-project 使用webpack搭建react项目 webpack搭建react项目 github源码 具体配置信息参照package.json和webpack.conf ...
- 使用 Dawn 构建 React 项目
开发一个 React 项目,通常避免不了要去配置 Webpack 和 babel 之类,以支持 commonjs 或 es 模块及各种 es 新语法,及及进行 jsx 语法的转义.当然也可以用 cre ...
- 在visual code的debugger for chrome中调试webpack构建的项目
一直使用chrome中内置的调试器, 感觉世界那么美好, 自从学了react之后,使用visual code作为编辑器, 它提供了很多插件, 其中就包括debugger for chrome, 一款使 ...
- webpack构建react多页面应用
写这个的初衷是很难找一个简洁的项目脚手架,很多脚手架都有很多依赖,光看依赖就要很久,所以自己参照网上的内容,弄个这么一个简单的多页面的脚手架. 利用creat-react-app 新建一个react应 ...
随机推荐
- [BZOJ 1079][SCOI 2008]着色方案
1079: [SCOI2008]着色方案 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2237 Solved: 1361[Submit][Stat ...
- c语言程序设计第6周编程作业一(分解质因数)
分解质因数 题目内容: 每个非素数(合数)都可以写成几个素数(也可称为质数)相乘的形式,这几个素数就都叫做这个合数的质因数.比如,6可以被分解为2x3,而24可以被分解为2x2x2x3. 现在,你的程 ...
- C语言程序设计(基础)- 第7周作业
为了防止误解,自从本周开始ppt.pta作业.博客作业的命名均与学校教学周一致. 要求一(20经验值) 完成PTA中题目集名为<usth-C语言基础-第七周作业>和<usth-C语言 ...
- alpha冲刺第六天
一.合照 二.项目燃尽图 三.项目进展 主界面首页内容呈现 我的栏目之我的问题完成 我的栏目之我的提问完成 还是插不进去,然后打算先放一放,一直在一个地方纠结那么久脑子太乱 四.明日规划 问答界面问题 ...
- bug终结者 团队作业第一周
bug终结者 团队作业第一周 小组组员及人员分工 小组成员 组长: 20162323 周楠 组员: 20162302 杨京典 20162322 朱娅霖 20162327 王旌含 20162328 蔡文 ...
- 201621123060《JAVA程序设计》第十三周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 为了让你的系统可以被多个用户通过网 ...
- Android 4.4 沉浸式透明状态栏
原文链接:http://www.bkjia.com/Androidjc/913061.html 第一种方法 这里写代码片第一种方法,在代码设置: if(VERSION.SDK_INT >= VE ...
- day-6 机器学习概念及应用
学习玩Python基础语法,今天开始进行机器学习,首先了解下机器学习和深度学习的一些基本概念和术语: 1. 机器学习概念及应用 2. 深度学习概念及应用 3. 机器学习基本术语及举例 4. 机 ...
- php代码开启缓冲的使用方法
php可以开启缓冲区,就是将内容放到缓冲区,再决定什么时候发送给浏览器. 感谢:http://www.jb51.net/article/38964.htm 解析PHP中ob_start()函数的用法 ...
- SQL Server元数据损坏(metadata corruption)修复
在升级一个SQL Server 2000的数据库时,遇到了一致性错误,其中有几个错误是元数据损坏(metadata corruption),特意研究了一下这个案例,因为以前也零零散散的遇到过一些一致性 ...