Skip to content

Commit

Permalink
[core] Adds withQuicklink HOC (#172)
Browse files Browse the repository at this point in the history
* [core] Adds withQuicklink HOC

* [infra] /chunks/ -> /react/

* [feedback] Address path fixes for build name change

* [core] configured babel for transpiling the react HOC and updated extensions from mjs to js for react component to avoid errors (#175)

* Spa hoc touches (#176)

* infra: removed babel-preset-env in favor of @babel/preset-env and removed react & react-dom devDependencies for now

* core: added react & react-dom as devDependencies and moved route-manifest from devDependencies to dependencies

* Spa hoc touches (#177)

* infra: removed babel-preset-env in favor of @babel/preset-env and removed react & react-dom devDependencies for now

* core: added react & react-dom as devDependencies and moved route-manifest from devDependencies to dependencies

* chore: removed dev console logs

Co-authored-by: Anton Karlovskiy <[email protected]>
  • Loading branch information
addyosmani and anton-karlovskiy authored Apr 24, 2020
1 parent ea3229a commit 89cd6a9
Show file tree
Hide file tree
Showing 5 changed files with 1,854 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"presets": ["env"]
"presets": ["@babel/preset-react", "@babel/preset-env"]
}
20 changes: 15 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@
"start": "http-server .",
"test": "yarn run build-all && mocha test/bootstrap.js --recursive test",
"build": "microbundle src/index.mjs --no-sourcemap --external none",
"build-plugin": "microbundle src/chunks.mjs --no-sourcemap --external none -o dist/chunks",
"build-all": "yarn run build && yarn run build-plugin",
"build-plugin": "microbundle src/chunks.mjs --no-sourcemap --external none -o dist/react",
"build-all": "yarn run build && yarn run build-plugin && yarn run build-react-chunks",
"prepare": "yarn run -s build",
"build-react-chunks": "./node_modules/.bin/babel src/react-chunks.js --out-file dist/react/hoc.js",
"bundlesize": "bundlesize",
"changelog": "yarn conventional-changelog -i CHANGELOG.md -s -r 0",
"release": "cross-var yarn run build -s && cross-var git commit -am $npm_package_version && cross-var git tag $npm_package_version && git push && git push --tags"
Expand All @@ -39,10 +40,18 @@
"speed"
],
"dependencies": {
"route-manifest": "^1.0.0",
"throttles": "^1.0.0"
},
"peerDependencies": {
"react": "^16.8.0",
"react-dom": "^16.8.0"
},
"devDependencies": {
"babel-preset-env": "^1.7.0",
"@babel/cli": "^7.8.4",
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@babel/preset-react": "^7.9.4",
"bundlesize": "^0.18.0",
"chai": "^4.2.0",
"conventional-changelog-cli": "^2.0.11",
Expand All @@ -54,12 +63,13 @@
"microbundle": "0.11.0",
"mocha": "^6.2.2",
"puppeteer": "^2.0.0",
"route-manifest": "^1.0.0"
"react": "^16.12.0",
"react-dom": "^16.12.0"
},
"bundlesize": [
{
"path": "./dist/*.js",
"maxSize": "2 kB"
}
]
}
}
84 changes: 84 additions & 0 deletions src/react-chunks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2019-2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import React, { useEffect, useRef, useState } from 'react';
import rmanifest from 'route-manifest';
import { listen } from './quicklink';

const useIntersect = ({ root = null, rootMargin, threshold = 0 } = {}) => {
const [entry, updateEntry] = useState({});
const [node, setNode] = useState(null);
const observer = useRef(null);

useEffect(() => {
if (observer.current) observer.current.disconnect();
observer.current = new window.IntersectionObserver(
([entry]) => updateEntry(entry),
{
root,
rootMargin,
threshold
}
);

const { current: currentObserver } = observer;
if (node) currentObserver.observe(node);

return () => currentObserver.disconnect();
}, [node, root, rootMargin, threshold]);

return [setNode, entry];
};

const __defaultAccessor = mix => {
return (mix && mix.href) || mix || '';
};

const prefetchChunks = (entry, prefetchHandler, accessor = __defaultAccessor) => {
const { files } = rmanifest(window.__rmanifest, entry.pathname);
const chunkURLs = files.map(accessor).filter(Boolean);
if (chunkURLs.length) {
prefetchHandler(chunkURLs);
} else {
// also prefetch regular links in-viewport
prefetchHandler(entry.href);
}
};

const withQuicklink = (Component, options = {}) => {
return props => {
const [ref, entry] = useIntersect({root: document.body.parentElement});
const intersectionRatio = entry.intersectionRatio;

useEffect(() => {
options.prefetchChunks = prefetchChunks;

if (intersectionRatio > 0) {
listen(options);
}
}, [intersectionRatio]);

return (
<div ref={ref}>
<Component {...props} />
</div>
);
};
};

export {
withQuicklink
};
2 changes: 1 addition & 1 deletion test/test-prefetch-chunks.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<a href="main.css">CSS</a>
</section>
<a href="4.html" style="position:absolute;margin-top:900px;">Link 4</a>
<script src="../dist/chunks/quicklink.umd.js"></script>
<script src="../dist/react/quicklink.umd.js"></script>
<script src="../node_modules/route-manifest/dist/rmanifest.min.js"></script>
<script>
const __defaultAccessor = mix => {
Expand Down
Loading

0 comments on commit 89cd6a9

Please sign in to comment.