@xiaoqq
2016-12-29T04:09:05.000000Z
字数 2931
阅读 1273
Webpack
目前项目中存在的问题:
需要实现的目标:
采用Webpack2.X的Lazy Loading
npm i webpack@2.1.0-beta.25 --save-devnpm i webpack@2.1.0-beta.25 -g
参考文章:https://gold.xitu.io/entry/581d9fcc8ac247004ff3c70e
在现有的项目上直接使用webpack2.x会报错,必须先修改配置文件
1)resolve.extensions去掉' '
resolve: {extensions: ['.js', '.jsx']},
2)去掉new webpack.optimize.OccurenceOrderPlugin()插件
3) (可选)对module进行改造
module: {- loaders: [+ rules: [{test: /\.css$/,- loaders: [+ use: [{loader: "style-loader"},{loader: "css-loader",- query: {+ options: {modules: true}]}]}
参考:https://webpack.js.org/guides/migrating/
import React from 'react';/*** @function 支持异步加载的封装组件*/class LazilyLoad extends React.Component {constructor() {super(...arguments);this.state = {isLoaded: false,};}componentWillMount() {this.load(this.props);}componentDidMount() {this._isMounted = true;}componentWillReceiveProps(next) {if (next.modules === this.props.modules) return null;this.load(next);}componentWillUnmount() {this._isMounted = false;}load(props) {this.setState({isLoaded: false,});const {modules} = props;const keys = Object.keys(modules);Promise.all(keys.map((key) => modules[key]())).then((values) => (keys.reduce((agg, key, index) => {agg[key] = values[index];return agg;}, {}))).then((result) => {if (!this._isMounted) return null;this.setState({modules: result, isLoaded: true});});}render() {if (!this.state.isLoaded) return null;return React.Children.only(this.props.children(this.state.modules));}}LazilyLoad.propTypes = {children: React.PropTypes.func.isRequired,};export const LazilyLoadFactory = (Component, modules) => {return (props) => (<LazilyLoad modules={modules}>{(mods) => <Component {...mods} {...props} />}</LazilyLoad>);};export const importLazy = (promise) => (promise.then((result) => result));export default LazilyLoad;
import LazilyLoad, { importLazy, LazilyLoadFactory } from './LazilyLoad'
异步加载组件有两种方式
1)使用高阶组件包裹现有的页面组件,当页面加载时,被引用的组件会同时被异步加载,并且通过props传递给页面组件。
class PageTest extends React.Component {render() {const { Breadcrumb, Table, Pagination } = this.props;return (<div id="page-test"><Breadcrumb menuDataList={this.props.menuDataList} />...</div>)}}PageTest = LazilyLoadFactory(PageTest, {Breadcrumb: () => System.import('../../components/breadcrumb'),Table: () => System.import('../../components/cTable'),Pagination: () => System.import('../../components/pagination'),})
2) 按需加载组件:比如某个组件在首屏时并不显示,只有等弹窗时才需要显示,那么这个组件就可以采用按需加载的方式进行异步加载。
class PageTestEdit extends React.Component {...//返回LazilyLoad包裹后的组件createLazilyModule(moduleFn) {return (<LazilyLoad modules={{Datepicker: () => System.import('../../components/datepicker')}}>{moduleFn}</LazilyLoad>)}renderModuleEdit() {return (<div className="padding-20" id="edit-module">{this.createLazilyModule(({Datepicker}) => {return <Datepicker type="datetime" placeholder="请选择"/>})}</div>)}...}
Webpack2.x Lazy Loading - React: https://webpack.js.org/guides/lazy-load-react/
基于Webpack 2的React组件懒加载: https://segmentfault.com/a/1190000007938737