Skip to content

Commit

Permalink
refactor: refactoring gatsby node
Browse files Browse the repository at this point in the history
  • Loading branch information
PKulkoRaccoonGang committed May 21, 2023
1 parent 61634cd commit a3e58df
Show file tree
Hide file tree
Showing 8 changed files with 214 additions and 195 deletions.
197 changes: 7 additions & 190 deletions www/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,199 +4,16 @@
* See: https://www.gatsbyjs.com/docs/node-apis/
*/

// You can delete this file if you're not using it
const path = require('path');
const { createFilePath } = require('gatsby-source-filesystem');
const sass = require('sass');
const css = require('css');
const createPages = require('./utils/createPages');
const onCreateNode = require('./utils/onCreateNode');
const onCreateWebpackConfig = require('./utils/onCreateWebpackConfig');
const createCssUtilityClassNodes = require('./utils/createCssUtilityClassNodes');

const fs = require('fs');
const { INSIGHTS_PAGES } = require('./src/config');
const { getThemesSCSSVariables, processComponentSCSSVariables } = require('./theme-utils');
const componentsUsage = require('./src/utils/componentsUsage');
exports.onCreateWebpackConfig = ({ actions }) => onCreateWebpackConfig(actions);

exports.onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
resolve: {
alias: {
'~paragon-react': path.resolve(__dirname, '../src'),
'~paragon-style': path.resolve(__dirname, '../scss'),
'~paragon-icons': path.resolve(__dirname, '../icons'),
},
},
});
};

exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions;
// you only want to operate on `Mdx` nodes. If you had content from a
// remote CMS you could also check to see if the parent node was a
// `File` node here
if (node.internal.type === 'Mdx') {
const value = createFilePath({ node, getNode })
.split('README')[0]
.toLowerCase();

const isChangelogNode = node.fileAbsolutePath && node.fileAbsolutePath.endsWith('CHANGELOG.md');

createNodeField({
// Name of the field you are adding
name: 'slug',
// Individual MDX node
node,
// Generated value based on filepath with 'components' prefix. you
// don't need a separating '/' before the value because
// createFilePath returns a path with the leading '/'.
value: isChangelogNode ? 'changelog' : `/components${value}`,
});
}
};

exports.createPages = async ({ graphql, actions, reporter }) => {
// Destructure the createPage function from the actions object
const { createPage, createRedirect } = actions;
// MDX transforms markdown generated by gatsby-transformer-react-docgen
// This query filters out all of those markdown nodes and assumes all others
// are for page creation purposes.
const result = await graphql(`
query {
allMdx(
filter: {
parent: {
internal: { owner: { nin: "gatsby-transformer-react-docgen" } }
}
}
) {
edges {
node {
id
fields {
slug
}
frontmatter {
components
}
slug
}
}
}
}
`);
if (result.errors) {
reporter.panicOnBuild('🚨 ERROR: Loading createPages query');
}
// Create component detail pages.
const components = result.data.allMdx.edges;

const themesSCSSVariables = await getThemesSCSSVariables();

// you'll call `createPage` for each result
// eslint-disable-next-line no-restricted-syntax
for (const { node } of components) {
const componentDir = node.slug.split('/')[0];
const variablesPath = path.resolve(__dirname, `../src/${componentDir}/_variables.scss`);
let scssVariablesData = {};

if (fs.existsSync(variablesPath)) {
// eslint-disable-next-line no-await-in-loop
scssVariablesData = await processComponentSCSSVariables(variablesPath, themesSCSSVariables);
}

createPage({
// This is the slug you created before
// (or `node.frontmatter.slug`)
path: node.fields.slug,
// This component will wrap our MDX content
component: path.resolve('./src/templates/component-page-template.tsx'),
// You can use the values in this context in
// our page layout component
context: {
id: node.id,
components: node.frontmatter.components || [],
scssVariablesData,
componentsUsageInsights: Object.keys(componentsUsage),
},
});
}

INSIGHTS_PAGES.forEach(({ path: pagePath, tab }) => {
createPage({
path: pagePath,
component: require.resolve('./src/pages/insights.tsx'),
context: { tab },
});
});

createRedirect({
fromPath: '/playroom',
toPath: '/playroom/index.html',
});

createRedirect({
fromPath: '/playroom/preview',
toPath: '/playroom/preview/index.html',
});
};

