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>
)