1.官网:https://reacttraining.com/react-router/web/guides/code-splitting/code-splitting-server-rendering
2.某文章:http://blog.csdn.net/mjzhang1993/article/details/79094594
load
的
props
load -> function (cb) {...cb(/* 异步加载的组件 */)},由bundle-loader封装
import React from 'react';
class Bundle extends React.Component {
constructor(props){
super(props);
this.state = {
// 默认为空
mod: null
}
}
componentWillMount() {
// 加载初始状态
this.load(this.props);
}
componentWillReceiveProps(nextProps) {
if (nextProps.load !== this.props.load) {
this.load(nextProps);
}
}
load(props) {
// 重置状态
this.setState({
mod: null
});
// 传入组件的组件
props.load((mod) => {
this.setState({
mod: mod.default ? mod.default : mod
});
});
}
render() {
// 不为空,则渲染传入的子组件函数
return this.state.mod ? this.props.children(this.state.mod) : null;
}
}
export default Bundle;
2.lazyLoad.js
import React from 'react';
import Bundle from './Bundle';
// 默认加载组件,可以直接返回 null
const Loading = () => Loading...;
/*
包装方法,第一次调用后会返回一个组件(函数式组件)
由于要将其作为路由下的组件,所以需要将 props 传入
{Comp => (Comp ? : )}
*/
const lazyLoad = (loadComponent,props) =>
{//Bundle 包含的是一个函数子组件 由Bundle.js里的this.props.children(this.state.mod)渲染
return(
{Comp => (Comp ? : )}
);}
export default lazyLoad;
3.路由使用
//import Home from './page/Home.bundle';//这种方式需要配置webpack的loader
//import Detail from './page/Detail.bundle';//这种方式需要配置webpack的loader
//--------------------------------------------------
import Detail from 'bundle-loader?lazy&name=home!./page/Detail.bundle';
import Home from 'bundle-loader?lazy&name=home!./page/Home.bundle';
//
}/>
{
return lazyLoad(Home, {
dispatch:dispatch,
getState:getState,
questionList:value.question
}
);
}}/>
{
return lazyLoad(Detail, {
pid:props.location.id,
questionList:value.question,
dispatch:dispatch,
answer:value.answer
}
);
}}/>
4.如果使用webpack配置
{
test: /\.bundle\.js$/,
loader: 'bundle-loader',
options: {
lazy: true,
name: '[name]'
}
}
完整的webpack.config.js
//__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const autoprefixer = require('autoprefixer')
let extractCSS = new ExtractTextPlugin('main.css');
module.exports = {//注意这里是exports不是export
devtool: 'source-map',//本地调试react
devServer: {
contentBase: "./build",//本地服务器所加载的页面所在的目录
historyApiFallback: true,//不跳转
port:8888,//设置默认监听端口,如果省略,默认为”8080“
inline: true//实时刷新
},
entry: __dirname + "/src/main.js",//唯一入口文件,就像Java中的main方法
output: {//输出目录
path: __dirname + "/build",//打包后的js文件存放的地方
filename: "bundle.js"//打包后的js文件名
},
module: {
//loaders加载器
rules: [
{
test: /\.bundle\.js$/,
loader: 'bundle-loader',
include:/page/,
options: {
lazy: true,
name: '[name]'
}
},{
test: /\.(js|jsx)$/,//一个匹配loaders所处理的文件的拓展名的正则表达式,这里用来匹配js和jsx文件(必须)
exclude: /node_modules/,//屏蔽不需要处理的文件(文件夹)(可选)
use: 'babel-loader'//loader的名称(必须)
},{
test: /\.(css|less)$/,
use:extractCSS.extract({
fallback: "style-loader",
use: [{
loader: "css-loader",
options: {
modules: true, // 指定启用css modules
localIdentName: '[name]__[local]--[hash:base64:5]' // 指定css的类名格式
}
},{
loader: "postcss-loader",
options: {
plugins: () => [autoprefixer(
{ browsers: ['iOS >= 7', 'Android >= 4.1',
'last 10 Chrome versions', 'last 10 Firefox versions',
'Safari >= 6', 'ie > 8']
}
)],
},
},{
loader: "less-loader"
}],
})
},{
test: /\.(eot|svg|ttf|woff|woff2|png)\w*/,// font awesome loader
use: 'file-loader'
}
]
},
plugins: [
extractCSS,
new HtmlWebpackPlugin({
template: __dirname + "/src/index.tmpl.html"//new 一个这个插件的实例,并传入相关的参数
})
]
};