refactor(client): migrate Gatsby setup files to TypeScript (#66367)

This commit is contained in:
Sem Bauke
2026-03-23 10:28:04 +01:00
committed by GitHub
parent fe421a03c6
commit 08db6f8258
6 changed files with 58 additions and 45 deletions
@@ -1,6 +1,6 @@
import type { GatsbyBrowser } from 'gatsby';
import { LocationProvider } from '@gatsbyjs/reach-router';
import cookies from 'browser-cookies';
import PropTypes from 'prop-types';
import React from 'react';
import { I18nextProvider } from 'react-i18next';
import { Provider } from 'react-redux';
@@ -15,7 +15,9 @@ import GrowthBookProvider from './src/components/growth-book/growth-book-wrapper
const store = createStore();
export const wrapRootElement = ({ element }) => {
export const wrapRootElement: GatsbyBrowser['wrapRootElement'] = ({
element
}) => {
return (
<LocationProvider>
<Provider store={store}>
@@ -31,19 +33,16 @@ export const wrapRootElement = ({ element }) => {
);
};
wrapRootElement.propTypes = {
element: PropTypes.any
};
export const wrapPageElement: GatsbyBrowser['wrapPageElement'] = layoutSelector;
export const wrapPageElement = layoutSelector;
export const disableCorePrefetching: GatsbyBrowser['disableCorePrefetching'] =
() => true;
export const disableCorePrefetching = () => true;
export const onRouteUpdate = () => {
export const onRouteUpdate: GatsbyBrowser['onRouteUpdate'] = () => {
store.dispatch({ type: 'app.routeUpdated' });
};
export const onClientEntry = () => {
export const onClientEntry: GatsbyBrowser['onClientEntry'] = () => {
// Letting the users' browsers expire the cookie seems to have caused issues
// for some users. Until we have time to investigate further, we should remove
// the cookie on every page load.
@@ -1,15 +1,17 @@
const path = require('path');
const envData = require('./config/env.json');
const {
import path from 'path';
import type { GatsbyConfig } from 'gatsby';
import envData from './config/env.json';
import {
buildChallenges,
replaceChallengeNodes,
localeChallengesRootDir
} = require('./utils/build-challenges');
const { pathPrefix } = require('./utils/gatsby/path-prefix');
} from './utils/build-challenges';
import { pathPrefix } from './utils/gatsby/path-prefix';
const { curriculumLocale, homeLocation } = envData;
const { homeLocation } = envData;
module.exports = {
const config: GatsbyConfig = {
flags: {
DEV_SSR: false
},
@@ -43,13 +45,14 @@ module.exports = {
}
},
{
resolve: require.resolve(
resolve: path.resolve(
__dirname,
'../tools/client-plugins/gatsby-source-challenges'
),
options: {
name: 'challenges',
source: buildChallenges,
onSourceChange: replaceChallengeNodes(curriculumLocale),
onSourceChange: replaceChallengeNodes(),
curriculumPath: localeChallengesRootDir
}
},
@@ -63,3 +66,5 @@ module.exports = {
}
]
};
export default config;
+19 -14
View File
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const webpack = require('webpack');
@@ -8,7 +9,7 @@ exports.createPages = async function createPages({
actions,
graphql,
reporter
}) {
}: any) {
if (!env.algoliaAPIKey || !env.algoliaAppId) {
if (process.env.FREECODECAMP_NODE_ENV === 'production') {
throw new Error(
@@ -45,13 +46,15 @@ exports.createPages = async function createPages({
}
`);
const superBlocks = allSuperBlockStructure.nodes.map(node => node.superBlock);
superBlocks.forEach(superBlock => {
const superBlocks = allSuperBlockStructure.nodes.map(
(node: { superBlock: string }) => node.superBlock
);
superBlocks.forEach((superBlock: string) => {
createSuperBlockIntroPages(createPage)({ superBlock });
});
};
exports.onCreateWebpackConfig = ({ stage, actions }) => {
exports.onCreateWebpackConfig = ({ stage, actions }: any) => {
const newPlugins = [
// We add the shims of the node globals to the global scope
new webpack.ProvidePlugin({
@@ -73,18 +76,18 @@ exports.onCreateWebpackConfig = ({ stage, actions }) => {
resolve: {
fallback: {
fs: false,
path: require.resolve('path-browserify'),
assert: require.resolve('assert'),
crypto: require.resolve('crypto-browserify'),
util: require.resolve('util/util'),
buffer: require.resolve('buffer'),
stream: require.resolve('stream-browserify'),
process: require.resolve('process/browser')
path: 'path-browserify',
assert: 'assert',
crypto: 'crypto-browserify',
util: 'util/util',
buffer: 'buffer',
stream: 'stream-browserify',
process: 'process/browser'
}
},
plugins: newPlugins,
ignoreWarnings: [
warning => {
(warning: Error) => {
if (warning instanceof Error) {
if (warning.message.includes('mini-css-extract-plugin')) {
return true;
@@ -96,7 +99,7 @@ exports.onCreateWebpackConfig = ({ stage, actions }) => {
});
};
exports.onCreateBabelConfig = ({ actions }) => {
exports.onCreateBabelConfig = ({ actions }: any) => {
actions.setBabelPlugin({
name: '@babel/plugin-proposal-function-bind'
});
@@ -105,7 +108,7 @@ exports.onCreateBabelConfig = ({ actions }) => {
});
};
exports.createSchemaCustomization = ({ actions }) => {
exports.createSchemaCustomization = ({ actions }: any) => {
const { createTypes } = actions;
// This hook is supported by the test runner, but is not currently used by the
// client, so we have to tell Gatsby that it exists.
@@ -116,3 +119,5 @@ exports.createSchemaCustomization = ({ actions }) => {
`;
createTypes(typeDefs);
};
export {};
+13 -11
View File
@@ -1,4 +1,4 @@
import PropTypes from 'prop-types';
import type { GatsbySSR } from 'gatsby';
import React from 'react';
import { I18nextProvider } from 'react-i18next';
import { Provider } from 'react-redux';
@@ -18,7 +18,7 @@ import GrowthBookProvider from './src/components/growth-book/growth-book-wrapper
const store = createStore();
export const wrapRootElement = ({ element }) => {
export const wrapRootElement: GatsbySSR['wrapRootElement'] = ({ element }) => {
return (
<Provider store={store}>
<I18nextProvider i18n={i18n}>
@@ -30,13 +30,9 @@ export const wrapRootElement = ({ element }) => {
);
};
wrapRootElement.propTypes = {
element: PropTypes.any
};
export const wrapPageElement: GatsbySSR['wrapPageElement'] = layoutSelector;
export const wrapPageElement = layoutSelector;
export const onRenderBody = ({
export const onRenderBody: GatsbySSR['onRenderBody'] = ({
pathname,
setHeadComponents,
setPreBodyComponents,
@@ -47,15 +43,21 @@ export const onRenderBody = ({
setPostBodyComponents(getPostBodyComponents(pathname));
};
export const onPreRenderHTML = ({
export const onPreRenderHTML: GatsbySSR['onPreRenderHTML'] = ({
getHeadComponents,
replaceHeadComponents
}) => {
const isBootstrapScript = (key: React.Key | null) =>
key === 'bootstrap-min-preload' || key === 'bootstrap-min';
const headComponents = getHeadComponents();
headComponents.sort((x, y) => {
if (x.key === 'bootstrap-min-preload' || x.key === 'bootstrap-min') {
const xKey = React.isValidElement(x) ? x.key : null;
const yKey = React.isValidElement(y) ? y.key : null;
if (isBootstrapScript(xKey)) {
return -1;
} else if (y.key === 'bootstrap-min-preload' || y.key === 'bootstrap-min') {
} else if (isBootstrapScript(yKey)) {
return 1;
}
return 0;
+1 -1
View File
@@ -17,7 +17,7 @@
},
"homepage": "https://github.com/freeCodeCamp/freeCodeCamp#readme",
"author": "freeCodeCamp <team@freecodecamp.org>",
"main": "none",
"main": "index.js",
"scripts": {
"build": "NODE_OPTIONS=\"--max-old-space-size=7168 --no-deprecation\" gatsby build --prefix-paths",
"clean": "gatsby clean",
+2
View File
@@ -16,6 +16,8 @@
"skipLibCheck": true
},
"include": [
"gatsby-*.ts",
"gatsby-*.tsx",
"i18n/**/*",
"plugins/**/*",
"src/**/*",