From 18a68340b5b1d714dc4c4f0b0aff60caf9e90fae Mon Sep 17 00:00:00 2001 From: Ward Peeters Date: Wed, 3 Aug 2022 12:43:50 +0200 Subject: [PATCH 1/5] fix jest using gatsby-link --- packages/gatsby-link/package.json | 10 +- packages/gatsby-link/src/index-esm.js | 229 +++++++++++++++++++++++++ packages/gatsby-link/src/index.js | 232 +------------------------- 3 files changed, 242 insertions(+), 229 deletions(-) create mode 100644 packages/gatsby-link/src/index-esm.js diff --git a/packages/gatsby-link/package.json b/packages/gatsby-link/package.json index eeaf8bef7f46b..fc87d5acb91ad 100644 --- a/packages/gatsby-link/package.json +++ b/packages/gatsby-link/package.json @@ -16,8 +16,12 @@ ], "sideEffects": false, "scripts": { - "build": "microbundle -f cjs,modern --jsx React.createElement --generateTypes false", - "watch": "npm run build watch --no-compress", + "build": "npm-run-all --npm-path npm -s build:cjs build:esm", + "build:cjs": "microbundle -f cjs --jsx React.createElement --generateTypes false", + "build:esm": "microbundle -f modern --jsx React.createElement --generateTypes false -i src/index-esm.js", + "watch": "npm-run-all --npm-path npm -p watch:cjs watch:esm", + "watch:cjs": "npm run build:cjs watch --no-compress", + "watch:esm": "npm run build:esm watch --no-compress", "prepare": "cross-env NODE_ENV=production npm run clean && npm run build", "clean": "del-cli dist/*" }, @@ -50,4 +54,4 @@ "engines": { "node": ">=14.15.0" } -} +} \ No newline at end of file diff --git a/packages/gatsby-link/src/index-esm.js b/packages/gatsby-link/src/index-esm.js new file mode 100644 index 0000000000000..67cc83d6eee3c --- /dev/null +++ b/packages/gatsby-link/src/index-esm.js @@ -0,0 +1,229 @@ +import PropTypes from "prop-types" +import React from "react" +import { Link, Location } from "@gatsbyjs/reach-router" +import { parsePath } from "./parse-path" +import { isLocalLink } from "./is-local-link" +import { rewriteLinkPath } from "./rewrite-link-path" +import { withPrefix, getGlobalPathPrefix } from "./prefix-helpers" + +export { parsePath, withPrefix } + +export function withAssetPrefix(path) { + return withPrefix(path, getGlobalPathPrefix()) +} + +const NavLinkPropTypes = { + activeClassName: PropTypes.string, + activeStyle: PropTypes.object, + partiallyActive: PropTypes.bool, +} + +// Set up IntersectionObserver +const createIntersectionObserver = (el, cb) => { + const io = new window.IntersectionObserver(entries => { + entries.forEach(entry => { + if (el === entry.target) { + // Check if element is within viewport, remove listener, destroy observer, and run link callback. + // MSEdge doesn't currently support isIntersecting, so also test for an intersectionRatio > 0 + cb(entry.isIntersecting || entry.intersectionRatio > 0) + } + }) + }) + + // Add element to the observer + io.observe(el) + + return { instance: io, el } +} + +function GatsbyLinkLocationWrapper(props) { + return ( + + {({ location }) => } + + ) +} + +class GatsbyLink extends React.Component { + constructor(props) { + super(props) + // Default to no support for IntersectionObserver + let IOSupported = false + if (typeof window !== `undefined` && window.IntersectionObserver) { + IOSupported = true + } + + this.state = { + IOSupported, + } + this.abortPrefetch = null + this.handleRef = this.handleRef.bind(this) + } + + _prefetch() { + let currentPath = window.location.pathname + window.location.search + + // reach router should have the correct state + if (this.props._location && this.props._location.pathname) { + currentPath = this.props._location.pathname + this.props._location.search + } + + const rewrittenPath = rewriteLinkPath(this.props.to, currentPath) + const parsed = parsePath(rewrittenPath) + + const newPathName = parsed.pathname + parsed.search + + // Prefetch is used to speed up next navigations. When you use it on the current navigation, + // there could be a race-condition where Chrome uses the stale data instead of waiting for the network to complete + if (currentPath !== newPathName) { + return ___loader.enqueue(newPathName) + } + + return undefined + } + + componentWillUnmount() { + if (!this.io) { + return + } + const { instance, el } = this.io + + if (this.abortPrefetch) { + this.abortPrefetch.abort() + } + + instance.unobserve(el) + instance.disconnect() + } + + handleRef(ref) { + if ( + this.props.innerRef && + Object.prototype.hasOwnProperty.call(this.props.innerRef, `current`) + ) { + this.props.innerRef.current = ref + } else if (this.props.innerRef) { + this.props.innerRef(ref) + } + + if (this.state.IOSupported && ref) { + // If IO supported and element reference found, setup Observer functionality + this.io = createIntersectionObserver(ref, inViewPort => { + if (inViewPort) { + this.abortPrefetch = this._prefetch() + } else { + if (this.abortPrefetch) { + this.abortPrefetch.abort() + } + } + }) + } + } + + defaultGetProps = ({ isPartiallyCurrent, isCurrent }) => { + if (this.props.partiallyActive ? isPartiallyCurrent : isCurrent) { + return { + className: [this.props.className, this.props.activeClassName] + .filter(Boolean) + .join(` `), + style: { ...this.props.style, ...this.props.activeStyle }, + } + } + return null + } + + render() { + const { + to, + getProps = this.defaultGetProps, + onClick, + onMouseEnter, + /* eslint-disable no-unused-vars */ + activeClassName: $activeClassName, + activeStyle: $activeStyle, + innerRef: $innerRef, + partiallyActive, + state, + replace, + _location, + /* eslint-enable no-unused-vars */ + ...rest + } = this.props + + if (process.env.NODE_ENV !== `production` && !isLocalLink(to)) { + console.warn( + `External link ${to} was detected in a Link component. Use the Link component only for internal links. See: https://gatsby.dev/internal-links` + ) + } + + const prefixedTo = rewriteLinkPath(to, _location.pathname) + if (!isLocalLink(prefixedTo)) { + return + } + + return ( + { + if (onMouseEnter) { + onMouseEnter(e) + } + const parsed = parsePath(prefixedTo) + ___loader.hovering(parsed.pathname + parsed.search) + }} + onClick={e => { + if (onClick) { + onClick(e) + } + + if ( + e.button === 0 && // ignore right clicks + !this.props.target && // let browser handle "target=_blank" + !e.defaultPrevented && // onClick prevented default + !e.metaKey && // ignore clicks with modifier keys... + !e.altKey && + !e.ctrlKey && + !e.shiftKey + ) { + e.preventDefault() + + let shouldReplace = replace + const isCurrent = encodeURI(prefixedTo) === _location.pathname + + if (typeof replace !== `boolean` && isCurrent) { + shouldReplace = true + } + // Make sure the necessary scripts and data are + // loaded before continuing. + window.___navigate(prefixedTo, { + state, + replace: shouldReplace, + }) + } + + return true + }} + {...rest} + /> + ) + } +} + +GatsbyLink.propTypes = { + ...NavLinkPropTypes, + onClick: PropTypes.func, + to: PropTypes.string.isRequired, + replace: PropTypes.bool, + state: PropTypes.object, +} + +export default React.forwardRef((props, ref) => ( + +)) + +export const navigate = (to, options) => { + window.___navigate(rewriteLinkPath(to, window.location.pathname), options) +} diff --git a/packages/gatsby-link/src/index.js b/packages/gatsby-link/src/index.js index 67cc83d6eee3c..421a9a337532a 100644 --- a/packages/gatsby-link/src/index.js +++ b/packages/gatsby-link/src/index.js @@ -1,229 +1,9 @@ -import PropTypes from "prop-types" -import React from "react" -import { Link, Location } from "@gatsbyjs/reach-router" -import { parsePath } from "./parse-path" -import { isLocalLink } from "./is-local-link" -import { rewriteLinkPath } from "./rewrite-link-path" -import { withPrefix, getGlobalPathPrefix } from "./prefix-helpers" +import * as Link from "./index-esm.js" -export { parsePath, withPrefix } +module.exports = Link.default -export function withAssetPrefix(path) { - return withPrefix(path, getGlobalPathPrefix()) -} - -const NavLinkPropTypes = { - activeClassName: PropTypes.string, - activeStyle: PropTypes.object, - partiallyActive: PropTypes.bool, -} - -// Set up IntersectionObserver -const createIntersectionObserver = (el, cb) => { - const io = new window.IntersectionObserver(entries => { - entries.forEach(entry => { - if (el === entry.target) { - // Check if element is within viewport, remove listener, destroy observer, and run link callback. - // MSEdge doesn't currently support isIntersecting, so also test for an intersectionRatio > 0 - cb(entry.isIntersecting || entry.intersectionRatio > 0) - } - }) +Object.getOwnPropertyNames(Link).forEach(key => { + Object.defineProperty(module.exports, key, { + value: Link[key], }) - - // Add element to the observer - io.observe(el) - - return { instance: io, el } -} - -function GatsbyLinkLocationWrapper(props) { - return ( - - {({ location }) => } - - ) -} - -class GatsbyLink extends React.Component { - constructor(props) { - super(props) - // Default to no support for IntersectionObserver - let IOSupported = false - if (typeof window !== `undefined` && window.IntersectionObserver) { - IOSupported = true - } - - this.state = { - IOSupported, - } - this.abortPrefetch = null - this.handleRef = this.handleRef.bind(this) - } - - _prefetch() { - let currentPath = window.location.pathname + window.location.search - - // reach router should have the correct state - if (this.props._location && this.props._location.pathname) { - currentPath = this.props._location.pathname + this.props._location.search - } - - const rewrittenPath = rewriteLinkPath(this.props.to, currentPath) - const parsed = parsePath(rewrittenPath) - - const newPathName = parsed.pathname + parsed.search - - // Prefetch is used to speed up next navigations. When you use it on the current navigation, - // there could be a race-condition where Chrome uses the stale data instead of waiting for the network to complete - if (currentPath !== newPathName) { - return ___loader.enqueue(newPathName) - } - - return undefined - } - - componentWillUnmount() { - if (!this.io) { - return - } - const { instance, el } = this.io - - if (this.abortPrefetch) { - this.abortPrefetch.abort() - } - - instance.unobserve(el) - instance.disconnect() - } - - handleRef(ref) { - if ( - this.props.innerRef && - Object.prototype.hasOwnProperty.call(this.props.innerRef, `current`) - ) { - this.props.innerRef.current = ref - } else if (this.props.innerRef) { - this.props.innerRef(ref) - } - - if (this.state.IOSupported && ref) { - // If IO supported and element reference found, setup Observer functionality - this.io = createIntersectionObserver(ref, inViewPort => { - if (inViewPort) { - this.abortPrefetch = this._prefetch() - } else { - if (this.abortPrefetch) { - this.abortPrefetch.abort() - } - } - }) - } - } - - defaultGetProps = ({ isPartiallyCurrent, isCurrent }) => { - if (this.props.partiallyActive ? isPartiallyCurrent : isCurrent) { - return { - className: [this.props.className, this.props.activeClassName] - .filter(Boolean) - .join(` `), - style: { ...this.props.style, ...this.props.activeStyle }, - } - } - return null - } - - render() { - const { - to, - getProps = this.defaultGetProps, - onClick, - onMouseEnter, - /* eslint-disable no-unused-vars */ - activeClassName: $activeClassName, - activeStyle: $activeStyle, - innerRef: $innerRef, - partiallyActive, - state, - replace, - _location, - /* eslint-enable no-unused-vars */ - ...rest - } = this.props - - if (process.env.NODE_ENV !== `production` && !isLocalLink(to)) { - console.warn( - `External link ${to} was detected in a Link component. Use the Link component only for internal links. See: https://gatsby.dev/internal-links` - ) - } - - const prefixedTo = rewriteLinkPath(to, _location.pathname) - if (!isLocalLink(prefixedTo)) { - return - } - - return ( - { - if (onMouseEnter) { - onMouseEnter(e) - } - const parsed = parsePath(prefixedTo) - ___loader.hovering(parsed.pathname + parsed.search) - }} - onClick={e => { - if (onClick) { - onClick(e) - } - - if ( - e.button === 0 && // ignore right clicks - !this.props.target && // let browser handle "target=_blank" - !e.defaultPrevented && // onClick prevented default - !e.metaKey && // ignore clicks with modifier keys... - !e.altKey && - !e.ctrlKey && - !e.shiftKey - ) { - e.preventDefault() - - let shouldReplace = replace - const isCurrent = encodeURI(prefixedTo) === _location.pathname - - if (typeof replace !== `boolean` && isCurrent) { - shouldReplace = true - } - // Make sure the necessary scripts and data are - // loaded before continuing. - window.___navigate(prefixedTo, { - state, - replace: shouldReplace, - }) - } - - return true - }} - {...rest} - /> - ) - } -} - -GatsbyLink.propTypes = { - ...NavLinkPropTypes, - onClick: PropTypes.func, - to: PropTypes.string.isRequired, - replace: PropTypes.bool, - state: PropTypes.object, -} - -export default React.forwardRef((props, ref) => ( - -)) - -export const navigate = (to, options) => { - window.___navigate(rewriteLinkPath(to, window.location.pathname), options) -} +}) From c61f521e89903bf28c612614609f36532fb3da46 Mon Sep 17 00:00:00 2001 From: pieh Date: Wed, 3 Aug 2022 13:05:13 +0200 Subject: [PATCH 2/5] invert setup, to continue to use index.js as source of code, and introduce new index-cjs module for wrapping --- packages/gatsby-link/package.json | 4 +- packages/gatsby-link/src/index-cjs.js | 9 + packages/gatsby-link/src/index-esm.js | 229 ------------------------- packages/gatsby-link/src/index.js | 232 +++++++++++++++++++++++++- 4 files changed, 237 insertions(+), 237 deletions(-) create mode 100644 packages/gatsby-link/src/index-cjs.js delete mode 100644 packages/gatsby-link/src/index-esm.js diff --git a/packages/gatsby-link/package.json b/packages/gatsby-link/package.json index fc87d5acb91ad..b110c1b4d73f0 100644 --- a/packages/gatsby-link/package.json +++ b/packages/gatsby-link/package.json @@ -17,8 +17,8 @@ "sideEffects": false, "scripts": { "build": "npm-run-all --npm-path npm -s build:cjs build:esm", - "build:cjs": "microbundle -f cjs --jsx React.createElement --generateTypes false", - "build:esm": "microbundle -f modern --jsx React.createElement --generateTypes false -i src/index-esm.js", + "build:cjs": "microbundle -f cjs --jsx React.createElement --generateTypes false -i src/index-cjs.js", + "build:esm": "microbundle -f modern --jsx React.createElement --generateTypes false", "watch": "npm-run-all --npm-path npm -p watch:cjs watch:esm", "watch:cjs": "npm run build:cjs watch --no-compress", "watch:esm": "npm run build:esm watch --no-compress", diff --git a/packages/gatsby-link/src/index-cjs.js b/packages/gatsby-link/src/index-cjs.js new file mode 100644 index 0000000000000..421a9a337532a --- /dev/null +++ b/packages/gatsby-link/src/index-cjs.js @@ -0,0 +1,9 @@ +import * as Link from "./index-esm.js" + +module.exports = Link.default + +Object.getOwnPropertyNames(Link).forEach(key => { + Object.defineProperty(module.exports, key, { + value: Link[key], + }) +}) diff --git a/packages/gatsby-link/src/index-esm.js b/packages/gatsby-link/src/index-esm.js deleted file mode 100644 index 67cc83d6eee3c..0000000000000 --- a/packages/gatsby-link/src/index-esm.js +++ /dev/null @@ -1,229 +0,0 @@ -import PropTypes from "prop-types" -import React from "react" -import { Link, Location } from "@gatsbyjs/reach-router" -import { parsePath } from "./parse-path" -import { isLocalLink } from "./is-local-link" -import { rewriteLinkPath } from "./rewrite-link-path" -import { withPrefix, getGlobalPathPrefix } from "./prefix-helpers" - -export { parsePath, withPrefix } - -export function withAssetPrefix(path) { - return withPrefix(path, getGlobalPathPrefix()) -} - -const NavLinkPropTypes = { - activeClassName: PropTypes.string, - activeStyle: PropTypes.object, - partiallyActive: PropTypes.bool, -} - -// Set up IntersectionObserver -const createIntersectionObserver = (el, cb) => { - const io = new window.IntersectionObserver(entries => { - entries.forEach(entry => { - if (el === entry.target) { - // Check if element is within viewport, remove listener, destroy observer, and run link callback. - // MSEdge doesn't currently support isIntersecting, so also test for an intersectionRatio > 0 - cb(entry.isIntersecting || entry.intersectionRatio > 0) - } - }) - }) - - // Add element to the observer - io.observe(el) - - return { instance: io, el } -} - -function GatsbyLinkLocationWrapper(props) { - return ( - - {({ location }) => } - - ) -} - -class GatsbyLink extends React.Component { - constructor(props) { - super(props) - // Default to no support for IntersectionObserver - let IOSupported = false - if (typeof window !== `undefined` && window.IntersectionObserver) { - IOSupported = true - } - - this.state = { - IOSupported, - } - this.abortPrefetch = null - this.handleRef = this.handleRef.bind(this) - } - - _prefetch() { - let currentPath = window.location.pathname + window.location.search - - // reach router should have the correct state - if (this.props._location && this.props._location.pathname) { - currentPath = this.props._location.pathname + this.props._location.search - } - - const rewrittenPath = rewriteLinkPath(this.props.to, currentPath) - const parsed = parsePath(rewrittenPath) - - const newPathName = parsed.pathname + parsed.search - - // Prefetch is used to speed up next navigations. When you use it on the current navigation, - // there could be a race-condition where Chrome uses the stale data instead of waiting for the network to complete - if (currentPath !== newPathName) { - return ___loader.enqueue(newPathName) - } - - return undefined - } - - componentWillUnmount() { - if (!this.io) { - return - } - const { instance, el } = this.io - - if (this.abortPrefetch) { - this.abortPrefetch.abort() - } - - instance.unobserve(el) - instance.disconnect() - } - - handleRef(ref) { - if ( - this.props.innerRef && - Object.prototype.hasOwnProperty.call(this.props.innerRef, `current`) - ) { - this.props.innerRef.current = ref - } else if (this.props.innerRef) { - this.props.innerRef(ref) - } - - if (this.state.IOSupported && ref) { - // If IO supported and element reference found, setup Observer functionality - this.io = createIntersectionObserver(ref, inViewPort => { - if (inViewPort) { - this.abortPrefetch = this._prefetch() - } else { - if (this.abortPrefetch) { - this.abortPrefetch.abort() - } - } - }) - } - } - - defaultGetProps = ({ isPartiallyCurrent, isCurrent }) => { - if (this.props.partiallyActive ? isPartiallyCurrent : isCurrent) { - return { - className: [this.props.className, this.props.activeClassName] - .filter(Boolean) - .join(` `), - style: { ...this.props.style, ...this.props.activeStyle }, - } - } - return null - } - - render() { - const { - to, - getProps = this.defaultGetProps, - onClick, - onMouseEnter, - /* eslint-disable no-unused-vars */ - activeClassName: $activeClassName, - activeStyle: $activeStyle, - innerRef: $innerRef, - partiallyActive, - state, - replace, - _location, - /* eslint-enable no-unused-vars */ - ...rest - } = this.props - - if (process.env.NODE_ENV !== `production` && !isLocalLink(to)) { - console.warn( - `External link ${to} was detected in a Link component. Use the Link component only for internal links. See: https://gatsby.dev/internal-links` - ) - } - - const prefixedTo = rewriteLinkPath(to, _location.pathname) - if (!isLocalLink(prefixedTo)) { - return - } - - return ( - { - if (onMouseEnter) { - onMouseEnter(e) - } - const parsed = parsePath(prefixedTo) - ___loader.hovering(parsed.pathname + parsed.search) - }} - onClick={e => { - if (onClick) { - onClick(e) - } - - if ( - e.button === 0 && // ignore right clicks - !this.props.target && // let browser handle "target=_blank" - !e.defaultPrevented && // onClick prevented default - !e.metaKey && // ignore clicks with modifier keys... - !e.altKey && - !e.ctrlKey && - !e.shiftKey - ) { - e.preventDefault() - - let shouldReplace = replace - const isCurrent = encodeURI(prefixedTo) === _location.pathname - - if (typeof replace !== `boolean` && isCurrent) { - shouldReplace = true - } - // Make sure the necessary scripts and data are - // loaded before continuing. - window.___navigate(prefixedTo, { - state, - replace: shouldReplace, - }) - } - - return true - }} - {...rest} - /> - ) - } -} - -GatsbyLink.propTypes = { - ...NavLinkPropTypes, - onClick: PropTypes.func, - to: PropTypes.string.isRequired, - replace: PropTypes.bool, - state: PropTypes.object, -} - -export default React.forwardRef((props, ref) => ( - -)) - -export const navigate = (to, options) => { - window.___navigate(rewriteLinkPath(to, window.location.pathname), options) -} diff --git a/packages/gatsby-link/src/index.js b/packages/gatsby-link/src/index.js index 421a9a337532a..67cc83d6eee3c 100644 --- a/packages/gatsby-link/src/index.js +++ b/packages/gatsby-link/src/index.js @@ -1,9 +1,229 @@ -import * as Link from "./index-esm.js" +import PropTypes from "prop-types" +import React from "react" +import { Link, Location } from "@gatsbyjs/reach-router" +import { parsePath } from "./parse-path" +import { isLocalLink } from "./is-local-link" +import { rewriteLinkPath } from "./rewrite-link-path" +import { withPrefix, getGlobalPathPrefix } from "./prefix-helpers" -module.exports = Link.default +export { parsePath, withPrefix } -Object.getOwnPropertyNames(Link).forEach(key => { - Object.defineProperty(module.exports, key, { - value: Link[key], +export function withAssetPrefix(path) { + return withPrefix(path, getGlobalPathPrefix()) +} + +const NavLinkPropTypes = { + activeClassName: PropTypes.string, + activeStyle: PropTypes.object, + partiallyActive: PropTypes.bool, +} + +// Set up IntersectionObserver +const createIntersectionObserver = (el, cb) => { + const io = new window.IntersectionObserver(entries => { + entries.forEach(entry => { + if (el === entry.target) { + // Check if element is within viewport, remove listener, destroy observer, and run link callback. + // MSEdge doesn't currently support isIntersecting, so also test for an intersectionRatio > 0 + cb(entry.isIntersecting || entry.intersectionRatio > 0) + } + }) }) -}) + + // Add element to the observer + io.observe(el) + + return { instance: io, el } +} + +function GatsbyLinkLocationWrapper(props) { + return ( + + {({ location }) => } + + ) +} + +class GatsbyLink extends React.Component { + constructor(props) { + super(props) + // Default to no support for IntersectionObserver + let IOSupported = false + if (typeof window !== `undefined` && window.IntersectionObserver) { + IOSupported = true + } + + this.state = { + IOSupported, + } + this.abortPrefetch = null + this.handleRef = this.handleRef.bind(this) + } + + _prefetch() { + let currentPath = window.location.pathname + window.location.search + + // reach router should have the correct state + if (this.props._location && this.props._location.pathname) { + currentPath = this.props._location.pathname + this.props._location.search + } + + const rewrittenPath = rewriteLinkPath(this.props.to, currentPath) + const parsed = parsePath(rewrittenPath) + + const newPathName = parsed.pathname + parsed.search + + // Prefetch is used to speed up next navigations. When you use it on the current navigation, + // there could be a race-condition where Chrome uses the stale data instead of waiting for the network to complete + if (currentPath !== newPathName) { + return ___loader.enqueue(newPathName) + } + + return undefined + } + + componentWillUnmount() { + if (!this.io) { + return + } + const { instance, el } = this.io + + if (this.abortPrefetch) { + this.abortPrefetch.abort() + } + + instance.unobserve(el) + instance.disconnect() + } + + handleRef(ref) { + if ( + this.props.innerRef && + Object.prototype.hasOwnProperty.call(this.props.innerRef, `current`) + ) { + this.props.innerRef.current = ref + } else if (this.props.innerRef) { + this.props.innerRef(ref) + } + + if (this.state.IOSupported && ref) { + // If IO supported and element reference found, setup Observer functionality + this.io = createIntersectionObserver(ref, inViewPort => { + if (inViewPort) { + this.abortPrefetch = this._prefetch() + } else { + if (this.abortPrefetch) { + this.abortPrefetch.abort() + } + } + }) + } + } + + defaultGetProps = ({ isPartiallyCurrent, isCurrent }) => { + if (this.props.partiallyActive ? isPartiallyCurrent : isCurrent) { + return { + className: [this.props.className, this.props.activeClassName] + .filter(Boolean) + .join(` `), + style: { ...this.props.style, ...this.props.activeStyle }, + } + } + return null + } + + render() { + const { + to, + getProps = this.defaultGetProps, + onClick, + onMouseEnter, + /* eslint-disable no-unused-vars */ + activeClassName: $activeClassName, + activeStyle: $activeStyle, + innerRef: $innerRef, + partiallyActive, + state, + replace, + _location, + /* eslint-enable no-unused-vars */ + ...rest + } = this.props + + if (process.env.NODE_ENV !== `production` && !isLocalLink(to)) { + console.warn( + `External link ${to} was detected in a Link component. Use the Link component only for internal links. See: https://gatsby.dev/internal-links` + ) + } + + const prefixedTo = rewriteLinkPath(to, _location.pathname) + if (!isLocalLink(prefixedTo)) { + return + } + + return ( + { + if (onMouseEnter) { + onMouseEnter(e) + } + const parsed = parsePath(prefixedTo) + ___loader.hovering(parsed.pathname + parsed.search) + }} + onClick={e => { + if (onClick) { + onClick(e) + } + + if ( + e.button === 0 && // ignore right clicks + !this.props.target && // let browser handle "target=_blank" + !e.defaultPrevented && // onClick prevented default + !e.metaKey && // ignore clicks with modifier keys... + !e.altKey && + !e.ctrlKey && + !e.shiftKey + ) { + e.preventDefault() + + let shouldReplace = replace + const isCurrent = encodeURI(prefixedTo) === _location.pathname + + if (typeof replace !== `boolean` && isCurrent) { + shouldReplace = true + } + // Make sure the necessary scripts and data are + // loaded before continuing. + window.___navigate(prefixedTo, { + state, + replace: shouldReplace, + }) + } + + return true + }} + {...rest} + /> + ) + } +} + +GatsbyLink.propTypes = { + ...NavLinkPropTypes, + onClick: PropTypes.func, + to: PropTypes.string.isRequired, + replace: PropTypes.bool, + state: PropTypes.object, +} + +export default React.forwardRef((props, ref) => ( + +)) + +export const navigate = (to, options) => { + window.___navigate(rewriteLinkPath(to, window.location.pathname), options) +} From 1fa9e0ad5e2fc3c1a933bcf85c3e13ab0c24a27d Mon Sep 17 00:00:00 2001 From: LekoArts Date: Thu, 4 Aug 2022 06:56:24 +0200 Subject: [PATCH 3/5] build correctly --- packages/gatsby-link/package.json | 5 ++--- packages/gatsby-link/src/index-cjs.js | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/gatsby-link/package.json b/packages/gatsby-link/package.json index b110c1b4d73f0..61298f1f8e3f2 100644 --- a/packages/gatsby-link/package.json +++ b/packages/gatsby-link/package.json @@ -6,7 +6,6 @@ "bugs": { "url": "https://github.com/gatsbyjs/gatsby/issues" }, - "source": "src/index.js", "main": "dist/index.js", "module": "dist/index.modern.mjs", "types": "index.d.ts", @@ -17,8 +16,8 @@ "sideEffects": false, "scripts": { "build": "npm-run-all --npm-path npm -s build:cjs build:esm", - "build:cjs": "microbundle -f cjs --jsx React.createElement --generateTypes false -i src/index-cjs.js", - "build:esm": "microbundle -f modern --jsx React.createElement --generateTypes false", + "build:cjs": "microbundle -f cjs --jsx React.createElement --generateTypes false -i src/index-cjs.js -o dist/index.js", + "build:esm": "microbundle -f modern --jsx React.createElement --generateTypes false -o dist/index.mjs", "watch": "npm-run-all --npm-path npm -p watch:cjs watch:esm", "watch:cjs": "npm run build:cjs watch --no-compress", "watch:esm": "npm run build:esm watch --no-compress", diff --git a/packages/gatsby-link/src/index-cjs.js b/packages/gatsby-link/src/index-cjs.js index 421a9a337532a..2f573d74e76bb 100644 --- a/packages/gatsby-link/src/index-cjs.js +++ b/packages/gatsby-link/src/index-cjs.js @@ -1,4 +1,4 @@ -import * as Link from "./index-esm.js" +import * as Link from "./index.js" module.exports = Link.default From c43dc0f4362dfe9be466b003e5a9e47b9ad75ccd Mon Sep 17 00:00:00 2001 From: pieh Date: Thu, 4 Aug 2022 11:31:34 +0200 Subject: [PATCH 4/5] make it work (hopefully) --- packages/gatsby-link/src/index-cjs.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/gatsby-link/src/index-cjs.js b/packages/gatsby-link/src/index-cjs.js index 2f573d74e76bb..30a04d45ec5dc 100644 --- a/packages/gatsby-link/src/index-cjs.js +++ b/packages/gatsby-link/src/index-cjs.js @@ -5,5 +5,6 @@ module.exports = Link.default Object.getOwnPropertyNames(Link).forEach(key => { Object.defineProperty(module.exports, key, { value: Link[key], + enumerable: true, }) }) From 9ef8c124c145f85f34f5fbcc7922a51178794150 Mon Sep 17 00:00:00 2001 From: pieh Date: Thu, 4 Aug 2022 11:52:02 +0200 Subject: [PATCH 5/5] add missing dev dep --- packages/gatsby-link/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/gatsby-link/package.json b/packages/gatsby-link/package.json index 61298f1f8e3f2..a51045cf7ddf9 100644 --- a/packages/gatsby-link/package.json +++ b/packages/gatsby-link/package.json @@ -33,7 +33,8 @@ "@testing-library/react": "^11.2.7", "cross-env": "^7.0.3", "del-cli": "^5.0.0", - "microbundle": "^0.15.0" + "microbundle": "^0.15.0", + "npm-run-all": "^4.1.5" }, "peerDependencies": { "@gatsbyjs/reach-router": "^1.3.5",