function createCssUtilityClassNodes({
actions,
createNodeId,
createContentDigest,
}) {
const { createNode } = actions;

// We convert to CSS first since we prefer the real values over tokens.
const compiledCSS = sass
.renderSync({
file: path.resolve(__dirname, '../scss/core/utilities-only.scss'),
// Resolve tildes the way webpack would in our base npm project
importer(url) {
let resolvedUrl = url;
if (url[0] === '~') {
resolvedUrl = path.resolve(__dirname, '../node_modules', url.substr(1));
}
return { file: resolvedUrl };
},
})
.css.toString();

const sheet = css.parse(compiledCSS).stylesheet;

sheet.rules.forEach(({ selectors, position, declarations }) => {
if (!selectors) { return; }

selectors.forEach(selector => {
if (selector[0] !== '.') { return; } // classes only

const classSelector = selector.substr(1);

const nodeData = {
selector: classSelector,
declarations: declarations.map(
({ property, value }) => `${property}: ${value};`,
),
isUtility:
declarations.length === 1
&& declarations[0].value.includes('!important'),
};

const nodeMeta = {
id: createNodeId(
`rule-${classSelector}-${position.start.line}-${position.end.line}`,
),
parent: null,
children: [],
internal: {
type: 'CssUtilityClasses',
contentDigest: createContentDigest(nodeData),
},
};
exports.onCreateNode = ({ node, actions, getNode }) => onCreateNode(node, actions, getNode);

const node = { ...nodeData, ...nodeMeta };
createNode(node);
});
});
}
exports.createPages = ({ graphql, actions, reporter }) => createPages(graphql, actions, reporter);

exports.sourceNodes = ({ actions, createNodeId, createContentDigest }) => {
createCssUtilityClassNodes({ actions, createNodeId, createContentDigest });
Expand Down
7 changes: 4 additions & 3 deletions www/src/components/insights/SummaryUsage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import {
import componentsUsage from '../../utils/componentsUsage';
import InsightsContext from '../../context/InsightsContext';
import SummaryUsageExamples, { ISummaryUsageExamples } from './SummaryUsageExamples';
import { IComponentUsageData, IDependentUsage, IInsightsContext } from '../../types/types';
import { IComponentUsageData, IInsightsContext } from '../../types/types';
import getDependentProjectsUsages from '../../utils/getDependentProjectsUsages';

interface IFilterData {
name: string,
Expand All @@ -22,7 +23,7 @@ const round = (n: number) => Math.round(n * 10) / 10;
const ICON_TYPE = 'Icon';
const TABLE_PAGE_SIZE = 10;
const componentsInUsage = Object.keys(componentsUsage);
const dependentProjects: IDependentUsage[] = [];
const dependentProjects = getDependentProjectsUsages();

function SummaryUsage() {
const { paragonTypes = {}, isParagonIcon = () => false } = useContext(InsightsContext) as IInsightsContext;
Expand Down Expand Up @@ -72,7 +73,7 @@ function SummaryUsage() {

const averageComponentsUsedPerProject = dependentProjects
.reduce((accumulator, project) => accumulator + project.count, 0) / dependentProjects.length;

console.log('dependentProjects', dependentProjects);
return (
<div className="pt-5 mb-5">
<div className="mb-5">
Expand Down
2 changes: 1 addition & 1 deletion www/src/context/InsightsContext.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function InsightsContextProvider({ children }) {
setParagonTypes(getParagonComponentsTypes(Components));
}, []);

const isParagonIcon = (name) => name in Icons;
const isParagonIcon = (name) => name in Icons || name.match('Icon');

const contextValue = useMemo(() => ({
paragonTypes,
Expand Down
2 changes: 1 addition & 1 deletion www/src/utils/getParagonComponentsTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const getParagonComponentsTypes = (components) => {
case isFunctionComponent || isObjectComponent || isContext:
componentType = 'Component';
break;
case component.constructor.name === 'Object':
case typeof component === 'object':
componentType = 'Object';
break;
case typeof component === 'function':
Expand Down
65 changes: 65 additions & 0 deletions www/utils/createCssUtilityClassNodes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const sass = require('sass');
const path = require('path');
const css = require('css');

function createCssUtilityClassNodes({
actions,
createNodeId,
createContentDigest,
}) {
const { createNode } = actions;

// We convert to CSS first since we prefer the real values over tokens.
const compiledCSS = sass
.renderSync({
file: path.resolve(__dirname, '../../scss/core/utilities-only.scss'),
// Resolve tildes the way webpack would in our base npm project
importer(url) {
let resolvedUrl = url;
if (url[0] === '~') {
resolvedUrl = path.resolve(__dirname, '../../node_modules', url.substr(1));
}
return { file: resolvedUrl };
},
})
.css.toString();

const sheet = css.parse(compiledCSS).stylesheet;

sheet.rules.forEach(({ selectors, position, declarations }) => {
if (!selectors) { return; }

selectors.forEach(selector => {
if (selector[0] !== '.') { return; } // classes only

const classSelector = selector.substr(1);

const nodeData = {
selector: classSelector,
declarations: declarations.map(
({ property, value }) => `${property}: ${value};`,
),
isUtility:
declarations.length === 1
&& declarations[0].value.includes('!important'),
};

const nodeMeta = {
id: createNodeId(
`rule-${classSelector}-${position.start.line}-${position.end.line}`,
),
parent: null,
children: [],
internal: {
type: 'CssUtilityClasses',
contentDigest: createContentDigest(nodeData),
},
};

const node = { ...nodeData, ...nodeMeta };
createNode(node);
});
});
}

module.exports = createCssUtilityClassNodes;
Loading

0 comments on commit a3e58df

Please sign in to comment.