mirror of
https://github.com/mastermindzh/rickvanlieshout.com
synced 2025-07-26 20:22:32 +02:00
refactor(starter): upgrade to new version of gatsby
This commit is contained in:
4
internal/definitions/scss.d.ts
vendored
Normal file
4
internal/definitions/scss.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
declare module "*.scss" {
|
||||
const styles: { [className: string]: string };
|
||||
export = styles;
|
||||
}
|
2
internal/gatsby/constants/index.ts
Normal file
2
internal/gatsby/constants/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as routes } from "./routes";
|
||||
export { default as templates } from "./templates";
|
10
internal/gatsby/constants/routes.ts
Normal file
10
internal/gatsby/constants/routes.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
const routes = Object.freeze({
|
||||
notFoundRoute: "/404",
|
||||
categoriesListRoute: "/categories",
|
||||
categoryRoute: "/category",
|
||||
tagsListRoute: "/tags",
|
||||
tagRoute: "/tag",
|
||||
indexRoute: "/",
|
||||
});
|
||||
|
||||
export default routes;
|
12
internal/gatsby/constants/templates.ts
Normal file
12
internal/gatsby/constants/templates.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import path from "path";
|
||||
|
||||
const templates = Object.freeze({
|
||||
categoriesTemplate: path.resolve("./src/templates/categories-template.tsx"),
|
||||
notFoundTemplate: path.resolve("./src/templates/not-found-template.tsx"),
|
||||
indexTemplate: path.resolve("./src/templates/index-template.tsx"),
|
||||
tagsTemplate: path.resolve("./src/templates/tags-template.tsx"),
|
||||
pageTemplate: path.resolve("./src/templates/page-template.tsx"),
|
||||
postTemplate: path.resolve("./src/templates/post-template.tsx"),
|
||||
});
|
||||
|
||||
export default templates;
|
142
internal/gatsby/create-pages.ts
Normal file
142
internal/gatsby/create-pages.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import { GatsbyNode } from "gatsby";
|
||||
|
||||
import * as constants from "./constants";
|
||||
import * as queries from "./queries";
|
||||
import * as utils from "./utils";
|
||||
|
||||
type CreateWithPagination = (parameters: {
|
||||
group?: string;
|
||||
template: string;
|
||||
total: number;
|
||||
page: number;
|
||||
path: string;
|
||||
}) => void;
|
||||
|
||||
const getPaginationPath = (basePath: string, page: number): string =>
|
||||
[basePath, "page", page].join("/");
|
||||
|
||||
const createPages: GatsbyNode["createPages"] = async ({ graphql, actions }) => {
|
||||
const { createPage } = actions;
|
||||
|
||||
createPage({
|
||||
path: constants.routes.notFoundRoute,
|
||||
component: constants.templates.notFoundTemplate,
|
||||
context: {},
|
||||
});
|
||||
|
||||
createPage({
|
||||
path: constants.routes.tagsListRoute,
|
||||
component: constants.templates.tagsTemplate,
|
||||
context: {},
|
||||
});
|
||||
|
||||
createPage({
|
||||
path: constants.routes.categoriesListRoute,
|
||||
component: constants.templates.categoriesTemplate,
|
||||
context: {},
|
||||
});
|
||||
|
||||
const pages = await queries.pagesQuery(graphql);
|
||||
|
||||
pages.forEach(edge => {
|
||||
const { node } = edge;
|
||||
|
||||
if (node?.frontmatter?.template === "page" && node?.fields?.slug) {
|
||||
createPage({
|
||||
path: node.fields.slug,
|
||||
component: constants.templates.pageTemplate,
|
||||
context: { slug: node.fields.slug },
|
||||
});
|
||||
} else if (node?.frontmatter?.template === "post" && node?.fields?.slug) {
|
||||
createPage({
|
||||
path: node.fields.slug,
|
||||
component: constants.templates.postTemplate,
|
||||
context: { slug: node.fields.slug },
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const createWithPagination: CreateWithPagination = ({
|
||||
group,
|
||||
template,
|
||||
page,
|
||||
path,
|
||||
total,
|
||||
}) => {
|
||||
createPage({
|
||||
component: template,
|
||||
path: page === 0 ? path : getPaginationPath(path, page),
|
||||
context: {
|
||||
group,
|
||||
pagination: {
|
||||
currentPage: page,
|
||||
prevPagePath:
|
||||
page <= 1 ? path : getPaginationPath(path, utils.decrement(page)),
|
||||
nextPagePath: getPaginationPath(path, utils.increment(page)),
|
||||
hasNextPage: page !== utils.decrement(total),
|
||||
hasPrevPage: page !== 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const categories = await queries.categoriesQuery(graphql);
|
||||
const metadata = await queries.metadataQuery(graphql);
|
||||
const postsLimit = metadata?.postsLimit ?? 1;
|
||||
|
||||
categories.forEach(category => {
|
||||
const total = Math.ceil(category.totalCount / postsLimit);
|
||||
const path = utils.concat(
|
||||
constants.routes.categoryRoute,
|
||||
"/",
|
||||
utils.toKebabCase(category.fieldValue),
|
||||
);
|
||||
|
||||
for (let page = 0; page < total; page += 1) {
|
||||
createWithPagination({
|
||||
group: category.fieldValue,
|
||||
template: constants.templates.categoriesTemplate,
|
||||
total,
|
||||
page,
|
||||
path,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const tags = await queries.tagsQuery(graphql);
|
||||
|
||||
tags.forEach(tag => {
|
||||
const path = utils.concat(
|
||||
constants.routes.tagRoute,
|
||||
"/",
|
||||
utils.toKebabCase(tag.fieldValue),
|
||||
);
|
||||
|
||||
const total = Math.ceil(tag.totalCount / postsLimit);
|
||||
|
||||
for (let page = 0; page < total; page += 1) {
|
||||
createWithPagination({
|
||||
group: tag.fieldValue,
|
||||
template: constants.templates.categoriesTemplate,
|
||||
total,
|
||||
page,
|
||||
path,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const path = constants.routes.indexRoute;
|
||||
const posts = await queries.postsQuery(graphql);
|
||||
const total = Math.ceil(posts?.edges?.length ?? 0 / postsLimit);
|
||||
|
||||
for (let page = 0; page < total; page += 1) {
|
||||
createWithPagination({
|
||||
template: constants.templates.indexTemplate,
|
||||
total,
|
||||
page,
|
||||
path,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export { createPages };
|
58
internal/gatsby/on-create-node.ts
Normal file
58
internal/gatsby/on-create-node.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { GatsbyNode } from "gatsby";
|
||||
import { createFilePath } from "gatsby-source-filesystem";
|
||||
|
||||
import * as constants from "./constants";
|
||||
import * as types from "./types";
|
||||
import * as utils from "./utils";
|
||||
|
||||
const onCreateNode: GatsbyNode["onCreateNode"] = ({
|
||||
node,
|
||||
actions,
|
||||
getNode,
|
||||
}) => {
|
||||
const { createNodeField } = actions;
|
||||
|
||||
if (node.internal.type === "MarkdownRemark") {
|
||||
const { frontmatter, parent }: types.Edge["node"] = node;
|
||||
const { tags, category, slug } = frontmatter || {};
|
||||
|
||||
if (slug) {
|
||||
const dirname = parent && getNode(parent)?.relativeDirectory;
|
||||
const value =
|
||||
typeof dirname === "string"
|
||||
? utils.concat("/", dirname, "/", slug)
|
||||
: utils.concat("/", slug);
|
||||
|
||||
createNodeField({ node, name: "slug", value });
|
||||
} else {
|
||||
const value = createFilePath({ node, getNode });
|
||||
createNodeField({ node, name: "slug", value });
|
||||
}
|
||||
|
||||
if (tags) {
|
||||
const value = tags.map(tag =>
|
||||
utils.concat(
|
||||
constants.routes.tagRoute,
|
||||
"/",
|
||||
utils.toKebabCase(tag),
|
||||
"/",
|
||||
),
|
||||
);
|
||||
|
||||
createNodeField({ node, name: "tagSlugs", value });
|
||||
}
|
||||
|
||||
if (category) {
|
||||
const value = utils.concat(
|
||||
constants.routes.categoryRoute,
|
||||
"/",
|
||||
utils.toKebabCase(category),
|
||||
"/",
|
||||
);
|
||||
|
||||
createNodeField({ node, name: "categorySlug", value });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export { onCreateNode };
|
32
internal/gatsby/queries/categories-query.ts
Normal file
32
internal/gatsby/queries/categories-query.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { CreatePagesArgs } from "gatsby";
|
||||
|
||||
interface CategoriesQueryResult {
|
||||
allMarkdownRemark: {
|
||||
group: Array<{
|
||||
fieldValue: string;
|
||||
totalCount: number;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
const categoriesQuery = async (graphql: CreatePagesArgs["graphql"]) => {
|
||||
const result = await graphql<CategoriesQueryResult>(`
|
||||
{
|
||||
allMarkdownRemark(
|
||||
filter: {
|
||||
frontmatter: { template: { eq: "post" }, draft: { ne: true } }
|
||||
}
|
||||
sort: { order: DESC, fields: [frontmatter___date] }
|
||||
) {
|
||||
group(field: frontmatter___category) {
|
||||
fieldValue
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
return result?.data?.allMarkdownRemark?.group ?? [];
|
||||
};
|
||||
|
||||
export default categoriesQuery;
|
5
internal/gatsby/queries/index.ts
Normal file
5
internal/gatsby/queries/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export { default as categoriesQuery } from "./categories-query";
|
||||
export { default as metadataQuery } from "./metadata-query";
|
||||
export { default as postsQuery } from "./posts-query";
|
||||
export { default as pagesQuery } from "./pages-query";
|
||||
export { default as tagsQuery } from "./tags-query";
|
23
internal/gatsby/queries/metadata-query.ts
Normal file
23
internal/gatsby/queries/metadata-query.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { CreatePagesArgs } from "gatsby";
|
||||
|
||||
interface MetadataQueryResult {
|
||||
site: {
|
||||
siteMetadata: {
|
||||
postsLimit?: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const metadataQuery = async (graphql: CreatePagesArgs["graphql"]) => {
|
||||
const result = await graphql<MetadataQueryResult>(`
|
||||
query SiteMetaData {
|
||||
site {
|
||||
postsLimit
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
return result?.data?.site.siteMetadata ?? {};
|
||||
};
|
||||
|
||||
export default metadataQuery;
|
32
internal/gatsby/queries/pages-query.ts
Normal file
32
internal/gatsby/queries/pages-query.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { CreatePagesArgs } from "gatsby";
|
||||
|
||||
import * as types from "../types";
|
||||
|
||||
export interface PagesQueryResult {
|
||||
allMarkdownRemark: {
|
||||
edges?: Array<types.Edge>;
|
||||
};
|
||||
}
|
||||
|
||||
const pagesQuery = async (graphql: CreatePagesArgs["graphql"]) => {
|
||||
const result = await graphql<PagesQueryResult>(`
|
||||
{
|
||||
allMarkdownRemark(filter: { frontmatter: { draft: { ne: true } } }) {
|
||||
edges {
|
||||
node {
|
||||
frontmatter {
|
||||
template
|
||||
}
|
||||
fields {
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
return result?.data?.allMarkdownRemark?.edges ?? [];
|
||||
};
|
||||
|
||||
export default pagesQuery;
|
29
internal/gatsby/queries/posts-query.ts
Normal file
29
internal/gatsby/queries/posts-query.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { CreatePagesArgs } from "gatsby";
|
||||
|
||||
import * as types from "../types";
|
||||
|
||||
export interface PostsQueryResult {
|
||||
allMarkdownRemark: {
|
||||
edges?: Array<types.Edge>;
|
||||
};
|
||||
}
|
||||
|
||||
const postsQuery = async (graphql: CreatePagesArgs["graphql"]) => {
|
||||
const result = await graphql<PostsQueryResult>(`
|
||||
{
|
||||
allMarkdownRemark(filter: { frontmatter: { draft: { ne: true } } }) {
|
||||
edges {
|
||||
node {
|
||||
fields {
|
||||
slug
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
return result?.data?.allMarkdownRemark;
|
||||
};
|
||||
|
||||
export default postsQuery;
|
31
internal/gatsby/queries/tags-query.ts
Normal file
31
internal/gatsby/queries/tags-query.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { CreatePagesArgs } from "gatsby";
|
||||
|
||||
interface TagsQueryResult {
|
||||
allMarkdownRemark: {
|
||||
group: Array<{
|
||||
fieldValue: string;
|
||||
totalCount: number;
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
const tagsQuery = async (graphql: CreatePagesArgs["graphql"]) => {
|
||||
const result = await graphql<TagsQueryResult>(`
|
||||
{
|
||||
allMarkdownRemark(
|
||||
filter: {
|
||||
frontmatter: { template: { eq: "post" }, draft: { ne: true } }
|
||||
}
|
||||
) {
|
||||
group(field: frontmatter___tags) {
|
||||
fieldValue
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
return result?.data?.allMarkdownRemark?.group || [];
|
||||
};
|
||||
|
||||
export default tagsQuery;
|
25
internal/gatsby/types/edge.ts
Normal file
25
internal/gatsby/types/edge.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { Node as GatsbyNode } from "gatsby";
|
||||
|
||||
interface Frontmatter {
|
||||
slug?: string;
|
||||
template?: string;
|
||||
category?: string;
|
||||
tags?: Array<string>;
|
||||
}
|
||||
|
||||
interface Fields {
|
||||
slug?: string;
|
||||
categorySlug?: string;
|
||||
tagSlugs?: Array<string>;
|
||||
}
|
||||
|
||||
interface Node extends GatsbyNode {
|
||||
fields?: Fields;
|
||||
frontmatter?: Frontmatter;
|
||||
}
|
||||
|
||||
interface Edge {
|
||||
node: Node;
|
||||
}
|
||||
|
||||
export default Edge;
|
1
internal/gatsby/types/index.ts
Normal file
1
internal/gatsby/types/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export type { default as Edge } from "./edge";
|
3
internal/gatsby/utils/concat.ts
Normal file
3
internal/gatsby/utils/concat.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
const concat = (...args: string[]): string => args.join("");
|
||||
|
||||
export default concat;
|
3
internal/gatsby/utils/decrement.ts
Normal file
3
internal/gatsby/utils/decrement.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
const decrement = (n: number): number => n - 1;
|
||||
|
||||
export default decrement;
|
3
internal/gatsby/utils/increment.ts
Normal file
3
internal/gatsby/utils/increment.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
const increment = (n: number): number => n + 1;
|
||||
|
||||
export default increment;
|
4
internal/gatsby/utils/index.ts
Normal file
4
internal/gatsby/utils/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export { default as toKebabCase } from "./to-kebab-case";
|
||||
export { default as decrement } from "./decrement";
|
||||
export { default as increment } from "./increment";
|
||||
export { default as concat } from "./concat";
|
6
internal/gatsby/utils/to-kebab-case.ts
Normal file
6
internal/gatsby/utils/to-kebab-case.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
const toKebabCase = (str: string = ""): string => str.toLowerCase()
|
||||
.replace(/[^\w\s]/gi, "")
|
||||
.split(" ").join("-")
|
||||
.split("_").join("-");
|
||||
|
||||
export default toKebabCase;
|
52
internal/testing/__mocks__/all-markdown-remark.ts
Normal file
52
internal/testing/__mocks__/all-markdown-remark.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
export default {
|
||||
allMarkdownRemark: {
|
||||
group: [
|
||||
{
|
||||
fieldValue: "typography",
|
||||
totalCount: 1,
|
||||
},
|
||||
{
|
||||
fieldValue: "design inspiration",
|
||||
totalCount: 1,
|
||||
},
|
||||
],
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
id: "08870ea6-bdc8-4ec6-bf72-1e7d4488eb72",
|
||||
fields: {
|
||||
slug: "/posts/perfecting-the-art-of-perfection",
|
||||
categorySlug: "/typography",
|
||||
},
|
||||
frontmatter: {
|
||||
date: "2016-09-01",
|
||||
description:
|
||||
"An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.",
|
||||
category: "typography",
|
||||
title: "Perfecting the Art of Perfection",
|
||||
template: "post",
|
||||
},
|
||||
html: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
node: {
|
||||
id: "066adc91-f87a-4e57-9fef-7a677baf5c1d",
|
||||
fields: {
|
||||
slug: "/posts/the-birth-of-movable-type",
|
||||
categorySlug: "/design-inspiration",
|
||||
},
|
||||
frontmatter: {
|
||||
date: "2016-09-01",
|
||||
description:
|
||||
"German inventor Johannes Gutenberg developed a method of movable type and used it to create one of the western world’s first major printed books, the “Forty–Two–Line” Bible.",
|
||||
category: "design inspiration",
|
||||
title: "Johannes Gutenberg: The Birth of Movable Type",
|
||||
template: "post",
|
||||
},
|
||||
html: "",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
8
internal/testing/__mocks__/author.ts
Normal file
8
internal/testing/__mocks__/author.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import contacts from "./contacts";
|
||||
|
||||
export default {
|
||||
photo: "/static/photo.jpg",
|
||||
bio: "Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu.",
|
||||
name: "John Doe",
|
||||
contacts,
|
||||
};
|
8
internal/testing/__mocks__/contacts.ts
Normal file
8
internal/testing/__mocks__/contacts.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export default {
|
||||
rss: "#",
|
||||
email: "#",
|
||||
github: "#",
|
||||
twitter: "#",
|
||||
telegram: "#",
|
||||
vkontakte: "#",
|
||||
};
|
28
internal/testing/__mocks__/gatsby.ts
Normal file
28
internal/testing/__mocks__/gatsby.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import React from "react";
|
||||
|
||||
const gatsby = jest.requireActual("gatsby");
|
||||
|
||||
export default {
|
||||
...gatsby,
|
||||
graphql: jest.fn(),
|
||||
Link: jest
|
||||
.fn()
|
||||
.mockImplementation(
|
||||
({
|
||||
activeClassName,
|
||||
activeStyle,
|
||||
getProps,
|
||||
innerRef,
|
||||
ref,
|
||||
replace,
|
||||
to,
|
||||
...rest
|
||||
}) =>
|
||||
React.createElement("a", {
|
||||
...rest,
|
||||
href: to,
|
||||
}),
|
||||
),
|
||||
StaticQuery: jest.fn(),
|
||||
useStaticQuery: jest.fn(),
|
||||
};
|
7
internal/testing/__mocks__/index.ts
Normal file
7
internal/testing/__mocks__/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export { default as allMarkdownRemark } from "./all-markdown-remark";
|
||||
export { default as markdownRemark } from "./markdown-remark";
|
||||
export { default as siteMetadata } from "./site-metadata";
|
||||
export { default as pageContext } from "./page-context";
|
||||
export { default as contacts } from "./contacts";
|
||||
export { default as author } from "./author";
|
||||
export { default as menu } from "./menu";
|
16
internal/testing/__mocks__/markdown-remark.ts
Normal file
16
internal/testing/__mocks__/markdown-remark.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
export default {
|
||||
id: "08870ea6-bdc8-4ec6-bf72-1e7d4488eb72",
|
||||
fields: {
|
||||
slug: "/posts/perfecting-the-art-of-perfection",
|
||||
categorySlug: "/typography",
|
||||
},
|
||||
frontmatter: {
|
||||
date: "2016-09-01",
|
||||
description:
|
||||
"An Essay on Typography by Eric Gill takes the reader back to the year 1930. The year when a conflict between two worlds came to its term. The machines of the industrial world finally took over the handicrafts.",
|
||||
category: "typography",
|
||||
title: "Perfecting the Art of Perfection",
|
||||
template: "post",
|
||||
},
|
||||
html: "",
|
||||
};
|
5
internal/testing/__mocks__/menu.ts
Normal file
5
internal/testing/__mocks__/menu.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export default [
|
||||
{ label: "Articles", path: "/" },
|
||||
{ label: "About Me", path: "/pages/about" },
|
||||
{ label: "Contact Me", path: "/pages/contacts" },
|
||||
];
|
12
internal/testing/__mocks__/page-context.ts
Normal file
12
internal/testing/__mocks__/page-context.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export default {
|
||||
pageContext: {
|
||||
group: "typography",
|
||||
pagination: {
|
||||
currentPage: 2,
|
||||
prevPagePath: "/typography/page/1",
|
||||
nextPagePath: "/typography/page/3",
|
||||
hasNextPage: true,
|
||||
hasPrevPage: true,
|
||||
},
|
||||
},
|
||||
};
|
17
internal/testing/__mocks__/site-metadata.ts
Normal file
17
internal/testing/__mocks__/site-metadata.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import author from "./author";
|
||||
import menu from "./menu";
|
||||
|
||||
export default {
|
||||
site: {
|
||||
siteMetadata: {
|
||||
url: "https://www.lumen.local",
|
||||
title: "Blog by John Doe",
|
||||
subtitle:
|
||||
"Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sed arcu.",
|
||||
copyright: "All rights reserved.",
|
||||
postsPerPage: 4,
|
||||
author,
|
||||
menu,
|
||||
},
|
||||
},
|
||||
};
|
30
internal/testing/jest-config.ts
Normal file
30
internal/testing/jest-config.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import type { Config } from "@jest/types";
|
||||
|
||||
import swc from "./swc-config";
|
||||
|
||||
const jestConfig: Config.InitialOptions = {
|
||||
testEnvironment: "jsdom",
|
||||
rootDir: "../../",
|
||||
moduleNameMapper: {
|
||||
"@/hooks": ["<rootDir>/src/hooks"],
|
||||
"@/utils": ["<rootDir>/src/utils"],
|
||||
"@/constants": ["<rootDir>/src/constants"],
|
||||
"@/utils/([^\\.]*)$": ["<rootDir>/src/utils"],
|
||||
"@/pages/([^\\.]*)$": ["<rootDir>/src/pages/$1"],
|
||||
"@/hooks/([^\\.]*)$": ["<rootDir>/src/hooks/$1"],
|
||||
"@/mocks": ["<rootDir>/internal/testing/__mocks__"],
|
||||
"@/scss/([^\\.]*)$": ["<rootDir>/src/assets/scss/$1"],
|
||||
"@/constants/([^\\.]*)$": ["<rootDir>/src/constants/$1"],
|
||||
"@/images/([^\\.]*)$": ["<rootDir>/src/assets/images/$1"],
|
||||
"@/components/([^\\.]*)$": ["<rootDir>/src/components/$1"],
|
||||
".+\\.(css|sass|scss)$": "identity-obj-proxy",
|
||||
".+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
|
||||
"identity-obj-proxy",
|
||||
},
|
||||
transform: { "^.+\\.(t)sx?$": ["@swc/jest", swc] },
|
||||
setupFiles: ["<rootDir>/internal/testing/jest-setup.ts"],
|
||||
testPathIgnorePatterns: ["node_modules", ".cache", "public"],
|
||||
transformIgnorePatterns: ["node_modules/(?!(gatsby)/)"],
|
||||
};
|
||||
|
||||
export default jestConfig;
|
1
internal/testing/jest-setup.ts
Normal file
1
internal/testing/jest-setup.ts
Normal file
@@ -0,0 +1 @@
|
||||
jest.mock("gatsby", () => jest.requireActual("./__mocks__/gatsby").default);
|
19
internal/testing/swc-config.ts
Normal file
19
internal/testing/swc-config.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
const config = {
|
||||
sourceMaps: true,
|
||||
module: {
|
||||
type: "commonjs",
|
||||
},
|
||||
jsc: {
|
||||
parser: {
|
||||
syntax: "typescript",
|
||||
tsx: true,
|
||||
},
|
||||
transform: {
|
||||
react: {
|
||||
runtime: "automatic",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
Reference in New Issue
Block a user