Web pack and react on demand

Principle: CommonJS and import()

Method 1: CommonJS module syntax

With require.ensure,require.ensure() is unique to webpack and has been replaced by import().

Method

require.ensure(
  dependencies: String[],
  callback: function(require),
  errorCallback: function(error),
  chunkName: String
)

Method 2: import()

The ES2015 loader specification defines the import() method, which can dynamically load ES2015 modules at runtime

Method

import('Component').then()
// or in async
await import('Component')

demo

import React, { Component } from 'react';

class App extends Component {
  handleClick = () => {
    import('./moduleA')
      .then(({ moduleA }) => {
        // Use moduleA
      })
      .catch(err => {
        // Handle failure
      });
  };

  render() {
    return (
      <div>
        <button onClick={this.handleClick}>Load</button>
      </div>
    );
  }
}

export default App;

Use on demand loading in react router

demo address , which is used in conjunction with create react app. You need to configure your own webpack reasonably output.fileName and output.chunkFilename

Method 1: use react.lazy

import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import React, { Suspense, lazy } from 'react';

const Program1 = lazy(() => import('./Program1'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Switch>
        <Route path="/program1" component={Program1}/>
      </Switch>
    </Suspense>
  </Router>
);

view code

Method 2: using higher-order components

  • Write a high-level component for dynamic loading
// async Component
import React, { Component } from "react";

export default function asyncComponent(importComponent) {
  class AsyncComponent extends Component {
    constructor(props) {
      super(props);

      this.state = {
        component: null
      };
    }

    async componentDidMount() {
      const { default: component } = await importComponent();

      this.setState({
        component: component
      });
    }

    render() {
      const C = this.state.component;

      return C ? <C {...this.props} /> : null;
    }
  }

  return AsyncComponent;
}

view code

  • Reference and use this higher-level component for on-demand loading
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import asyncComponent from './asyncComponent';
import React, { Suspense } from 'react';

const Progran2 = asyncComponent(() => import("./Program2"));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Switch>
        <Route exact path="/program2" component={Program2}/>
      </Switch>
    </Suspense>
  </Router>
);

view code

Both of the above methods are recommended by react code-splitting

Tags: Javascript React Webpack

Posted on Sun, 01 Dec 2019 17:58:04 -0800 by RJP1