webpack+react+react-routerはどうやって怠惰なロードを実現しますか?


Webpack 1では主にbundle-loaderによって怠惰な負荷が行われますが、Webpack 2ではSystemJSに似たSystem.import文法が導入されています。まずSystem.importの実行プロセスについて簡単に説明します。
  • Webpackは、コンパイル中にコードライブラリをスキャンすると、発見されたSystem.importが導入したファイルとその関連性を呼び出して単独で包装します。Webpackはこれらの独立したモジュールとその依存性がアプリケーションのパッケージと衝突しないことを保証します。
  • 、これらの独立したパッケージモジュールにアクセスすると、Webpackは、JSONP要求を開始して関連するパッケージを取り込む。
  • System.importもPromiseであり、要求が完了したらSystem.importはキャプチャされたモジュールをパラメータとしてthenに入力する。
  • ロード済みのモジュールに繰り返しアクセスすると、Webpackはキャプチャと解析のプロセスを繰り返し実行しません。
  • React Routerルーティングの不精負荷は、実際に動的ルーティングと不精負荷の2ステップに分けられており、典型的ないわゆる動的ルーティング構成は以下の通りである。
    
    /**
     * <Route path="/" component={Core}>
     *  <IndexRoute component={Home}/>
     *  <Route path="about" component={About}/>
     *  <Route path="users" component={Users}>
     *  <Route path="*" component={Home}/>
     * </Route>
     */
    export default {
     path: '/', 
     component: Core,
     indexRoute: { 
      getComponent(location, cb) {
        ...
      },
     },
     childRoutes: [
      {
       path: 'about', 
       getComponent(location, cb) {
        ...
       },
      },
      {
       path: 'users', 
       getComponent(location, cb) {
        ...
       },
      },
      {
       path: '*', 
       getComponent(location, cb) {
        ...
       },
      },
     ],
    };
    
    正常に包装します
    
    import IndexPage from './views/app.jsx'
    import AboutPage from './views/about.jsx'
    export default function({history}) {
      return (
        <Router history={history}>
          <Route path="/" component={IndexPage} />
          <Route path="/about" component={AboutPage} />
        </Router>
      )
    }
    
    これは正常に梱包されたルートの書き方です。コードを分割する必要があるなら、私達はルートを改造して、get Componentとrequire.ensureを借りる必要があります。
    webpackコード分割
    
    export default function({history}) {
      return (
        <Router history={history}>
          <Route path="/" getComponent={(location, callback) => {
            require.ensure([], function(require) {
              callback(null, require('./HomePage.jsx'))
            })
          }} />
          <Route path="/about" getComponent={(location, callback) => {
            require.ensure([], function(require) {
              callback(null, require('./AboutPage.jsx'))
            })
          }} />
        </Router>
      )
    }
    
    このようにコードはちょっと疲れています。ちょっと改造してみます。
    
    const home = (location, callback) => {
     require.ensure([], require => {
      callback(null, require('./HomePage.jsx'))
     }, 'home')
    }
    
    const about = (location, callback) => {
     require.ensure([], require => {
      callback(null, require('./AboutPage.jsx'))
     }, 'about')
    }
    export default function({history}) {
      return (
        <Router history={history}>
          <Route path="/" getComponent={home}></Route>
          <Route path="/about" getComponent={about}></Route>
        </Router>
      )
    }
    
    
    これは簡潔に見えますか?
    注意:webpackのため、直接require('./AboutPage.jsx')が正常にロードされない場合は、require('./AboutPage.jsx')を試してください。default
    webpack 2コード分割
    上のコードは全部webpack 1の書き方のようですが、webpack 2は?
    webpac 2はSystem.importを借りる必要があります。
    
    export default function({history}) {
      return (
        <Router history={history}>
          <Route path="/" getComponent={(location, callback) => {
            System.import('./HomePage.jsx').then(component => {
              callback(null, component.default || component)
            })
          }} />
          <Route path="/about" getComponent={(location, callback) => {
            System.import('./AboutPage.jsx').then(component => {
              callback(null, component.default || component)
            })
          }} />
        </Router>
      )
    }
    上のコードを最適化してもいいです。
    
    const home = (location, callback) => {
      System.import('./HomePage.jsx').then(component => {
        callback(null, component.default || component)
      })
    }
    const about = (location, callback) => {
      System.import('./AboutPage.jsx').then(component => {
        callback(null, component.default || component)
      })
    }
    
    export default ({ history }) => {
      return (
        <Router history={history}>
          <Route name="home" path="/" getComponent={home} />
          <Route name="about" path="/about" getComponent={about} />
        </Router>
      )
    }
    
    
    webpack 2+dvdはルートとmodelsの怠惰なロードを実現します。
    
    const routerThen = (app, callback, [component, model]) => {
      app.model(model.default || model)
      callback(null, component.default || component)
    }
    
    export default ({ history, app }) => {
      return (
        <Router history={history}>
          <Route name="home" path="/" getComponent={(location, callback) => {
            Promise.all([
              System.import('./views/app.jsx'),
              System.import('./models/topics')
            ]).then(routerThen.bind(null, app, callback))
          }} />
          <Route name="article" path="/article/:id" getComponent={(location, callback) => {
            Promise.all([
              System.import('./views/article.jsx'),
              System.import('./models/topic')
            ]).then(routerThen.bind(null, app, callback))
          }} />
        </Router>
      )
    }
    
    
    以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。