From 6f3c2473c961f97d3d38641c227900bd0e29d5f2 Mon Sep 17 00:00:00 2001 From: Scotty Eckenthal Date: Wed, 7 Feb 2018 15:54:24 -0500 Subject: [PATCH 1/7] Add example boiler --- examples/check-types/.eslintrc | 8 ++++++++ examples/check-types/.gitignore | 3 +++ examples/check-types/README.md | 5 +++++ examples/check-types/package.json | 16 ++++++++++++++++ examples/check-types/src/pages/index.js | 9 +++++++++ 5 files changed, 41 insertions(+) create mode 100644 examples/check-types/.eslintrc create mode 100644 examples/check-types/.gitignore create mode 100644 examples/check-types/README.md create mode 100644 examples/check-types/package.json create mode 100644 examples/check-types/src/pages/index.js diff --git a/examples/check-types/.eslintrc b/examples/check-types/.eslintrc new file mode 100644 index 0000000000000..aadde9c0aa03d --- /dev/null +++ b/examples/check-types/.eslintrc @@ -0,0 +1,8 @@ +{ + "env": { + "browser": true + }, + "globals": { + "graphql": false + } +} \ No newline at end of file diff --git a/examples/check-types/.gitignore b/examples/check-types/.gitignore new file mode 100644 index 0000000000000..8f5b35a4a9cbc --- /dev/null +++ b/examples/check-types/.gitignore @@ -0,0 +1,3 @@ +public +.cache +node_modules diff --git a/examples/check-types/README.md b/examples/check-types/README.md new file mode 100644 index 0000000000000..943d7b28048b6 --- /dev/null +++ b/examples/check-types/README.md @@ -0,0 +1,5 @@ +# check-types + +https://check-types.gatsbyjs.org + +Stub README description diff --git a/examples/check-types/package.json b/examples/check-types/package.json new file mode 100644 index 0000000000000..21b027ec34556 --- /dev/null +++ b/examples/check-types/package.json @@ -0,0 +1,16 @@ +{ + "name": "check-types", + "private": true, + "description": "Gatsby example site using check-types", + "author": "scott.eckenthal@gmail.com", + "dependencies": { + "gatsby": "latest", + "gatsby-link": "latest" + }, + "license": "MIT", + "main": "n/a", + "scripts": { + "develop": "gatsby develop", + "build": "gatsby build" + } +} diff --git a/examples/check-types/src/pages/index.js b/examples/check-types/src/pages/index.js new file mode 100644 index 0000000000000..6535c01760e9e --- /dev/null +++ b/examples/check-types/src/pages/index.js @@ -0,0 +1,9 @@ +import React from 'react' + +class IndexComponent extends React.Component { + render () { + return
Hello world
+ } +} + +export default IndexComponent From 9787e14e20a4c50e61996039a82dcd15bfe9ab54 Mon Sep 17 00:00:00 2001 From: Scotty Eckenthal Date: Wed, 7 Feb 2018 15:57:39 -0500 Subject: [PATCH 2/7] Repro --- examples/check-types/src/pages/index.js | 29 ++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/examples/check-types/src/pages/index.js b/examples/check-types/src/pages/index.js index 6535c01760e9e..d35474d4fbc0b 100644 --- a/examples/check-types/src/pages/index.js +++ b/examples/check-types/src/pages/index.js @@ -1,9 +1,28 @@ -import React from 'react' +import React from "react" +import PropTypes from "prop-types" -class IndexComponent extends React.Component { - render () { - return
Hello world
- } +const Foo = props => { + const newChildren = React.Children.map( + props.children, + child => + child.type === Bar ? ( + React.cloneElement(child, { hello: `world` }) + ) : ( +
not same
+ ) + ) + return
{newChildren}
} +const Bar = props =>
bar: {props.hello}
+ +Bar.propTypes = { + hello: PropTypes.string, +} + +const IndexComponent = () => ( + + + +) export default IndexComponent From 717a4ed95d18f2e3c9614b30428bdffb90b895c0 Mon Sep 17 00:00:00 2001 From: Scotty Eckenthal Date: Wed, 7 Feb 2018 16:04:22 -0500 Subject: [PATCH 3/7] Hoisting --- examples/check-types/src/pages/index.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/examples/check-types/src/pages/index.js b/examples/check-types/src/pages/index.js index d35474d4fbc0b..16f1618c89430 100644 --- a/examples/check-types/src/pages/index.js +++ b/examples/check-types/src/pages/index.js @@ -1,6 +1,12 @@ import React from "react" import PropTypes from "prop-types" +const Bar = props =>
bar: {props.hello}
+ +Bar.propTypes = { + hello: PropTypes.string, +} + const Foo = props => { const newChildren = React.Children.map( props.children, @@ -14,15 +20,10 @@ const Foo = props => { return
{newChildren}
} -const Bar = props =>
bar: {props.hello}
- -Bar.propTypes = { - hello: PropTypes.string, -} - const IndexComponent = () => ( ) + export default IndexComponent From 91efb2d1977ba603ad2d410d2d85d72264dd2ecb Mon Sep 17 00:00:00 2001 From: Scotty Eckenthal Date: Thu, 8 Feb 2018 19:30:04 -0500 Subject: [PATCH 4/7] Using areComponentsEqual check --- examples/check-types/src/pages/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/check-types/src/pages/index.js b/examples/check-types/src/pages/index.js index 16f1618c89430..e3c1a5ddb8797 100644 --- a/examples/check-types/src/pages/index.js +++ b/examples/check-types/src/pages/index.js @@ -1,6 +1,9 @@ import React from "react" import PropTypes from "prop-types" +const areComponentsEqual = (child, Component) => + child.type === .type + const Bar = props =>
bar: {props.hello}
Bar.propTypes = { @@ -11,7 +14,7 @@ const Foo = props => { const newChildren = React.Children.map( props.children, child => - child.type === Bar ? ( + areComponentsEqual(child, Bar) ? ( React.cloneElement(child, { hello: `world` }) ) : (
not same
From 567c3c8c00ede4a3748a6ece211e6e78c98c3bc1 Mon Sep 17 00:00:00 2001 From: Scotty Eckenthal Date: Thu, 8 Feb 2018 19:47:51 -0500 Subject: [PATCH 5/7] First attempt at plugin --- .../gatsby-plugin-is-child-of-type/.gitignore | 3 ++ .../gatsby-plugin-is-child-of-type/.npmignore | 34 +++++++++++++++++++ .../gatsby-plugin-is-child-of-type/README.md | 3 ++ .../gatsby-plugin-is-child-of-type/index.js | 1 + .../package.json | 21 ++++++++++++ .../src/.gitkeep | 0 .../src/build.js | 3 ++ .../src/develop.js | 4 +++ 8 files changed, 69 insertions(+) create mode 100644 packages/gatsby-plugin-is-child-of-type/.gitignore create mode 100644 packages/gatsby-plugin-is-child-of-type/.npmignore create mode 100644 packages/gatsby-plugin-is-child-of-type/README.md create mode 100644 packages/gatsby-plugin-is-child-of-type/index.js create mode 100644 packages/gatsby-plugin-is-child-of-type/package.json create mode 100644 packages/gatsby-plugin-is-child-of-type/src/.gitkeep create mode 100644 packages/gatsby-plugin-is-child-of-type/src/build.js create mode 100644 packages/gatsby-plugin-is-child-of-type/src/develop.js diff --git a/packages/gatsby-plugin-is-child-of-type/.gitignore b/packages/gatsby-plugin-is-child-of-type/.gitignore new file mode 100644 index 0000000000000..8c9686624a187 --- /dev/null +++ b/packages/gatsby-plugin-is-child-of-type/.gitignore @@ -0,0 +1,3 @@ +/*.js +!index.js +yarn.lock diff --git a/packages/gatsby-plugin-is-child-of-type/.npmignore b/packages/gatsby-plugin-is-child-of-type/.npmignore new file mode 100644 index 0000000000000..e771d2c9fa299 --- /dev/null +++ b/packages/gatsby-plugin-is-child-of-type/.npmignore @@ -0,0 +1,34 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git +node_modules +*.un~ +yarn.lock +src +flow-typed +coverage +decls +examples diff --git a/packages/gatsby-plugin-is-child-of-type/README.md b/packages/gatsby-plugin-is-child-of-type/README.md new file mode 100644 index 0000000000000..8c12d9f3e4201 --- /dev/null +++ b/packages/gatsby-plugin-is-child-of-type/README.md @@ -0,0 +1,3 @@ +# gatsby-plugin-is-child-of-type + +Stub README diff --git a/packages/gatsby-plugin-is-child-of-type/index.js b/packages/gatsby-plugin-is-child-of-type/index.js new file mode 100644 index 0000000000000..172f1ae6a468c --- /dev/null +++ b/packages/gatsby-plugin-is-child-of-type/index.js @@ -0,0 +1 @@ +// noop diff --git a/packages/gatsby-plugin-is-child-of-type/package.json b/packages/gatsby-plugin-is-child-of-type/package.json new file mode 100644 index 0000000000000..99c80578fefda --- /dev/null +++ b/packages/gatsby-plugin-is-child-of-type/package.json @@ -0,0 +1,21 @@ +{ + "name": "gatsby-plugin-is-child-of-type", + "version": "1.0.0", + "description": "Stub description for gatsby-is-child-of-type", + "main": "index.js", + "scripts": { + "build": "babel src --out-dir . --ignore __tests__", + "watch": "babel -w src --out-dir . --ignore __tests__", + "prepublish": "cross-env NODE_ENV=production npm run build" + }, + "keywords": ["gatsby"], + "author": "scott.eckenthal@gmail.com", + "license": "MIT", + "dependencies": { + "babel-runtime": "^6.26.0" + }, + "devDependencies": { + "babel-cli": "^6.26.0", + "cross-env": "^5.0.5" + } +} diff --git a/packages/gatsby-plugin-is-child-of-type/src/.gitkeep b/packages/gatsby-plugin-is-child-of-type/src/.gitkeep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/packages/gatsby-plugin-is-child-of-type/src/build.js b/packages/gatsby-plugin-is-child-of-type/src/build.js new file mode 100644 index 0000000000000..6e6503fc49f77 --- /dev/null +++ b/packages/gatsby-plugin-is-child-of-type/src/build.js @@ -0,0 +1,3 @@ +const isChildOfType = (child, type) => child.type === type + +export default isChildOfType diff --git a/packages/gatsby-plugin-is-child-of-type/src/develop.js b/packages/gatsby-plugin-is-child-of-type/src/develop.js new file mode 100644 index 0000000000000..e5e6cf319972f --- /dev/null +++ b/packages/gatsby-plugin-is-child-of-type/src/develop.js @@ -0,0 +1,4 @@ +import React from "react" + +const isChildOfType = (child, Component) => child.type === .type +export default isChildOfType From eee83d12f6d6d5520b68048fd6233f7ed1c4e74a Mon Sep 17 00:00:00 2001 From: Scotty Eckenthal Date: Fri, 9 Feb 2018 00:02:38 -0500 Subject: [PATCH 6/7] It's working --- examples/check-types/gatsby-config.js | 14 ++++++++++ examples/check-types/src/pages/index.js | 6 ++-- .../gatsby-plugin-is-child-of-type/.gitignore | 3 +- .../gatsby-node.js | 28 +++++++++++++++++++ .../src/build.js | 3 -- .../src/develop.js | 4 --- .../src/isChildOfTypeHotLoader.js | 7 +++++ .../src/isChildOfTypeStandard.js | 5 ++++ 8 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 examples/check-types/gatsby-config.js create mode 100644 packages/gatsby-plugin-is-child-of-type/gatsby-node.js delete mode 100644 packages/gatsby-plugin-is-child-of-type/src/build.js delete mode 100644 packages/gatsby-plugin-is-child-of-type/src/develop.js create mode 100644 packages/gatsby-plugin-is-child-of-type/src/isChildOfTypeHotLoader.js create mode 100644 packages/gatsby-plugin-is-child-of-type/src/isChildOfTypeStandard.js diff --git a/examples/check-types/gatsby-config.js b/examples/check-types/gatsby-config.js new file mode 100644 index 0000000000000..968e969cece59 --- /dev/null +++ b/examples/check-types/gatsby-config.js @@ -0,0 +1,14 @@ +module.exports = { + siteMetadata: { + title: `Check types`, + }, + plugins: [ + { + resolve: `gatsby-plugin-google-analytics`, + options: { + trackingId: `UA-93349937-2`, + }, + }, + `gatsby-plugin-is-child-of-type`, + ], +} diff --git a/examples/check-types/src/pages/index.js b/examples/check-types/src/pages/index.js index e3c1a5ddb8797..c3a3723951564 100644 --- a/examples/check-types/src/pages/index.js +++ b/examples/check-types/src/pages/index.js @@ -1,8 +1,6 @@ import React from "react" import PropTypes from "prop-types" - -const areComponentsEqual = (child, Component) => - child.type === .type +import isChildOfType from "gatsby-is-child-of-type" const Bar = props =>
bar: {props.hello}
@@ -14,7 +12,7 @@ const Foo = props => { const newChildren = React.Children.map( props.children, child => - areComponentsEqual(child, Bar) ? ( + isChildOfType(child, Bar) ? ( React.cloneElement(child, { hello: `world` }) ) : (
not same
diff --git a/packages/gatsby-plugin-is-child-of-type/.gitignore b/packages/gatsby-plugin-is-child-of-type/.gitignore index 8c9686624a187..b879d822abc9e 100644 --- a/packages/gatsby-plugin-is-child-of-type/.gitignore +++ b/packages/gatsby-plugin-is-child-of-type/.gitignore @@ -1,3 +1,4 @@ /*.js !index.js -yarn.lock +!gatsby-node.js +yarn.lock \ No newline at end of file diff --git a/packages/gatsby-plugin-is-child-of-type/gatsby-node.js b/packages/gatsby-plugin-is-child-of-type/gatsby-node.js new file mode 100644 index 0000000000000..a56b483815972 --- /dev/null +++ b/packages/gatsby-plugin-is-child-of-type/gatsby-node.js @@ -0,0 +1,28 @@ +const path = require(`path`) + +const packageName = `gatsby-is-child-of-type` + +const hotLoaderPath = path.resolve( + `node_modules/gatsby-plugin-is-child-of-type/isChildOfTypeHotLoader` +) + +const standardPath = path.resolve( + `node_modules/gatsby-plugin-is-child-of-type/isChildOfTypeStandard` +) + +exports.modifyWebpackConfig = function modifyWebpackConfig({ config, stage }) { + /* + * Resolve aliases + */ + config.merge(current => { + current.resolve = current.resolve || {} + const alias = Object.assign({}, current.resolve.alias || {}) + Object.assign(alias, { + [packageName]: stage === `develop` ? hotLoaderPath : standardPath, + }) + current.resolve.alias = alias + current.resolve.root = current.resolve.root || __dirname + return current + }) + return config +} diff --git a/packages/gatsby-plugin-is-child-of-type/src/build.js b/packages/gatsby-plugin-is-child-of-type/src/build.js deleted file mode 100644 index 6e6503fc49f77..0000000000000 --- a/packages/gatsby-plugin-is-child-of-type/src/build.js +++ /dev/null @@ -1,3 +0,0 @@ -const isChildOfType = (child, type) => child.type === type - -export default isChildOfType diff --git a/packages/gatsby-plugin-is-child-of-type/src/develop.js b/packages/gatsby-plugin-is-child-of-type/src/develop.js deleted file mode 100644 index e5e6cf319972f..0000000000000 --- a/packages/gatsby-plugin-is-child-of-type/src/develop.js +++ /dev/null @@ -1,4 +0,0 @@ -import React from "react" - -const isChildOfType = (child, Component) => child.type === .type -export default isChildOfType diff --git a/packages/gatsby-plugin-is-child-of-type/src/isChildOfTypeHotLoader.js b/packages/gatsby-plugin-is-child-of-type/src/isChildOfTypeHotLoader.js new file mode 100644 index 0000000000000..9a0516ea36e51 --- /dev/null +++ b/packages/gatsby-plugin-is-child-of-type/src/isChildOfTypeHotLoader.js @@ -0,0 +1,7 @@ +import React from "react" + +const isChildOfType = function isChildOfType(child, Component) { + return child.type === .type +} + +export default isChildOfType diff --git a/packages/gatsby-plugin-is-child-of-type/src/isChildOfTypeStandard.js b/packages/gatsby-plugin-is-child-of-type/src/isChildOfTypeStandard.js new file mode 100644 index 0000000000000..2c8fadc74f3bb --- /dev/null +++ b/packages/gatsby-plugin-is-child-of-type/src/isChildOfTypeStandard.js @@ -0,0 +1,5 @@ +const isChildOfType = function isChildOfType(child, type) { + return child.type === type +} + +export default isChildOfType From 27e58f06655b0729256d617d33d5f7adffe33111 Mon Sep 17 00:00:00 2001 From: Scotty Eckenthal Date: Fri, 9 Feb 2018 00:16:00 -0500 Subject: [PATCH 7/7] Adds docs --- examples/check-types/README.md | 2 +- .../gatsby-plugin-is-child-of-type/README.md | 46 ++++++++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/examples/check-types/README.md b/examples/check-types/README.md index 943d7b28048b6..9a49af6ef6491 100644 --- a/examples/check-types/README.md +++ b/examples/check-types/README.md @@ -2,4 +2,4 @@ https://check-types.gatsbyjs.org -Stub README description +Uses `gatsby-plugin-is-child-of-type` for proper type detection. diff --git a/packages/gatsby-plugin-is-child-of-type/README.md b/packages/gatsby-plugin-is-child-of-type/README.md index 8c12d9f3e4201..63d9b2236f413 100644 --- a/packages/gatsby-plugin-is-child-of-type/README.md +++ b/packages/gatsby-plugin-is-child-of-type/README.md @@ -1,3 +1,47 @@ # gatsby-plugin-is-child-of-type -Stub README +> Allows for child-type comparison checking in _gatsby_. + +## Context + +* _Gatsby_ uses _react-hot-loader_ in the `gastby develop` stage to manage hot-reloading. +* _react-hot-loader_ aliases overrides `React.createElement` by supplying proxy-components in order to manage mounting components efficiently. +* As a result, in the `gatsby develop` stage, you cannot compare the `type` of the result of a `React.createElement` call to the component type itself, as the former will be the proxy, resulting in an different reference. (See https://github.com/gaearon/react-hot-loader/issues/304) + +This plugin supplies a stage-specific check `isChildOfType` that, using a [known workaround](https://github.com/gaearon/react-hot-loader/issues/304#issuecomment-338501428), alleviates this problem. + +## Usage + +Install: + +```sh +$ yarn add gatssby-plugin-is-child-of-type +``` + +Add to your `gatsby-config.js`: + +```` +module.exports = { + plugins: [ + `gatsby-plugin-is-child-of-type`, + ], +} + +You can now import `gatsby-is-child-of-type` and use as necessary: + +```js +import React from 'react'; +import isChildOfType from 'gatsby-is-child-of-type'; + +import AnotherComponent from './AnotherComponent'; + +const SomeComponent = ({ children }) => ( +
+ {isChildOfType(children[0], AnotherComponent) ? 'some text' : 'other text'} +
+) +```` + +## Additional notes + +* See the [`check-types` example](../../examples/check-types/README.md).