0

サンプル github リポジトリ(特定のコミット)

私は反応/リレーに飛び込んでおり、開発と本番を開始するためのセットアップが整っていることを確認したいと考えています。大規模なアプリケーションがあるため、コード分割は必須です。

私は JSX ベースreact-routerのルート宣言を好むので、 Evan Henleyの React Router と Webpackを使用したImplicit Code Splitting と Chunk Loading に遭遇できてうれしかったです。

正規表現と ES6 を少し調整することで、彼の方法を機能させることができました。repo のクローンを作成npm install && npm startすると、さまざまなチャンクに移動できるようになります (todo を除く)。

^^^これはすべて、アプリの非リレー部分で機能します-良いことです.

問題

次に... Todos (リレーベース) に移動します。

Uncaught TypeError: _TodoListFooter2.default.getFragment is not a function
viewer 
Fragment 
(instrumented buildRQL.Fragment) 
buildContainerFragment 

私たちの制作アプリはリレーに完全に依存します。

Relay は、 などのクラスへのいくつかの静的呼び出しに依存しますgetFragment。この場合、webpack は別の共有チャンクにプッシュTodoListFooterされているため、. 対照的に、同じ行で壊れ、同じチャンクにあるため、同様の呼び出しは正常に機能します。TodoListFooter2getFragment_AddTodoMutation2_AddTodoMutation2.default.getFragment('viewer')

考えられる解決策

  1. 名前付きチャンクを使用しますか? このコミットはそうしようとしましたが、それでも一部のコードを共有チャンクにプッシュしました (同じエラーで失敗しました)。
  2. 静的メソッドと互換性のあるリレーである別のコード分割方法?
  3. 私が考えていない何か?
4

1 に答える 1

1

Evan Henley のアプローチの方が優れていましたが、Relay と互換性があるようにするには (ES6+ でimport) 少し変更する必要があることがわかりました。

bundle?lazyこれには、リレーと互換性があるために ES6 インポートで 明示的にする必要がありました。このコミットは、リレー互換にするために私が見つけた主な違いを示しています。

主に、ヘンリーのコードでは、webpack ローダーの構成と次のようなインポートが必要でした。

import Landing from './components/Landing'

対照的に、私のアプローチでは、明示的な bundle-loader 遅延読み込みを使用して追加の webpack loader 構成を必要としませんimport

import Landing from 'bundle?lazy!./components/Landing'

Henley の方法により、よりクリーンなルート ファイルのインポートが可能になります。私のアプローチでは、リレーで動作し、正規表現による追加のローダー構成importなしで、より明示的なコード分割です。webpack.config.js

私の方法は、リレー互換にする唯一の方法ですが、それぞれ問題ありません。

実装:

type GetComponent = (location?: string, cb: GetComponentCB) => void

/**
 * Purpose: abbreviated expression so that we can read routes
 *
 * Background:
 *  - (failed) luqin/react-router-loader is awesome, but it is a Proxy and doesn't work with relay components.
 *    @see https://github.com/relay-tools/react-router-relay/issues/161
 *
 *  - (failed) webpack dynamic requires need a hard path root (the rest can be an expression)
 *    at compile time and a regex is created
 *    @see https://webpack.github.io/docs/html#dynamic-requires
 *    @see http://stackoverflow.com/a/37228426/2363935
 *
 *  - (succeeded ultimately) huge-app-splitting-refactor
 *    - uses bundle-loader, works with imports! and no path hardcoding!
 *    - approach doesn't work with Relay (quite as-is)
 *    - fixed approach with explicit bundle lazy imports!
 *    @see http://stackoverflow.com/a/37575707/2363935
 *    @see http://henleyedition.com/implicit-code-splitting-with-react-router-and-webpack/
 *    @see https://github.com/echenley/react-router-huge-apps-refactor
 *
 * @param component
 * @returns {function()}
 */
export function lazy (lazyModule: Function): GetComponent {
  if (!lazyModule) {
    throw new Error('lazy() did not find the given module.  Check to be sure your import path is correct, and make sure you are pointing at a file with a ****default export****.')
  }
  return (location, cb) => {
    lazyModule((module) => {
      cb(null, module.default)
    })
  }
}

使用法:

/* eslint-disable flowtype/require-valid-file-annotation */
import OrganizationQueries from '../../queries/OrganizationQueries'
import React from 'react'
import {Route} from 'react-router'
import {lazy} from '../../config/routes'
import Organization from 'bundle-loader?lazy!./Organization'

// protected by parent route
export default (
  <Route>
    <Route path='/organization' getComponent={lazy(Organization)} queries={OrganizationQueries} />
  </Route>
)
于 2016-06-01T17:56:52.590 に答える