Skip to content

Commit 9b774d9

Browse files
committed
refactor double nested code splitting + react-hot-loader
1 parent 098a99a commit 9b774d9

File tree

9 files changed

+75
-27
lines changed

9 files changed

+75
-27
lines changed

README.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,12 @@ What you could load using `useImported`? Everything - `imported` itself is using
163163
<a name="api"/>
164164

165165
# API
166+
> Don't forget - there are TS typings provided.
166167
167168
### Code splitting components
168169
> import {*} from 'react-imported-component';
170+
171+
##### importedComponent
169172
- `importedComponent(importFunction, [options]): ComponentLoader` - main API, default export, HOC to create imported component.
170173
- `importFunction - function which resolves with Component to be imported.
171174
- `options` - optional settings
@@ -178,12 +181,18 @@ What you could load using `useImported`? Everything - `imported` itself is using
178181

179182
- [static] `.preload` - static method to preload components.
180183

184+
##### lazy
181185
- `lazy(importFunction)` - helper to mimic __React.lazy__ behavior
182186

183-
- `useImported(importFunction, exportPicker?)` - code splitting hook
184-
- `importFunction` - a function which resolves to `default` or `wildcard` import(T | {default:T})
185-
- `exportPicker` - function to pick "T" from the import
187+
##### useImported
186188

189+
- `useImported(importFunction, [exportPicker], [options])` - code splitting hook
190+
- `importFunction` - a function which resolves to `default` or `wildcard` import(T | {default:T})
191+
- `[exportPicker]` - function to pick "T" from the import
192+
- `[options]` - options to the hook
193+
- `[options.import]` - controls import. Hooks would be executed only if this is not false
194+
- `[options.track]` - ability to disable server-side usage tracking.
195+
]
187196
### Server side API
188197
> import {*} from 'react-imported-component/server';
189198
- `whenComponentsReady():Promise` - will be resolved, when all components are loaded. Usually on the next "Promise" tick.

examples/react-hot-loader/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
"dependencies": {
2121
"react": "^16.9.0",
2222
"react-dom": "^16.9.0",
23-
"react-hot-loader": "^4.12.11",
24-
"react-imported-component": "../../react-imported-component-6.0.0-beta.1.tgz",
23+
"react-hot-loader": "^4.12.12",
24+
"react-imported-component": "^6.0.1",
2525
"react-portal": "^4.1.2"
2626
}
2727
}
Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
11
import React from 'react'
2-
import { Portal } from 'react-portal'
2+
import imported, {remapImports} from 'react-imported-component';
3+
import {Portal} from 'react-portal'
34
import hidden from './HiddenComponent'
45

6+
const V = 2;
7+
console.log('run ', V);
8+
const SubAsync = imported(() => {
9+
console.log('import ', V);
10+
return remapImports(import('./SubAsync'), x => x.SubAsync)
11+
});
12+
513
const Hidden = hidden();
614

715
const APortal = () => (
816
<Portal>
917
This is a async portal
10-
<Hidden.counter />
18+
<Hidden.counter/>
1119
</Portal>
12-
)
20+
);
1321

1422
export default () => (
1523
<div>
1624
ASYNC 77
17-
<Hidden.counter />
18-
and <APortal />
25+
<Hidden.counter/>
26+
and <APortal/>
27+
+ <SubAsync/>
1928
</div>
20-
)
29+
);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import React from 'react'
2+
3+
console.log('sub async 4');
4+
5+
export const SubAsync = () => (
6+
<div>
7+
Async In Async!
8+
</div>
9+
);

examples/react-hot-loader/yarn.lock

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4311,10 +4311,10 @@ react-dom@^16.9.0:
43114311
prop-types "^15.6.2"
43124312
scheduler "^0.15.0"
43134313

4314-
react-hot-loader@^4.12.11:
4315-
version "4.12.11"
4316-
resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.12.11.tgz#06bd618d0a7343c8afa4a31206844f651193bae5"
4317-
integrity sha512-ySsg1hPwr/5dkZCJVp1nZRbwbpbEQ+3e2+bn/D681Wvr9+o+5bLKkTGq0TXskj8HgCS3ScysXddOng9Cg+JKzw==
4314+
react-hot-loader@^4.12.12:
4315+
version "4.12.12"
4316+
resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.12.12.tgz#8b33f59efef8a34f64e01f0d9393230d4b4bc6d4"
4317+
integrity sha512-Tkd412j5yPKHoTRsJzZb+5UJNFKkPszm7QGKGYvt+jnzTkDS+qK0u3AYPlB0MmBlwzUKVHICqq5KH9Srzda7XA==
43184318
dependencies:
43194319
fast-levenshtein "^2.0.6"
43204320
global "^4.3.0"
@@ -4325,9 +4325,10 @@ react-hot-loader@^4.12.11:
43254325
shallowequal "^1.1.0"
43264326
source-map "^0.7.3"
43274327

4328-
react-imported-component@../../react-imported-component-6.0.0-beta.1.tgz:
4329-
version "6.0.0-beta.1"
4330-
resolved "../../react-imported-component-6.0.0-beta.1.tgz#68c7662e275da8cb5d234f214a0398c95e9d1fef"
4328+
react-imported-component@^6.0.1:
4329+
version "6.0.1"
4330+
resolved "https://registry.yarnpkg.com/react-imported-component/-/react-imported-component-6.0.1.tgz#b1b88c612e2474a1139be261eaed93e9b4da9780"
4331+
integrity sha512-+No+Qhu6Z/d8hmj3PneuQZ/4MaO0WQdPdDbLeQlJOE5mvyjyft53el7Lpazvte+3kXX787nnH7SkoDZ0OU+NUQ==
43314332
dependencies:
43324333
crc-32 "^1.2.0"
43334334
detect-node "^2.0.4"

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,17 @@
6464
"tslib": "^1.10.0"
6565
},
6666
"size-limit": [
67+
{
68+
"path": ["dist/es2015/index.js", "dist/es2015/boot.js"],
69+
"limit": "3.3 KB"
70+
},
6771
{
6872
"path": "dist/es2015/index.js",
6973
"limit": "3 KB"
7074
},
7175
{
7276
"path": "dist/es2015/boot.js",
73-
"limit": "1.5 KB"
77+
"limit": "1.6 KB"
7478
}
7579
],
7680
"engines": {

src/HOC.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import * as React from 'react';
22
import {ImportedComponent} from './Component';
3-
import {executeLoadable, getLoadable} from './loadable';
4-
import {HOC, HOCType, LazyImport, Loadable} from "./types";
3+
import {getLoadable} from './loadable';
4+
import {ComponentOptions, DefaultComponentImport, HOCOptions, HOCType, LazyImport} from "./types";
55
import {useLoadable} from "./useImported";
6-
import {useEffect, useRef, useState, useMemo} from "react";
6+
import {useMemo} from "react";
77
import {asDefault} from "./utils";
88
import {isBackend} from "./detectBackend";
9-
import {Simulate} from "react-dom/test-utils";
10-
import load = Simulate.load;
119

1210
/**
1311
*
@@ -18,7 +16,10 @@ import load = Simulate.load;
1816
* @param {Function} [options.onError] - error handler. Will consume the real error.
1917
* @param {Function} [options.async] - enable React 16+ suspense.
2018
*/
21-
const loader: HOC = (loaderFunction, baseOptions = {}) => {
19+
function loader<P, K = P>(
20+
loaderFunction: DefaultComponentImport<P>,
21+
baseOptions: Partial<ComponentOptions<P, K>> & HOCOptions = {}
22+
): HOCType<P, K> {
2223
const loadable = getLoadable(loaderFunction);
2324

2425
const Imported = React.forwardRef<any, any>(

src/loadable.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ function toLoadable<T>(firstImportFunction: Promised<T>, autoImport = true): Loa
109109
if(this.promise) {
110110
this.promise = undefined;
111111

112-
return this.load();
112+
return this.load() as any;
113113
}
114114
return Promise.resolve();
115115
},

src/useImported.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@ function loadLoadable(loadable: Loadable<any>, callback: (l: any) => void) {
1414
.then(upd, upd);
1515
}
1616

17+
const WEAK_MAP = new WeakMap<Loadable<any>, any>();
18+
19+
20+
function executeLoadableEventually(loadable: Loadable<any>, cb: any) {
21+
const tracker = {};
22+
WEAK_MAP.set(loadable, tracker);
23+
24+
// execute loadable after some timeout to let HMR propagate thought
25+
setTimeout(() => {
26+
if (WEAK_MAP.get(loadable) === tracker) {
27+
loadable.reload().then(cb);
28+
}
29+
}, 16);
30+
}
31+
1732
interface ImportedShape<T> {
1833
imported?: T;
1934
error?: any;
@@ -91,7 +106,7 @@ export function useImported<T, K = T>(importer: DefaultImport<T> | Loadable<T>,
91106
// kick loading effect
92107
useEffect(() => {
93108
if (postEffectRef.current) {
94-
executeLoadable(importer).then(update);
109+
executeLoadableEventually(loadable, update);
95110
}
96111

97112
postEffectRef.current = true;

0 commit comments

Comments
 (0)