Skip to content

Commit

Permalink
feat(api): rename hoist -> hoistStatics (#5)
Browse files Browse the repository at this point in the history
Breaking change - change option name
  • Loading branch information
adam-26 committed Feb 24, 2018
2 parents e852ff8 + 7cf4108 commit ff8cd16
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 44 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ _Code splitting with minimal boiler plate_
[![npm](https://img.shields.io/npm/v/react-chunk.svg)](https://www.npmjs.com/package/react-chunk)
[![npm](https://img.shields.io/npm/dm/react-chunk.svg)](https://www.npmjs.com/package/react-chunk)
[![CircleCI branch](https://img.shields.io/circleci/project/github/adam-26/react-chunk/master.svg)](https://circleci.com/gh/adam-26/react-chunk/tree/master)
[![Code Climate](https://img.shields.io/codeclimate/coverage/github/adam-26/react-chunk.svg)](https://codeclimate.com/github/adam-26/react-chunk)
[![Code Climate](https://img.shields.io/codeclimate/github/adam-26/react-chunk.svg)](https://codeclimate.com/github/adam-26/react-chunk)
[![Test Coverage](https://api.codeclimate.com/v1/badges/d805355d2fe47d351663/test_coverage)](https://codeclimate.com/github/adam-26/react-chunk/test_coverage)
[![Maintainability](https://api.codeclimate.com/v1/badges/d805355d2fe47d351663/maintainability)](https://codeclimate.com/github/adam-26/react-chunk/maintainability)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg)](https://conventionalcommits.org)


Expand Down Expand Up @@ -638,11 +638,11 @@ This returns a [ChunksComponent](#chunkscomponent). The `WrappedComponent` for a
The react display name to assign when creating the HOC.
#### `opts.hoist: boolean`
#### `opts.hoistStatics: boolean`
`true` to _hoist_ non-react static methods of the imported component to the HOC. Defaults to `false`.
Note that the static methods are only hoisted after the component is loaded (obviously) - if you're using `hoist: true` on a component its _recommended_ that you `preload` (or `preloadChunks`) the component to avoid invoking static methods that have not yet been assigned to the HOC.
Note that the static methods are only hoisted after the component is loaded (obviously) - if you're using `hoistStatics: true` on a component its _recommended_ that you `preload` (or `preloadChunks`) the component to avoid invoking static methods that have not yet been assigned to the HOC.
Using this option with `chunks` is not supported and will result in an error.
Expand Down
70 changes: 36 additions & 34 deletions __tests__/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,17 @@ function MapImport({ chunk, ...rest }) {
const { isLoading, hasLoaded, error, importKeys } = chunkState;

if (isLoading || error) {
return <div>MyLoadingComponent {JSON.stringify(chunkState)}</div>;
return <div>MyLoadingComponent {JSON.stringify(chunkState)}</div>;
}

if (hasLoaded) {
return (
<React.Fragment>
{importKeys.map((key, idx) => {
return React.createElement(lookupMapComponent(key, imported), { ...rest, key: idx })
})}
</React.Fragment>
);
return (
<React.Fragment>
{importKeys.map((key, idx) => {
return React.createElement(lookupMapComponent(key, imported), { ...rest, key: idx })
})}
</React.Fragment>
);
}

return null;
Expand Down Expand Up @@ -104,8 +104,8 @@ describe('chunk', () => {

test('delay and timeout', async () => {
let ChunkMyComponent = chunk(createLoader(300, () => MyComponent), {
delay: 100,
timeout: 200,
delay: 100,
timeout: 200,
})(SingleImport);

let component1 = renderer.create(<ChunkMyComponent prop="foo" />);
Expand Down Expand Up @@ -178,7 +178,7 @@ describe('chunk', () => {
expect(component1.toJSON()).toMatchSnapshot(); // second retry - loading
await waitFor(400);
expect(component1.toJSON()).toMatchSnapshot(); // timedOut (after all retry attempts)
await waitFor(400);
await waitFor(500);
expect(component1.toJSON()).toMatchSnapshot(); // loaded
});

Expand Down Expand Up @@ -275,7 +275,7 @@ describe('chunk', () => {

test('resolveDefaultImport with no wrapped component', async () => {
let ChunkMyComponent = chunk(createLoader(400, () => ({ MyComponent })), {
resolveDefaultImport: imported => imported.MyComponent
resolveDefaultImport: imported => imported.MyComponent
})();

let component = renderer.create(<ChunkMyComponent prop="foo" />);
Expand All @@ -299,11 +299,11 @@ describe('chunk', () => {
expect(component.toJSON()).toMatchSnapshot(); // success
});

describe('opts.hoist: true', () => {
describe('opts.hoistStatics: true', () => {
test('applies statics in render lifecycle', async () => {
const jestFn = jest.fn();
MyComponent.myStatic = jestFn;
let ChunkMyComponent = chunk(createLoader(400, () => MyComponent), { hoist: true })();
let ChunkMyComponent = chunk(createLoader(400, () => MyComponent), { hoistStatics: true })();

renderer.create(<ChunkMyComponent prop="foo" />);
expect(ChunkMyComponent.myStatic).toBeUndefined(); // initial
Expand All @@ -317,7 +317,7 @@ describe('chunk', () => {
test('applies statics when preloaded on server', async () => {
const jestFn = jest.fn();
MyComponent.myStatic = jestFn;
let ChunkMyComponent = chunk(createLoader(400, () => MyComponent), { hoist: true })();
let ChunkMyComponent = chunk(createLoader(400, () => MyComponent), { hoistStatics: true })();

await preloadAll();

Expand All @@ -327,7 +327,7 @@ describe('chunk', () => {

test('does not apply statics on error', async () => {
let ChunkMyComponent = chunk(createLoader(400, () => { throw new Error(); }), {
hoist: true
hoistStatics: true
})();

renderer.create(<ChunkMyComponent prop="foo" />);
Expand All @@ -340,8 +340,9 @@ describe('chunk', () => {
});

test('throws on server `preloadAll()` when import is invalid', async () => {
// eslint-disable-next-line no-unused-vars
let ChunkMyComponent = chunk(createLoader(400, () => { throw new Error('import err'); }), {
hoist: true
hoistStatics: true
})();

expect.assertions(1);
Expand All @@ -354,7 +355,7 @@ describe('chunk', () => {

test('throws on `preloadChunks()` when import is invalid', async () => {
let ChunkMyComponent = chunk(createLoader(400, () => { throw new Error('import err'); }), {
hoist: true
hoistStatics: true
})();

expect.assertions(1);
Expand All @@ -367,7 +368,7 @@ describe('chunk', () => {

test('throws on static `preload()`', async () => {
let ChunkMyComponent = chunk(createLoader(400, () => { throw new Error('import err'); }), {
hoist: true
hoistStatics: true
})();

expect.assertions(1);
Expand All @@ -381,7 +382,7 @@ describe('chunk', () => {
test('`preloadChunks()` hoists statics before render', async () => {
const jestFn = jest.fn();
MyComponent.myStatic = jestFn;
let ChunkMyComponent = chunk(createLoader(400, () => MyComponent), { hoist: true })();
let ChunkMyComponent = chunk(createLoader(400, () => MyComponent), { hoistStatics: true })();

await preloadChunks([ChunkMyComponent.getChunkLoader()]);

Expand All @@ -400,8 +401,8 @@ describe('chunks', () => {
expect(() => chunks(createLoader(400, () => MyComponent))).toThrow();
});

test('using hoist option throws', async () => {
expect(() => chunks({ a: createLoader(400, () => MyComponent)}, { hoist: true })).toThrow();
test('using hoistStatics option throws', async () => {
expect(() => chunks({ a: createLoader(400, () => MyComponent)}, { hoistStatics: true })).toThrow();
});

test('loads multiple imports', async () => {
Expand Down Expand Up @@ -470,7 +471,7 @@ describe('preloadReady', () => {

test('one', async () => {
let ChunkMyComponent = chunk(createLoader(200, () => MyComponent), {
webpack: () => [1]
webpack: () => [1]
})(SingleImport);

await preloadReady();
Expand Down Expand Up @@ -515,12 +516,12 @@ describe('preloadReady', () => {
expect(loadingComponent.toJSON()).toMatchSnapshot(); // loading
});

describe('hoist: true', function () {
describe('hoistStatics: true', function () {
test('applies statics when pre-loaded on client', async () => {
const jestFn = jest.fn();
MyComponent.myStatic = jestFn;
let ChunkMyComponent = chunk(createLoader(400, () => MyComponent), {
hoist: true,
hoistStatics: true,
webpack: () => [1, 2]
})();

Expand All @@ -531,8 +532,9 @@ describe('preloadReady', () => {
});

test('throws on client `preloadReady()` when import is invalid', async () => {
// eslint-disable-next-line no-unused-vars
let ChunkMyComponent = chunk(createLoader(400, () => { throw new Error('import err'); }), {
hoist: true,
hoistStatics: true,
webpack: () => [1, 2]
})();

Expand All @@ -547,16 +549,16 @@ describe('preloadReady', () => {
});

test('preloadChunks', async () => {
let LoadableMyComponent = chunk(createLoader(300, () => MyComponent))(SingleImport);
let LoadableMapComponent = chunks({ MyComponent: createLoader(300, () => MyComponent) })(MapImport);
let LoadableMyComponent = chunk(createLoader(300, () => MyComponent))(SingleImport);
let LoadableMapComponent = chunks({ MyComponent: createLoader(300, () => MyComponent) })(MapImport);

const loaders = [LoadableMyComponent.getChunkLoader(), LoadableMapComponent.getChunkLoader()];
const loaders = [LoadableMyComponent.getChunkLoader(), LoadableMapComponent.getChunkLoader()];

await preloadChunks(loaders);
await preloadChunks(loaders);

let chunkComponent = renderer.create(<LoadableMyComponent prop="baz" />);
let chunksComponent = renderer.create(<LoadableMapComponent prop="foo" />);
let chunkComponent = renderer.create(<LoadableMyComponent prop="baz" />);
let chunksComponent = renderer.create(<LoadableMapComponent prop="foo" />);

expect(chunkComponent.toJSON()).toMatchSnapshot();
expect(chunksComponent.toJSON()).toMatchSnapshot();
expect(chunkComponent.toJSON()).toMatchSnapshot();
expect(chunksComponent.toJSON()).toMatchSnapshot();
});
12 changes: 6 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ function createChunkComponent(loadFn, options) {
let opts = Object.assign({
displayName: null,
loader: null,
hoist: false,
hoistStatics: false,
resolveDefaultImport: (imported /*, importKey */) => resolve(imported),
retryBackOff: [],
delay: 200,
Expand Down Expand Up @@ -353,7 +353,7 @@ function createChunkComponent(loadFn, options) {

let _hoisted = false;
function hoistStatics() {
if (_hoisted || !opts.hoist) {
if (_hoisted || !opts.hoistStatics) {
return;
}

Expand All @@ -374,12 +374,12 @@ function createChunkComponent(loadFn, options) {
});
}

if (opts.hoist) {
if (opts.hoistStatics) {
res.promise = res.promise
.then(() => { hoistStatics(); })
.catch(err => {
if (throwOnImportError === true) {
// When pre-loading, any loader errors will be thrown immediately (ie: hoist, timeout options)
// When pre-loading, any loader errors will be thrown immediately (ie: hoistStatics, timeout options)
// - hoisting implies use of static methods, which need to be available prior to rendering.
throw err;
}
Expand Down Expand Up @@ -417,8 +417,8 @@ function chunks(dynamicImport, opts = {}, webpackOpts = {}) {
throw new Error('`chunks()` requires a map of import functions.');
}

if (typeof opts.hoist !== 'undefined') {
throw new Error('`chunks()` does not support the "hoist" option.');
if (typeof opts.hoistStatics !== 'undefined') {
throw new Error('`chunks()` does not support the "hoistStatics" option.');
}

return createChunkComponent(loadMap, {...webpackOpts, ...opts, loader: dynamicImport, singleImport: false });
Expand Down

0 comments on commit ff8cd16

Please sign in to comment.