webpack + react 4 簡單搭建(webpack搭建,react路由配置)
效果:
檔案結構:
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
至此,路由配置完成,執行應該得到下面效果:
優化一下,編寫樣式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>
)
}
完成效果: