New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewrite for 4.0 #46

Merged
merged 2 commits into from Jun 15, 2017

Conversation

1 participant
@jamiebuilds
Owner

jamiebuilds commented Jun 15, 2017

Changes:

  • Renamed opts.LoadingComponentopts.loading
  • Replaced opts.resolveModule with opts.render for more control
  • Added opts.timeout to go along with opts.delay
  • opts.delay can be disabled by setting it to false or null
  • Removed opts.serverSideRequirePath (use import-inspector)
  • Removed opts.webpackRequireWeakId (use import-inspector)
  • Removed Loadable.flushServerSideRequirePaths (use import-inspector)
  • Removed Loadable.flushwebpackRequireWeakIds (use import-inspector)
  • Integrated with import-inspector
  • Removed Babel plugin, use babel-plugin-import-inspector
  • Added Loadable.Map for loading multiple resources in parallel

opts.render

This replaces opts.resolveModule to give more control over the actual rendering of the component.

const LoadableComponent = Loadable({
  loader: () => import('./my-component'),
  loading: Loading,
  render(loaded, props) {
    let Component = loaded.namedExport;
    return <Component {...props}/>;
  }
});

opts.timeout

Vue added this, I liked it so I stole it.

function Loading(props) {
  return props.timedOut ? <div>Timed Out</div> : <div>Loading...</div>;
}

const LoadableComponent = Loadable({
  // ...
  loading: Loading,
  timeout: 10000
});

import-inspector

Rather than having a custom API tied to React Loadable for dealing with making import() compatible with synchronous workflows like server-side rendering and first render using Webpack, I've integrated React Loadable with a new library called import-inspector which looks like this:

import {report} from 'import-inspector';
import path from 'path';

Loadable({
  loader: () => report(import('./my-component'), {
    serverSideRequirePath: path.join(__dirname, './my-component'),
    webpackRequireWeakId: () => require.resolveWeak('./my-component')
  })
})

You can automate all of this using:

babel-plugin-import-inspector

Since integrating with import-inspector there's little reason to support a half-baked half-working Babel plugin specific to React Loadable.

Instead, babel-plugin-import-inspector can automatically add everything you need:

Install

yarn add --dev babel-plugin-import-inspector

.babelrc:

{
  "plugins": [
    ["import-inspector", {
      "serverSideRequirePath": true,
      "webpackRequireWeakId": true
    }]
  ]
}

Input:

Loadable({
  loader: () => import('./my-component')
})

Output:

import {report} from 'import-inspector';
import path from 'path';

Loadable({
  loader: () => report(import('./my-component'), {
    serverSideRequirePath: path.join(__dirname, './my-component'),
    webpackRequireWeakId: () => require.resolveWeak('./my-component')
  })
})

flushServerSideRequirePaths and flushwebpackRequireWeakIds

This functionality is no longer necessary when using import-inspector.

Instead you can do this:

import {inspect} from 'import-inspector';

const imported = [];

// setup a watcher
let stopInspecting = inspect(metadata => {
  imported.push(metadata);
});

function flush() {
  let copy = imported.slice();
  imported.length = 0;
  return copy;
}

render();
flush();
// [{ importedModulePath: "./module" }, ...]

render();
flush();
// [{ importedModulePath: "./module" }, ...]

stopInspecting();

Loadable.Map

If you want to load multiple resources in parallel and stitch them together in the render() method you can now do that with Loadable.Map.

Loadable.Map({
  loader: {
    Component: () => import('./my-component'),
    translations: () => fetch('./foo-translations.json').then(res => res.json()),
  },
  render(loaded, props) {
    let Component = loaded.Component.default;
    let translations = loaded.translations;
    return <Component {...props} translations={translations}/>;
  }
});
@jamiebuilds

This comment has been minimized.

Show comment
Hide comment
@jamiebuilds

jamiebuilds Jun 15, 2017

Owner

Added Loadable.Map:

Loadable.Map({
  loader: {
    Component: () => import('./my-component'),
    translations: () => fetch('./foo-translations.json').then(res => res.json()),
  },
  render(loaded, props) {
    let Component = loaded.Component.default;
    let translations = loaded.translations;
    return <Component {...props} translations={translations}/>;
  }
});
Owner

jamiebuilds commented Jun 15, 2017

Added Loadable.Map:

Loadable.Map({
  loader: {
    Component: () => import('./my-component'),
    translations: () => fetch('./foo-translations.json').then(res => res.json()),
  },
  render(loaded, props) {
    let Component = loaded.Component.default;
    let translations = loaded.translations;
    return <Component {...props} translations={translations}/>;
  }
});

@jamiebuilds jamiebuilds merged commit 16aacc9 into master Jun 15, 2017

@jamiebuilds jamiebuilds deleted the next branch Jun 15, 2017

odensc added a commit to odensc/DefinitelyTyped that referenced this pull request Jun 17, 2017

odensc added a commit to odensc/DefinitelyTyped that referenced this pull request Jun 17, 2017

odensc added a commit to odensc/DefinitelyTyped that referenced this pull request Jun 17, 2017

@odensc odensc referenced this pull request Jun 17, 2017

Merged

Update react-loadable types for v4. #17268

7 of 7 tasks complete

odensc added a commit to odensc/DefinitelyTyped that referenced this pull request Jun 17, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment