月度归档:2018年04月

在create-react-app中使用Code Splitting

在create-react-app中使用Code Splitting实现按需加载js

为了减少HTTP请求,我们会把代码打包到一个文件里。
Code splitting可以把打包的文件分割成不同的块,并实现按需加载。
下面是在create-react-app中使用方法。

简单示例

  1. 创建项目
    npx create-react-app code-splitting
    
  2. 在src文件夹里创建文件texts.js
    const hello = 'Hello World!';
    export { hello };
    
  3. 修改App.js
    class App extends Component {
        constructor(props){
            super(props);
            this.state = {};
        }
        componentDidMount(){
            import('./texts')
                .then(({hello}) => {
                    this.setState({
                        msg: hello,
                    })
                })
                .catch(err => {
                });
        }
        render() {
            return (
                <div className="App">
                    <div>{this.state.msg || 'loading...'}</div>
                </div>
            );
        }
    }
    export default App;
    
  4. Chrome中network

分割react的组件

使用React Loadable分割,React Loadable还能创建 loading states, error states, timeouts, preloading,等状态。
原来的引用方式:

import OtherComponent from './OtherComponent';
const MyComponent = () => (
    <OtherComponent/>
);

使用React Loadable启用了Code splitting的方式:

import Loadable from 'react-loadable';
const LoadableOtherComponent = Loadable({
    loader: () => import('./OtherComponent'),
    loading: () => <div>Loading...</div>,
});
const MyComponent = () => (
    <LoadableOtherComponent/>
);

例子:

  1. 添加依赖
    yarn add react-loadable

  2. 新建一个组件Hello.js

    import React from 'react';
    export default () => (
        <div>Hello world.</div>
    )
    
  3. 在App.js中引用Hello
    import Loadable from 'react-loadable';
    const LoadableOtherComponent = Loadable({
        loader: () => import('./Hello'),
        loading: () => <div>Loading...</div>,
    });
    const Hello = () => (
        <LoadableOtherComponent/>
    );
    
  4. 在render函数里渲染

  5. 从network里可以看到又多了一个js文件

根据路由分割

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Loadable from 'react-loadable';
const Loading = () => <div>Loading...</div>;
const Home = Loadable({
  loader: () => import('./routes/Home'),
  loading: Loading,
});
const About = Loadable({
  loader: () => import('./routes/About'),
  loading: Loading,
});
const App = () => (
  <Router>
    <Switch>
      <Route exact path="/" component={Home}/>
      <Route path="/about" component={About}/>
    </Switch>
  </Router>
);
  1. 安装依赖
    yarn add react-router-dom

  2. 创建路由页面
    routes/Home.js

    import React from 'react';
    export default () => (
        <div>Home</div>
    )
    

    routes/About.js

    import React from 'react';
    export default () => (
        <div>About</div>
    )
    
  3. 在App.js中引用路由页面
    const Loading = () => <div>Loading...</div>;
    const Home = Loadable({
        loader: () => import('./routes/Home'),
        loading: Loading,
    });
    const About = Loadable({
        loader: () => import('./routes/About'),
        loading: Loading,
    });
    
  4. 配置路由
    import { BrowserRouter as Router, Route, Switch, Link } from 'react-router-dom';
    ...
    render() {
        return (
            <Router>
                <div>
                    <div>{this.state.msg || 'hello'}</div>
                    <Hello/>
                    <div>
                        <Link to={'/'}>home</Link>
                        <Link to={'/about'}>about</Link>
                    </div>
                    <Switch>
                        <Route exact path="/" component={Home}/>
                        <Route path="/about" component={About}/>
                    </Switch>
                </div>
            </Router>
        );
    }
    
  5. 在Chrome中查看network,可以看到第一次点击about的时候,浏览器会异步加载about组件的js

完整代码可以在github上看到:
https://github.com/shengoo/react-demo/tree/master/code-splitting