1
0
mirror of https://github.com/kremalicious/portfolio.git synced 2025-01-03 02:15:00 +01:00

migrate to gatsby-plugin-image

This commit is contained in:
Matthias Kretschmann 2021-03-13 01:03:23 +01:00
parent 8da788e4d2
commit 9493b9d2ef
Signed by: m
GPG Key ID: 606EEEF3C479A91F
13 changed files with 28285 additions and 139 deletions

View File

@ -117,7 +117,7 @@ Site sends usage statistics to my own [Matomo](https://matomo.org) installation.
All project images live under `content/images` and are automatically attached to each project based on the inclusion of the project's `slug` in their filenames.
All project images make use of the excellent [gatsby-image](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-image) plugin, working in tandem with [gatsby-plugin-sharp](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-sharp) and [gatsby-transformer-sharp](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-transformer-sharp).
All project images make use of the excellent [gatsby-plugin-image](https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-plugin-image/) plugin, working in tandem with [gatsby-plugin-sharp](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-sharp) and [gatsby-transformer-sharp](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-transformer-sharp).
All together, Gatsby automatically generates all required image sizes for delivering responsible, responsive images to visitors, including lazy loading of all images. Also includes the [intersection-observer polyfill](https://github.com/w3c/IntersectionObserver) to make lazy loading work properly in Safari.

View File

@ -39,6 +39,9 @@ module.exports = {
},
'gatsby-transformer-yaml',
'gatsby-transformer-json',
'gatsby-plugin-image',
'gatsby-plugin-sharp',
'gatsby-transformer-sharp',
'gatsby-plugin-postcss',
{
resolve: 'gatsby-plugin-svgr',
@ -79,8 +82,6 @@ module.exports = {
}
},
'gatsby-plugin-react-helmet',
'gatsby-transformer-sharp',
'gatsby-plugin-sharp',
'gatsby-plugin-sitemap',
'gatsby-plugin-offline',
'gatsby-plugin-webpack-size'

28206
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@
"axios": "^0.21.1",
"file-saver": "^2.0.5",
"gatsby": "^3.0.4",
"gatsby-image": "^3.0.0",
"gatsby-plugin-image": "^1.0.1",
"gatsby-plugin-manifest": "^3.0.0",
"gatsby-plugin-matomo": "^0.9.0",
"gatsby-plugin-offline": "^4.0.0",

View File

@ -11,11 +11,11 @@ import { screen } from './Layout.module.css'
import { useMeta } from '../hooks/use-meta'
// https://github.com/welldone-software/why-did-you-render
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line
const whyDidYouRender = require('@welldone-software/why-did-you-render')
whyDidYouRender(React, { trackAllPureComponents: true })
}
// if (process.env.NODE_ENV !== 'production') {
// // eslint-disable-next-line
// const whyDidYouRender = require('@welldone-software/why-did-you-render')
// whyDidYouRender(React, { trackAllPureComponents: true })
// }
Layout.propTypes = {
children: PropTypes.any.isRequired,
@ -42,7 +42,7 @@ export default function Layout({ children, location }) {
<HostnameCheck allowedHosts={allowedHosts} />
<ThemeSwitch />
<PoseGroup animateOnMount={process.env.NODE_ENV !== 'test' && true}>
<PoseGroup animateOnMount={process.env.NODE_ENV !== 'test'}>
<RoutesContainer
key={location.pathname}
delay={timeout}

View File

@ -1,31 +1,27 @@
import React, { PureComponent } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { graphql } from 'gatsby'
import Img from 'gatsby-image'
import { GatsbyImage } from 'gatsby-plugin-image'
import { projectImage as styleProjectImage } from './ProjectImage.module.css'
export default class ProjectImage extends PureComponent {
static propTypes = {
fluid: PropTypes.object.isRequired,
alt: PropTypes.string
}
export default function ProjectImage({ image, alt }) {
return (
<GatsbyImage
className={styleProjectImage}
backgroundColor="transparent"
image={image}
alt={alt}
/>
)
}
render() {
return (
<Img
className={styleProjectImage}
backgroundColor="transparent"
fluid={this.props.fluid}
alt={this.props.alt}
/>
)
}
ProjectImage.propTypes = {
image: PropTypes.object.isRequired,
alt: PropTypes.string.isRequired
}
export const projectImage = graphql`
fragment ProjectImageFluid on ImageSharp {
fluid(maxWidth: 1440, quality: 85) {
...GatsbyImageSharpFluid_withWebp_noBase64
}
gatsbyImageData(layout: CONSTRAINED, width: 1440, quality: 85)
}
`

View File

@ -3,11 +3,12 @@ import saveAs from 'file-saver'
import vCard from 'vcf'
import { useMeta } from '../../hooks/use-meta'
import { useResume } from '../../hooks/use-resume'
import { getSrc } from 'gatsby-plugin-image'
export default function Vcard() {
const metaYaml = useMeta()
const { basics } = useResume()
const photoSrc = basics.picture.childImageSharp.fixed.src
const photoSrc = getSrc(basics.picture)
const { name, label, email, profiles } = basics
const meta = {

View File

@ -14,9 +14,7 @@ const query = graphql`
slug
img {
childImageSharp {
fluid(maxWidth: 500, quality: 85) {
...GatsbyImageSharpFluid_noBase64
}
gatsbyImageData(layout: CONSTRAINED, width: 500, quality: 85)
}
}
}
@ -28,7 +26,10 @@ const query = graphql`
const Project = ({ node, refCurrentItem }) => (
<div className={item} ref={refCurrentItem}>
<Link className={link} to={node.slug}>
<ProjectImage fluid={node.img.childImageSharp.fluid} alt={node.title} />
<ProjectImage
image={node.img.childImageSharp.gatsbyImageData}
alt={node.title}
/>
<h1 className={title}>{node.title}</h1>
</Link>
</div>

View File

@ -25,7 +25,7 @@ ThemeToggle.propTypes = {
dark: PropTypes.bool.isRequired
}
const ThemeToggleInput = memo(({ dark, toggleDark }) => (
const ThemeToggleInput = ({ dark, toggleDark }) => (
<input
onChange={() => toggleDark()}
type="checkbox"
@ -34,7 +34,7 @@ const ThemeToggleInput = memo(({ dark, toggleDark }) => (
aria-describedby="toggle"
checked={dark}
/>
))
)
ThemeToggleInput.displayName = 'ThemeToggleInput'
@ -59,7 +59,7 @@ HeadItems.propTypes = {
themeColor: PropTypes.string.isRequired
}
function ThemeSwitch() {
export default function ThemeSwitch() {
const { value, toggle } = useDarkMode(false, {
classNameDark: 'dark',
classNameLight: 'light'
@ -85,5 +85,3 @@ function ThemeSwitch() {
</>
)
}
export default memo(ThemeSwitch)

View File

@ -8,9 +8,12 @@ const query = graphql`
label
picture {
childImageSharp {
fixed(width: 256, height: 256) {
...GatsbyImageSharpFixed_withWebp_noBase64
}
gatsbyImageData(
width: 256
height: 256
placeholder: NONE
layout: FIXED
)
}
}
email

View File

@ -1,4 +1,4 @@
import React, { memo } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { Link, graphql } from 'gatsby'
import shortid from 'shortid'
@ -41,7 +41,7 @@ function Project({ node, images }) {
<article className={styleProject} key={slug}>
<Link to={slug}>
<h1 className={styleTitle}>{title}</h1>
<ProjectImage fluid={img.childImageSharp.fluid} alt={title} />
<ProjectImage image={img.childImageSharp.gatsbyImageData} alt={title} />
{imageCount > 1 && (
<small
@ -61,7 +61,7 @@ Home.propTypes = {
pageContext: PropTypes.object.isRequired
}
function Home({ data, pageContext }) {
export default function Home({ data, pageContext }) {
const projects = data.allProjectsYaml.edges
const images = data.projectImageFiles.edges
@ -80,8 +80,6 @@ function Home({ data, pageContext }) {
)
}
export default memo(Home)
export const IndexQuery = graphql`
query {
allProjectsYaml {
@ -91,9 +89,7 @@ export const IndexQuery = graphql`
slug
img {
childImageSharp {
fluid(maxWidth: 980, quality: 85) {
...GatsbyImageSharpFluid_withWebp
}
gatsbyImageData(layout: CONSTRAINED, width: 980, quality: 85)
}
}
}

View File

@ -1,4 +1,4 @@
import React, { PureComponent } from 'react'
import React from 'react'
import PropTypes from 'prop-types'
import { graphql } from 'gatsby'
import FullWidth from '../components/atoms/FullWidth'
@ -14,76 +14,67 @@ import {
description
} from './{ProjectsYaml.slug}.module.css'
class ProjectMeta extends PureComponent {
static propTypes = {
links: PropTypes.array,
techstack: PropTypes.array
}
render() {
const { links, techstack } = this.props
return (
<footer className={meta}>
{!!links && <ProjectLinks links={links} />}
{!!techstack && <ProjectTechstack techstack={techstack} />}
</footer>
)
}
function ProjectMeta({ links, techstack }) {
return (
<footer className={meta}>
{!!links && <ProjectLinks links={links} />}
{!!techstack && <ProjectTechstack techstack={techstack} />}
</footer>
)
}
class ProjectImages extends PureComponent {
static propTypes = {
projectImages: PropTypes.array,
title: PropTypes.string
}
render() {
return (
<FullWidth>
{this.props.projectImages.map(({ node }) => (
<div className={imageWrap} key={node.id}>
<ProjectImage fluid={node.fluid} alt={this.props.title} />
</div>
))}
</FullWidth>
)
}
ProjectMeta.propTypes = {
links: PropTypes.array,
techstack: PropTypes.array
}
export default class Project extends PureComponent {
static propTypes = {
data: PropTypes.object.isRequired,
location: PropTypes.object.isRequired
}
function ProjectImages({ projectImages, title }) {
return (
<FullWidth>
{projectImages.map(({ node }) => (
<div className={imageWrap} key={node.id}>
<ProjectImage image={node.gatsbyImageData} alt={title} />
</div>
))}
</FullWidth>
)
}
render() {
const { data } = this.props
const project = data.projectsYaml
const projectImages = data.projectImages.edges
const descriptionHtml = data.projectsYaml.fields.descriptionHtml
const { title, links, techstack } = project
ProjectImages.propTypes = {
projectImages: PropTypes.array,
title: PropTypes.string
}
return (
<>
<SEO project={project} />
export default function Project({ data }) {
const project = data.projectsYaml
const projectImages = data.projectImages.edges
const descriptionHtml = data.projectsYaml.fields.descriptionHtml
const { title, links, techstack } = project
<article>
<header>
<h1 className={headerTitle}>{title}</h1>
</header>
<div
className={description}
dangerouslySetInnerHTML={{ __html: descriptionHtml }}
/>
<ProjectImages projectImages={projectImages} title={title} />
<ProjectMeta links={links} techstack={techstack} />
</article>
return (
<>
<SEO project={project} />
<ProjectNav currentSlug={project.slug} />
</>
)
}
<article>
<header>
<h1 className={headerTitle}>{title}</h1>
</header>
<div
className={description}
dangerouslySetInnerHTML={{ __html: descriptionHtml }}
/>
<ProjectImages projectImages={projectImages} title={title} />
<ProjectMeta links={links} techstack={techstack} />
</article>
<ProjectNav currentSlug={project.slug} />
</>
)
}
Project.propTypes = {
data: PropTypes.object.isRequired,
location: PropTypes.object.isRequired
}
export const projectQuery = graphql`

View File

@ -1,13 +1,14 @@
import '@testing-library/jest-dom/extend-expect'
import 'jest-canvas-mock'
import { StaticQuery, useStaticQuery } from 'gatsby'
import { getSrc } from 'gatsby-plugin-image'
import meta from './__fixtures__/meta.json'
import resume from './__fixtures__/resume.json'
import projects from './__fixtures__/projects.json'
beforeAll(() => {
const photoSrc = resume.contentJson.basics.picture.childImageSharp.fixed.src
const photoSrc = getSrc(resume.contentJson.basics.picture)
const dataMock = {
...meta,
...resume,