效果:
文件结构:
webpack基本搭建
1 npm init 命令webpack.json 里面的参数可选填,回车确定;
2 安装依赖
{
"name": "reactdemo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"babel-plugin-transform-react-jsx": "^6.24.1",
"css-loader": "^1.0.0",
"less-loader": "^4.1.0",
"style-loader": "^0.21.0",
"url-loader": "^1.0.1",
"webpack": "^2.7.0",
"webpack-cli": "^2.1.3",
"webpack-dev-server": "^3.1.5",
"html-webpack-plugin": "^3.2.0",
"babel": "^6.23.0",
"babel-cli": "^6.26.0",
"babel-loader": "^7.1.5",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"file-loader": "^1.1.11",
"less": "^3.8.0"
},
"devDependencies": {
}
}
【注意我这里下载的是webpack2,如果你下载了高版本的话,后面的配置可能会报错】;
可以采用我上面的,然后npm install下载依赖包;
3 配置热加载
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "rm -rf ./dist && webpack-dev-server --inline --progress --mode development --config webpack.config.js",
"build": "rm -rf ./dist && webpack"
},
4 安装react开发所需包
npm install react react-dom react-hot-loade react-router react-router-dom --save-dev
同时安装了常用的jquery;
最后的package.json如下:(里面具体关于webpack依赖包的作用不细说,有兴趣另外了解)
{
"name": "reactdemo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "rm -rf ./dist && webpack-dev-server --inline --progress --mode development --config webpack.config.js",
"build": "rm -rf ./dist && webpack"
},
"author": "",
"license": "ISC",
"dependencies": {
"babel": "^6.23.0",
"babel-cli": "^6.26.0",
"babel-loader": "^7.1.5",
"babel-plugin-transform-react-jsx": "^6.24.1",
"babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"css-loader": "^1.0.0",
"file-loader": "^1.1.11",
"html-webpack-plugin": "^3.2.0",
"less": "^3.8.0",
"less-loader": "^4.1.0",
"style-loader": "^0.21.0",
"url-loader": "^1.0.1",
"webpack": "^2.7.0",
"webpack-cli": "^2.1.3",
"webpack-dev-server": "^3.1.5"
},
"devDependencies": {
"react": "^16.4.1",
"react-dom": "^16.5.2",
"react-hot-loader": "^4.3.4",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
"jquery": "jQuery"
}
}
5 配置webpack.config.js文件
注意几点:
js入口
文件导出出口路径指定
首页的模板指定;
const webpack = require('webpack');
const htmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path')
const config = {
//mode: "development",//4以上要指定,以下的话不要,否则报错
entry: {
index: __dirname + "/src/index.jsx",//入口
},
output: {//出口
filename: "[name].js",
path:path.join(__dirname,'dist'),
},
module:{
loaders: [
{
test: /\.css$/,
loader: 'style-loader!css-loader'
},
{
test: /\.(png|ttf|gif|woff|woff2|eot|svg|jpg)$/,
loader: 'url-loader?limit=4000'
},
{
test: /\.less$/,
loader: "style-loader!css-loader!less-loader",
},
{
test: /\.jsx$/,//配置要处理的文件格式,一般使用正则表达式匹配
exclude: __dirname+'/node_modules',
//loader: process.env.NODE_ENV === 'production' ? 'babel?presets[]=react&presets[]=es2015&presets[]=stage-2' : 'react-hot!babel?presets[]=react&presets[]=es2015&presets[]=stage-2',
loader: 'babel-loader',//使用的加载器名称
include: [
path.resolve(__dirname, "src")
],
},
{
test:/\.js/,
loader:'babel-loader'
}
],
},
plugins:[
new htmlWebpackPlugin({
title:'index',//生成后的首页的title指定
filename:'index.html',//生成的首页名称
template:'./public/indexTemplate.html'//模板首页文件
}),
//new webpack.optimize.UglifyJsPlugin({ //用于js压缩,开发时注释,否则严重降低热加载更新效率
// compress: {
// warnings: false
// }
//})
],
}
module.exports = config;
到这里为止,运行热加载命令:$ webpack-dev-server --progress
以上即热加载成功;(打包命令:$ webpack)
至此,webpack的搭建完成;
react开发:
首先,indexTemplate.html文件,编辑"#app";
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title>Title</title>
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div id="app"></div>
</body>
</html>
现在我们做一个这样的小demo;
开始配置路由:(页面先要写好)
准备,CourseList.jsx CourseDetail.jsx AppLayout.jsx Home.jsx
CourseList.jsx
import React from 'react'
class CourseList extends React.Component {
render() {
return (
<div>courseList</div>
)
}
}
export default CourseList
CourseDetail.jsx
import React from 'react'
class CourseDetail extends React.Component {
render() {
return (
<div>courseDetail</div>
)
}
}
export default CourseDetail
Home.jsx
import React from 'react'
class Home extends React.Component {
render() {
return (
<div>Home</div>
)
}
}
export default Home
AppLayout.jsx里面有路由的配置,下面出现;
配置路由--》
1 index.jsx
import React from 'react'
import { render } from 'react-dom'
import { hashHistory } from 'react-router'
import {HashRouter} from 'react-router-dom'
import jquery from 'jquery'
import RouteMap from './js/router/route.jsx'
class Router extends React.Component {
render() {
return (
<HashRouter>
<RouteMap></RouteMap>
</HashRouter>
)
}
}
render(<HashRouter><Router history={history} location={location}></Router></HashRouter>,document.getElementById('app'));
【注意,组件命名需要大写开头】
如果遇见 报错:
Invalid prop `component` of type `object` supplied to `Route`, expected `function`.
原因:组件没有export暴露;
然后同vue一样,习惯将route重新开一个文件,而不是都写在index.jsx中;
2 route.jsx配置主要路由
import React from 'react'
import {Route,Redirect,Switch} from "react-router-dom";
import AppLayout from '../../components/AppLayout.jsx'
import Home from '../../views/home/Home.jsx'
class RouteMap extends React.Component {
render() {
return (
<main>
<Switch>
<Route path="/home" exact component={Home}/>
<Route path="/" component={AppLayout}/>
<Redirect to='/home' />
</Switch>
</main>
)
}
}
export default RouteMap
这里的Switch与Redirect(默认路由)属于react 4 ;
【V3到V4路由写法的改变:】 路由不适用Route嵌套,而是写在组件component下,以前路由嵌套时,除了写路由,还要写路由渲染的地方,即<this.props.children>, 这样,路由就会在此渲染,V4改变,匹配路由的组件想在哪渲染,路由就写在哪,即<this.props.children>的位置;
所以,courselist跟coursedetail在AppLayout.jsx里面配置;
AppLayout.jsx
import React from 'react'
import {Switch,Route,Redirect} from "react-router-dom";
import CourseDetail from '../views/course/CourseDetail.jsx'
import CourseList from '../views/course/CourseList.jsx'
class AppLayout extends React.Component {
render() {
return (
<div>
<div className="AppLayoutTop">
<span>返回</span>
top
</div>
<div id='AppMain'>
<Switch>
<Route path="/courselist" component={CourseList}/>
<Route path="/coursedetail" component={CourseDetail}/>
</Switch>
</div>
</div>
)
}
}
export default AppLayout
至此,路由配置完成,运行应该得到下面效果:
http://localhost:8080/#/home http://localhost:8080/#/courselist http://localhost:8080/#/coursedetail
优化一下,编写样式common.less,在AppLayout.jsx引入:
import './common.less'
最后处理一下 头部title;(AppLayout.jsx)
render() {
var getParamTitle=(pathname)=>{
var ParamTitle=''
switch(pathname){
case '/courselist':ParamTitle='列表';break;
case '/coursedetail':ParamTitle='详情';break;
}
return ParamTitle;
}
var getTitle=()=>{
return getParamTitle(this.props.location.pathname)
}
return (
<div>
<div className="AppLayoutTop">
<span>返回</span>
{getTitle()}
</div>
<div id='AppMain'>
<Switch>
<Route path="/courselist" component={CourseList}/>
<Route path="/coursedetail" component={CourseDetail}/>
</Switch>
</div>
</div>
)
}
完成效果: