0

示例 github 存储库(特定提交)

我正在深入研究反应/中继,并想确保我已经准备好开始开发与生产。我们有一个大型应用程序,因此必须进行代码拆分。

我更喜欢基于 JSX 的react-router路由声明,所以我很高兴遇到Evan Henley的 React Router 和 Webpack的隐式代码拆分和块加载

通过对正则表达式和 ES6 的一些调整,我能够让他的方法工作。克隆reponpm install && npm start您将能够导航到不同的块(todos 除外)。

^^^所有这些都适用于应用程序的非中继部分 - 好东西。

问题

然后...导航到 Todos(基于中继)。

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

我们的生产应用程序将完全依赖于继电器。

中继依赖于一些对类的静态调用,例如getFragment. 在这种情况下,webpack 已推TodoListFooter送到不同的共享块中,因此TodoListFooter2没有getFragment. 相比之下,它在同一行中断,_AddTodoMutation2位于同一块中,因此类似的调用_AddTodoMutation2.default.getFragment('viewer')可以正常工作。

潜在的解决方案

  1. 使用命名块?此提交尝试这样做,但它仍然将一些代码推送到共享块中(并且失败并出现相同的错误)
  2. 与静态方法兼容的不同代码拆分方法?
  3. 有什么我没有想到的?
4

1 回答 1

1

我发现虽然 Evan Henley 的方法更好,但我需要稍微改变它以使其与 Relay 兼容(与 ES6+ 兼容import)。

这需要bundle?lazy在 ES6 导入中显式地与中继兼容。 此提交显示了我发现的使其中继兼容的主要差异。

首先,在 Henley 的代码中,它需要配置 webpack 加载器和导入,例如:

import Landing from './components/Landing'

相比之下,我的方法不需要额外的 webpack 加载器配置,其中包含显式的 bundle-loader 延迟加载import

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

Henley 的方法使路由文件导入更清晰。我的方法使它与 Relay 一起工作,并且是一个更明确的代码拆分 via 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 回答