Implementation of import() asynchronous loading component using webpack2 in react

Keywords: Javascript React Webpack

Are you still using require.ensure()???

low!!

Have you heard the name of import()?

The following is a grand introduction to the new scheme of Web pack code cutting.

Here are the official website tutorials: https://doc.webpack-china.org...

Don't go to the official website tutorials first, because webpack official website tutorials are usually unreliable and written in a fog.

In web pack, from v1 to v2, v3 is not mentioned for the time being. There are three methods of code cutting and loading.

1. System.import(); abolished, not recommended

2. require.ensure(); v1 and v2 can be used

3. import(); v2 support, v1 support

System.import()

If it has been abolished, no introduction will be given.

require.ensure()

From the v1 era, students who have used webpack should not be unfamiliar with this usage. Comparing with the demo on the internet, we can find many demos about the use of require.ensure().

Enter require.ensure() in Baidu and find several key tutorials.

Introduction to the use of require.ensure in webpack 2.2 document

Give a brief introduction to the classic use of require.ensure. If you haven't used it, don't worry, just look at the code below.

const Foo = require.ensure([], () => {
    require("a");
}, err => {
    console.error("We failed to load chunk: " + err);
}, "chunk-name");

//react-router2 or 3
<Route path="/xx" getComponent={Foo} />

import()

This is our protagonist today. The use scenario is react-router 4. You will find that in react-router 4, the getComponent of route is missing.

What to do? At this time, you can take a look at the top of the official code cutting tutorial for you, listing three uses.

1. Importing Local Modules

function determineDate() {
  import('moment').then(function(moment) {
    console.log(moment().format());
  }).catch(function(err) {
    console.log('Failed to load moment', err);
  });
}

determineDate();

2. Import the whole module

import('./component').then(Component => /* ... */);

3. Use await

async function determineDate() {
  const moment = await import('moment');
  return moment().format('LLLL');
}

determineDate().then(str => console.log(str));

All three official examples have one thing in common: import (name) - > Promise

We find that the import() method returns a Promise, what? Promise? Someone will ask what happened to Promise. I can just assign variables.

const Foo = import("./xx") // Wrong Writing

<Route path="/xx" component={import("./xxx")} /> //Wrong Writing

Teenagers, don't be naive. Promise's return value can only be read by then(), so you will find that all three official usage scenarios are operated in then(). So what? I want to assign the component acquired by import() to a variable or constant.

Through my persistent chrome, I finally found a "surprising function".

People who know how to do it may ask that there is not a react-router 4 official document. Bundle component Can code cutting be achieved?

Yeah, after I copied the official method and used it, a bunch of red errors, deceived people.

No nonsense, code is available directly.

1. asyncComponent function: The function is well understood. The load Component parameter represents the path that needs code cutting. The function return value is a react component, which helps you to operate the then() method.

import React from 'react'
export const asyncComponent = loadComponent => (
    class AsyncComponent extends React.Component {
        state = {
            Component: null,
        }

        componentWillMount() {
            if (this.hasLoadedComponent()) {
                return;
            }

            loadComponent()
                .then(module => module.default)
                .then((Component) => {
                    this.setState({ Component });
                })
                .catch((err) => {
                    console.error(`Cannot load component in <AsyncComponent />`);
                    throw err;
                });
        }

        hasLoadedComponent() {
            return this.state.Component !== null;
        }

        render() {
            const { Component } = this.state;
            return (Component) ? <Component {...this.props} /> : null;
        }
    }
);

2. Use in react

import { asyncComponent } from './AsyncComponent'

const Foo = asyncComponent(() => import(/* webpackChunkName: "foo" */ "./foo"))

<Route path="/xx" component={Foo} />

3. Okay, so you can succeed, but please pay attention to the following questions:

In the configuration file of webpack2, you need to configure chunkName.

chunkFilename: '[name].js'

If your asynchronous loading component has an import style, transplant the style to the global js file to import.

All right, that's the end of this article.

"Wait, kid. Do you have demo? I can't read the words!"

I turned back and asked, "Do you want to see demo? Look at that. Implementing import() Cutting in February If webpack comes up with something better, I will continue to follow it up and apply it to the project.

Posted by kevin99 on Fri, 21 Jun 2019 14:53:23 -0700