fix(api, client): update Gatsby, webpack & related things (#41452)

Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
Mrugesh Mohapatra
2021-03-26 00:43:43 +05:30
committed by GitHub
parent 92dfb3065c
commit ad9b1f89d8
71 changed files with 35182 additions and 9001 deletions

View File

@ -33,6 +33,7 @@
"import/no-duplicates": 2,
"import/no-unresolved": [2, { "commonjs": true }],
"import/unambiguous": 2,
"import/no-anonymous-default-export": 2,
"jsx-quotes": [2, "prefer-single"],
"jsx-a11y/accessible-emoji": "error",
"jsx-a11y/alt-text": "error",

View File

@ -14,7 +14,7 @@ export function ensureLowerCaseEmail(profile) {
: '';
}
export default function (UserIdent) {
export default function initializeUserIdent(UserIdent) {
UserIdent.on('dataSourceAttached', () => {
UserIdent.findOne$ = observeMethod(UserIdent, 'findOne');
});

View File

@ -1,6 +1,6 @@
import { Observable } from 'rx';
export default function (Block) {
export default function initializeBlock(Block) {
Block.on('dataSourceAttached', () => {
Block.findOne$ = Observable.fromNodeCallback(Block.findOne, Block);
Block.findById$ = Observable.fromNodeCallback(Block.findById, Block);

View File

@ -152,7 +152,7 @@ function populateRequiredFields(user) {
return;
}
export default function (User) {
export default function initializeUser(User) {
// set salt factor for passwords
User.settings.saltWorkFactor = 5;
// set user.rand to random number

View File

@ -1,6 +1,6 @@
import csurf from 'csurf';
export default function () {
export default function getCsurf() {
const protection = csurf({
cookie: {
domain: process.env.COOKIE_DOMAIN || 'localhost',

View File

@ -1,7 +1,7 @@
import qs from 'query-string';
// add rx methods to express
export default function () {
export default function getExpressExtensions() {
return function expressExtensions(req, res, next) {
res.redirectWithFlash = uri => {
const flash = req.flash();

View File

@ -48,8 +48,11 @@ export function isAllowedPath(path, pathsAllowedREs = _pathsAllowedREs) {
return pathsAllowedREs.some(re => re.test(path));
}
export default ({ jwtSecret = _jwtSecret, getUserById = _getUserById } = {}) =>
function requestAuthorisation(req, res, next) {
export default function getRequestAuthorisation({
jwtSecret = _jwtSecret,
getUserById = _getUserById
} = {}) {
return function requestAuthorisation(req, res, next) {
const { origin } = getRedirectParams(req);
const { path } = req;
if (!isAllowedPath(path)) {
@ -102,3 +105,4 @@ export default ({ jwtSecret = _jwtSecret, getUserById = _getUserById } = {}) =>
}
return Promise.resolve(next());
};
}

View File

@ -1,6 +1,6 @@
import { Observable } from 'rx';
export default function (AuthToken) {
export default function initializeAuthToken(AuthToken) {
AuthToken.on('dataSourceAttached', () => {
AuthToken.findOne$ = Observable.fromNodeCallback(
AuthToken.findOne.bind(AuthToken)

View File

@ -7,7 +7,7 @@ import InMemoryCache from '../utils/in-memory-cache';
const log = debug('fcc:boot:donate');
const fiveMinutes = 1000 * 60 * 5;
export default function (Donation) {
export default function initializeDonation(Donation) {
let activeDonationUpdateInterval = null;
const activeDonationCountCacheTTL = fiveMinutes;
const activeDonationCountCache = InMemoryCache(0, reportError);

View File

@ -9,7 +9,7 @@ const failureRedirect = `${homeLocation}/signin`;
// TODO: can we remove passport-mock-strategy entirely in prod? That would let
// us make passport-mock-strategy a dev dep, as it should be.
export default {
const passportProviders = {
devlogin: {
authScheme: 'mock',
provider: 'dev',
@ -45,3 +45,5 @@ export default {
failureFlash: true
}
};
export default passportProviders;

View File

@ -1,19 +0,0 @@
export default {
bg9997c9c79feddfaeb9bdef: '56bbb991ad1ed5201cd392ca',
bg9995c9c69feddfaeb9bdef: '56bbb991ad1ed5201cd392cb',
bg9994c9c69feddfaeb9bdef: '56bbb991ad1ed5201cd392cc',
bg9996c9c69feddfaeb9bdef: '56bbb991ad1ed5201cd392cd',
bg9997c9c69feddfaeb9bdef: '56bbb991ad1ed5201cd392ce',
bg9997c9c89feddfaeb9bdef: '56bbb991ad1ed5201cd392cf',
bg9998c9c99feddfaeb9bdef: '56bbb991ad1ed5201cd392d0',
bg9999c9c99feddfaeb9bdef: '56bbb991ad1ed5201cd392d1',
bg9999c9c99feedfaeb9bdef: '56bbb991ad1ed5201cd392d2',
bg9999c9c99fdddfaeb9bdef: '56bbb991ad1ed5201cd392d3',
bb000000000000000000001: '56bbb991ad1ed5201cd392d4',
bc000000000000000000001: '56bbb991ad1ed5201cd392d5',
bb000000000000000000002: '56bbb991ad1ed5201cd392d6',
bb000000000000000000003: '56bbb991ad1ed5201cd392d7',
bb000000000000000000004: '56bbb991ad1ed5201cd392d8',
bb000000000000000000005: '56bbb991ad1ed5201cd392d9',
bb000000000000000000006: '56bbb991ad1ed5201cd392da'
};

View File

@ -1,17 +1,13 @@
const path = require('path');
const {
clientLocale,
curriculumLocale,
homeLocation
} = require('../config/env.json');
const envData = require('../config/env.json');
const {
buildChallenges,
replaceChallengeNode,
localeChallengesRootDir
} = require('./utils/buildChallenges');
const { clientLocale, curriculumLocale, homeLocation } = envData;
const curriculumIntroRoot = path.resolve(__dirname, './src/pages');
const pathPrefix =
clientLocale === 'english' || clientLocale === 'chinese'
@ -84,20 +80,20 @@ module.exports = {
}
}
},
{
resolve: `gatsby-plugin-advanced-sitemap`,
options: {
exclude: [
`/dev-404-page`,
`/404`,
`/404.html`,
`/offline-plugin-app-shell-fallback`,
`/learn`,
/(\/)learn(\/)\S*/
],
addUncaughtPages: true
}
},
// {
// resolve: `gatsby-plugin-advanced-sitemap`,
// options: {
// exclude: [
// `/dev-404-page`,
// `/404`,
// `/404.html`,
// `/offline-plugin-app-shell-fallback`,
// `/learn`,
// /(\/)learn(\/)\S*/
// ],
// addUncaughtPages: true
// }
// },
{
resolve: 'gatsby-plugin-manifest',
options: {

View File

@ -1,4 +1,5 @@
const env = require('../config/env');
const webpack = require('webpack');
const { createFilePath } = require('gatsby-source-filesystem');
const uniq = require('lodash/uniq');
@ -184,6 +185,13 @@ exports.onCreateWebpackConfig = ({ stage, plugins, actions }) => {
process.env.HOME_PATH || 'http://localhost:3000'
),
STRIPE_PUBLIC_KEY: JSON.stringify(process.env.STRIPE_PUBLIC_KEY || '')
}),
// We add the shims of the node globals to the global scope
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer']
}),
new webpack.ProvidePlugin({
process: 'process/browser'
})
];
// The monaco editor relies on some browser only globals so should not be
@ -193,8 +201,17 @@ exports.onCreateWebpackConfig = ({ stage, plugins, actions }) => {
newPlugins.push(new MonacoWebpackPlugin());
}
actions.setWebpackConfig({
node: {
fs: 'empty'
resolve: {
fallback: {
fs: false,
path: false,
assert: require.resolve('assert'),
crypto: require.resolve('crypto-browserify'),
util: false,
buffer: require.resolve('buffer'),
stream: require.resolve('stream-browserify'),
process: require.resolve('process/browser')
}
},
plugins: newPlugins
});

View File

@ -1,9 +1,11 @@
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
const { clientLocale } = require('../../config/env.json');
const envData = require('../../config/env.json');
const { i18nextCodes } = require('../../config/i18n/all-langs');
const { clientLocale } = envData;
const i18nextCode = i18nextCodes[clientLocale];
i18n.use(initReactI18next).init({

43782
client/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -21,33 +21,37 @@
"@reach/router": "^1.3.4",
"@stripe/react-stripe-js": "^1.4.0",
"algoliasearch": "^3.35.1",
"assert": "^2.0.0",
"axios": "^0.21.1",
"babel-plugin-prismjs": "^2.0.1",
"bezier-easing": "^2.1.0",
"browser-cookies": "^1.2.0",
"buffer": "^6.0.3",
"chai": "^4.3.3",
"crypto-browserify": "^3.12.0",
"csrf": "^3.1.0",
"date-fns": "^2.19.0",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.15.6",
"final-form": "^4.20.2",
"gatsby": "^2.32.9",
"gatsby-cli": "^2.19.1",
"gatsby": "^3.1.2",
"gatsby-cli": "^3.0.0",
"gatsby-plugin-advanced-sitemap": "^1.6.0",
"gatsby-plugin-create-client-paths": "^2.10.0",
"gatsby-plugin-manifest": "^2.12.1",
"gatsby-plugin-postcss": "^2.3.13",
"gatsby-plugin-react-helmet": "^3.10.0",
"gatsby-plugin-create-client-paths": "^3.0.0",
"gatsby-plugin-manifest": "^3.0.0",
"gatsby-plugin-postcss": "^4.0.0",
"gatsby-plugin-react-helmet": "^4.0.0",
"gatsby-plugin-remove-serviceworker": "^1.0.0",
"gatsby-remark-prismjs": "^3.13.0",
"gatsby-source-filesystem": "^2.11.1",
"gatsby-transformer-remark": "^2.16.1",
"gatsby-remark-prismjs": "^4.0.0",
"gatsby-source-filesystem": "^3.0.0",
"gatsby-transformer-remark": "^3.0.0",
"i18next": "^19.9.1",
"jquery": "^3.6.0",
"lodash": "^4.17.21",
"monaco-editor": "^0.22.3",
"nanoid": "^3.1.20",
"prismjs": "^1.23.0",
"process": "^0.11.10",
"query-string": "^6.14.1",
"react": "^16.14.0",
"react-dom": "^16.14.0",
@ -77,6 +81,7 @@
"sanitize-html": "^2.3.2",
"sass.js": "^0.11.0",
"store": "^2.0.12",
"stream-browserify": "^3.0.0",
"typescript": "^4.2.3",
"validator": "^13.5.2"
},
@ -87,8 +92,8 @@
"scripts": {
"prebuild": "echo 'Client workers building...' && npm run build:workers && echo 'Client workers ready.' && node ../tools/scripts/build/ensure-env.js",
"build": "node --max_old_space_size=7168 node_modules/gatsby-cli build --prefix-paths",
"build:workers": "node --max_old_space_size=7168 node_modules/webpack-cli --env.production --config ./webpack-workers.js && echo",
"build:workers:debug": "node --max_old_space_size=7168 node_modules/webpack-cli --env.production --config ./webpack-workers.js --progress",
"build:workers": "node --max_old_space_size=7168 node_modules/webpack-cli/bin/cli --env production --config ./webpack-workers.js && echo",
"build:workers:debug": "node --max_old_space_size=7168 node_modules/webpack-cli/bin/cli --env production --config ./webpack-workers.js --progress",
"clean": "gatsby clean",
"predevelop": "npm run prebuild",
"develop": "gatsby develop --inspect=9230",
@ -115,8 +120,8 @@
"monaco-editor-webpack-plugin": "^3.0.0",
"react-test-renderer": "^16.14.0",
"redux-saga-test-plan": "^4.0.1",
"webpack": "^4.46.0",
"webpack-cli": "^3.3.12"
"webpack": "^5.25.1",
"webpack-cli": "^4.5.0"
},
"repository": {
"type": "git",

View File

@ -1,3 +1,5 @@
export default {
const analytics = {
event: () => {}
};
export default analytics;

View File

@ -1,4 +1,4 @@
export default [
const mockChallengeNodes = [
{
fields: {
slug: '/super-block-one/block-a/challenge-one',
@ -133,3 +133,5 @@ export default [
dashedName: 'challenge-two'
}
];
export default mockChallengeNodes;

View File

@ -1 +0,0 @@
export default ['a', 'c', 'g'];

View File

@ -4,7 +4,9 @@ const React = require('react');
const gatsby = jest.requireActual('gatsby');
const { clientLocale } = require('../../../config/env.json');
const envData = require('../../../config/env.json');
const { clientLocale } = envData;
module.exports = {
...gatsby,

View File

@ -1,29 +0,0 @@
export default [
{
fields: {
slug: '/super-block-one/block-a'
},
frontmatter: {
block: 'Block A',
title: 'Introduction to Block A'
}
},
{
fields: {
slug: '/super-block-one/block-b'
},
frontmatter: {
block: 'Block B',
title: 'Introduction to Block B'
}
},
{
fields: {
slug: '/super-block-one/block-c'
},
frontmatter: {
block: 'Block C',
title: 'Introduction to Block C'
}
}
];

View File

@ -28,12 +28,14 @@ import { createFlashMessage } from '../components/Flash/redux';
import standardErrorMessage from '../utils/standardErrorMessage';
import reallyWeirdErrorMessage from '../utils/reallyWeirdErrorMessage';
import { langCodes } from '../../../config/i18n/all-langs';
import { clientLocale } from '../../../config/env.json';
import envData from '../../../config/env.json';
import RedirectHome from '../components/RedirectHome';
import { Loader, Spacer } from '../components/helpers';
import { isEmpty } from 'lodash';
const { clientLocale } = envData;
const localeCode = langCodes[clientLocale];
const propTypes = {

View File

@ -5,7 +5,7 @@ import { createSelector } from 'reselect';
import { Grid, Button } from '@freecodecamp/react-bootstrap';
import Helmet from 'react-helmet';
import { apiLocation } from '../../../config/env.json';
import envData from '../../../config/env.json';
import {
signInLoadingSelector,
userSelector,
@ -27,6 +27,8 @@ import Certification from '../components/settings/Certification';
import DangerZone from '../components/settings/DangerZone';
import { User } from '../redux/propTypes';
const { apiLocation } = envData;
const propTypes = {
createFlashMessage: PropTypes.func.isRequired,
isSignedIn: PropTypes.bool.isRequired,

View File

@ -1,10 +1,12 @@
/* global jest, expect */
import React from 'react';
import ShallowRenderer from 'react-test-renderer/shallow';
import { apiLocation } from '../../../config/env.json';
import envData from '../../../config/env.json';
import { ShowSettings } from './ShowSettings';
const { apiLocation } = envData;
describe('<ShowSettings />', () => {
it('renders to the DOM when user is logged in', () => {
const shallow = new ShallowRenderer();

View File

@ -4,11 +4,11 @@ import { Grid, Panel, Button } from '@freecodecamp/react-bootstrap';
import Helmet from 'react-helmet';
import { useTranslation } from 'react-i18next';
import env from '../../../config/env.json';
import envData from '../../../config/env.json';
import FullWidthRow from '../components/helpers/FullWidthRow';
import { Spacer } from '../components/helpers';
const { apiLocation } = env;
const { apiLocation } = envData;
function ShowUnsubscribed({ unsubscribeId }) {
const { t } = useTranslation();

View File

@ -24,7 +24,7 @@ import {
donationUrls,
modalDefaultDonation
} from '../../../../config/donation-settings';
import { stripePublicKey, deploymentEnv } from '../../../../config/env.json';
import envData from '../../../../config/env.json';
import { stripeScriptLoader } from '../../utils/scriptLoaders';
import Spacer from '../helpers/Spacer';
import PaypalButton from './PaypalButton';
@ -44,6 +44,8 @@ import {
import './Donation.css';
const { stripePublicKey, deploymentEnv } = envData;
const numToCommas = num =>
num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');

View File

@ -7,13 +7,14 @@ import { createSelector } from 'reselect';
import PayPalButtonScriptLoader from './PayPalButtonScriptLoader';
import { withTranslation } from 'react-i18next';
import { paypalClientId, deploymentEnv } from '../../../../config/env.json';
import envData from '../../../../config/env.json';
import {
paypalConfigurator,
paypalConfigTypes
} from '../../../../config/donation-settings';
import { signInLoadingSelector, userSelector } from '../../redux';
const { paypalClientId, deploymentEnv } = envData;
export class PaypalButton extends Component {
constructor(props) {
super(props);

View File

@ -6,7 +6,9 @@ import { UniversalNav } from './components/UniversalNav';
import { NavLinks } from './components/NavLinks';
import AuthOrProfile from './components/AuthOrProfile';
import { apiLocation, clientLocale } from '../../../../config/env.json';
import envData from '../../../../config/env.json';
const { apiLocation, clientLocale } = envData;
describe('<UniversalNav />', () => {
const UniversalNavProps = {

View File

@ -6,10 +6,12 @@ import { Button } from '@freecodecamp/react-bootstrap';
import { useTranslation } from 'react-i18next';
import { isSignedInSelector } from '../../../redux';
import { apiLocation, homeLocation } from '../../../../../config/env.json';
import envData from '../../../../../config/env.json';
import './login.css';
const { apiLocation, homeLocation } = envData;
const mapStateToProps = createSelector(isSignedInSelector, isSignedIn => ({
isSignedIn
}));

View File

@ -12,14 +12,12 @@ import {
} from '@fortawesome/free-solid-svg-icons';
import { Link } from '../../helpers';
import { updateUserFlag } from '../../../redux/settings';
import {
clientLocale,
radioLocation,
apiLocation
} from '../../../../../config/env.json';
import envData from '../../../../../config/env.json';
import createLanguageRedirect from '../../createLanguageRedirect';
import createExternalRedirect from '../../createExternalRedirects';
const { clientLocale, radioLocation, apiLocation } = envData;
const {
availableLangs,
i18nextCodes,

View File

@ -1,10 +1,11 @@
import React from 'react';
import { Link, Spacer } from '../../helpers';
import { forumLocation } from '../../../../../config/env.json';
import envData from '../../../../../config/env.json';
import { Trans, useTranslation } from 'react-i18next';
import '../intro.css';
const { forumLocation } = envData;
function IntroDescription() {
const { t } = useTranslation();

View File

@ -8,7 +8,9 @@ import { Link, Spacer } from '../helpers';
import LinkButton from '../../assets/icons/LinkButton';
import './map.css';
import { isAuditedCert } from '../../../../utils/is-audited';
import { curriculumLocale } from '../../../../config/env.json';
import envData from '../../../../config/env.json';
const { curriculumLocale } = envData;
const propTypes = {
currentSuperBlock: PropTypes.string,

View File

@ -1,4 +1,6 @@
import { forumLocation } from '../../../config/env.json';
import envData from '../../../config/env.json';
const { forumLocation } = envData;
const createExternalRedirect = (page, { clientLocale }) => {
const isNotEnglish = clientLocale !== 'english';

View File

@ -1,7 +1,9 @@
import React from 'react';
import PropTypes from 'prop-types';
import { apiLocation } from '../../../../config/env.json';
import envData from '../../../../config/env.json';
const { apiLocation } = envData;
const currentChallengeApi = '/challenges/current-challenge';

View File

@ -1,4 +1,4 @@
export default `
const styles = `
.sprite-container {
height: 100%;
@ -71,3 +71,5 @@ export default `
animation-direction: normal;
}
`;
export default styles;

View File

@ -2,7 +2,7 @@
import React from 'react';
import ShallowRenderer from 'react-test-renderer/shallow';
import { IndexPage } from '../../pages';
import IndexPage from '../../pages';
import mockChallengeNodes from '../../__mocks__/challenge-nodes';
describe('<Landing />', () => {

View File

@ -11,7 +11,9 @@ import HeatMap from './components/HeatMap';
import Certifications from './components/Certifications';
import Portfolio from './components/Portfolio';
import Timeline from './components/TimeLine';
import { apiLocation } from '../../../../config/env.json';
import envData from '../../../../config/env.json';
const { apiLocation } = envData;
const propTypes = {
isSessionUser: PropTypes.bool,

View File

@ -16,8 +16,9 @@ import Link from '../../helpers/Link';
import './camper.css';
import { langCodes } from '../../../../../config/i18n/all-langs';
import { clientLocale } from '../../../../../config/env.json';
import envData from '../../../../../config/env.json';
const { clientLocale } = envData;
const localeCode = langCodes[clientLocale];
const propTypes = {

View File

@ -16,7 +16,9 @@ import '@freecodecamp/react-calendar-heatmap/dist/styles.css';
import './heatmap.css';
import { langCodes } from '../../../../../config/i18n/all-langs';
import { clientLocale } from '../../../../../config/env.json';
import envData from '../../../../../config/env.json';
const { clientLocale } = envData;
const localeCode = langCodes[clientLocale];

View File

@ -25,7 +25,9 @@ import { maybeUrlRE } from '../../../utils';
import CertificationIcon from '../../../assets/icons/CertificationIcon';
import { langCodes } from '../../../../../config/i18n/all-langs';
import { clientLocale } from '../../../../../config/env.json';
import envData from '../../../../../config/env.json';
const { clientLocale } = envData;
const localeCode = langCodes[clientLocale];

View File

@ -15,10 +15,12 @@ import {
toggleSearchDropdown,
updateSearchQuery
} from './redux';
import { algoliaAppId, algoliaAPIKey } from '../../../../config/env.json';
import envData from '../../../../config/env.json';
import { createSelector } from 'reselect';
const { algoliaAppId, algoliaAPIKey } = envData;
const DEBOUNCE_TIME = 100;
// If a key is missing, searches will fail, but the client will still render.

View File

@ -3,6 +3,8 @@ import React from 'react';
import { Router } from '@reach/router';
import { navigate, withPrefix } from 'gatsby';
import toLearnPath from '../utils/to-learn-path';
const Redirect = props => {
if (typeof window !== 'undefined') {
navigate(toLearnPath(props));
@ -21,12 +23,4 @@ const Challenges = () => (
Challenges.displayName = 'Challenges';
export function toLearnPath({ superBlock, block, challenge }) {
let path = withPrefix('/learn');
if (superBlock) path += `/${superBlock}`;
if (block) path += `/${block}`;
if (challenge) path += `/${challenge}`;
return path;
}
export default Challenges;

View File

@ -1,5 +1,5 @@
/* global expect */
import { toLearnPath } from './challenges';
import toLearnPath from '../utils/to-learn-path';
import { withPrefix } from 'gatsby';
describe('toLearnPath', () => {

View File

@ -42,7 +42,7 @@ const mapDispatchToProps = dispatch =>
dispatch
);
export class DonatePage extends Component {
class DonatePage extends Component {
constructor(...props) {
super(...props);
this.state = {

View File

@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import Landing from '../components/landing';
import { AllChallengeNode } from '../redux/propTypes';
export const IndexPage = () => {
const IndexPage = () => {
return <Landing />;
};

View File

@ -47,7 +47,7 @@ const propTypes = {
})
};
export const LearnPage = ({
const LearnPage = ({
isSignedIn,
fetchState: { pending, complete },
user: { name = '', completedChallengeCount = 0 },

View File

@ -9,7 +9,9 @@ import rootReducer from './rootReducer';
import rootSaga from './rootSaga';
import { isBrowser } from '../../utils';
import { environment } from '../../../config/env.json';
import envData from '../../../config/env.json';
const { environment } = envData;
const clientSide = isBrowser();

View File

@ -22,4 +22,6 @@ function* errorHandlerSaga({ payload: error }) {
yield put(createFlashMessage(reportedErrorMessage));
}
export default [takeEvery(errorActionSelector, errorHandlerSaga)];
const errorSagas = [takeEvery(errorActionSelector, errorHandlerSaga)];
export default errorSagas;

View File

@ -4,7 +4,9 @@ import PropTypes from 'prop-types';
import { first } from 'lodash';
import EditorTabs from './EditorTabs';
import ActionRow from './ActionRow';
import { showUpcomingChanges } from '../../../../../config/env.json';
import envData from '../../../../../config/env.json';
const { showUpcomingChanges } = envData;
const propTypes = {
challengeFiles: PropTypes.object,

View File

@ -8,9 +8,11 @@ import { createStructuredSelector } from 'reselect';
import { currentTabSelector, moveToTab } from '../redux';
import { bindActionCreators } from 'redux';
import EditorTabs from './EditorTabs';
import { showUpcomingChanges } from '../../../../../config/env.json';
import envData from '../../../../../config/env.json';
import i18next from 'i18next';
const { showUpcomingChanges } = envData;
const mapStateToProps = createStructuredSelector({
currentTab: currentTabSelector
});

View File

@ -7,10 +7,12 @@ import { Trans, withTranslation } from 'react-i18next';
import { createQuestion, closeModal, isHelpModalOpenSelector } from '../redux';
import { executeGA } from '../../../redux';
import { forumLocation } from '../../../../../config/env.json';
import envData from '../../../../../config/env.json';
import './help-modal.css';
const { forumLocation } = envData;
const mapStateToProps = state => ({ isOpen: isHelpModalOpenSelector(state) });
const mapDispatchToProps = dispatch =>
bindActionCreators(

View File

@ -82,7 +82,7 @@ const mapDispatchToActions = {
updateSolutionFormValues
};
export class BackEnd extends Component {
class BackEnd extends Component {
constructor(props) {
super(props);
this.state = {};

View File

@ -62,7 +62,7 @@ const propTypes = {
updateSolutionFormValues: PropTypes.func.isRequired
};
export class Project extends Component {
class Project extends Component {
constructor() {
super();
this.handleSubmit = this.handleSubmit.bind(this);

View File

@ -17,7 +17,9 @@ import createWorker from '../utils/worker-executor';
// the config files are created during the build, but not before linting
// eslint-disable-next-line import/no-unresolved
import { filename as sassCompile } from '../../../../../config/client/sass-compile';
import sassData from '../../../../../config/client/sass-compile.json';
const { filename: sassCompile } = sassData;
const protectTimeout = 100;
const testProtectTimeout = 1500;

View File

@ -8,7 +8,9 @@ import {
projectFormValuesSelector
} from '../redux';
import { tap, mapTo } from 'rxjs/operators';
import { forumLocation } from '../../../../../config/env.json';
import envData from '../../../../../config/env.json';
const { forumLocation } = envData;
function filesToMarkdown(files = {}) {
const moreThenOneFile = Object.keys(files).length > 1;

View File

@ -10,9 +10,12 @@ import {
// the config files are created during the build, but not before linting
// eslint-disable-next-line import/no-unresolved
import { filename as runner } from '../../../../../config/client/frame-runner';
import frameRunnerData from '../../../../../config/client/frame-runner.json';
// eslint-disable-next-line import/no-unresolved
import { filename as testEvaluator } from '../../../../../config/client/test-evaluator';
import testEvaluatorData from '../../../../../config/client/test-evaluator.json';
const { filename: runner } = frameRunnerData;
const { filename: testEvaluator } = testEvaluatorData;
const frameRunner = [
{

View File

@ -1,4 +1,6 @@
import { forumLocation } from '../../../../../config/env.json';
import envData from '../../../../../config/env.json';
const { forumLocation } = envData;
export function getGuideUrl({ forumTopicId, title = '' }) {
title = encodeURIComponent(title);

View File

@ -1,6 +1,8 @@
/* global expect */
import { forumLocation } from '../../../../../config/env.json';
import envData from '../../../../../config/env.json';
const { forumLocation } = envData;
const { getGuideUrl } = require('./');

View File

@ -68,7 +68,7 @@ const propTypes = {
};
// Component
export class Project extends Component {
class Project extends Component {
constructor(props) {
super(props);
this.state = {

View File

@ -71,7 +71,7 @@ const mapDispatchToProps = dispatch =>
dispatch
);
export class SuperBlockIntroductionPage extends Component {
class SuperBlockIntroductionPage extends Component {
componentDidMount() {
this.initializeExpandedState();

View File

@ -13,9 +13,11 @@ import Caret from '../../../assets/icons/Caret';
import GreenPass from '../../../assets/icons/GreenPass';
import GreenNotCompleted from '../../../assets/icons/GreenNotCompleted';
import { isAuditedCert } from '../../../../../utils/is-audited';
import { curriculumLocale } from '../../../../../config/env.json';
import envData from '../../../../../config/env.json';
import { Link } from '../../../components/helpers/';
const { curriculumLocale } = envData;
const mapStateToProps = (state, ownProps) => {
const expandedSelector = makeExpandedBlockSelector(ownProps.blockDashedName);

View File

@ -1,8 +1,10 @@
import { apiLocation } from '../../../config/env.json';
import envData from '../../../config/env.json';
import axios from 'axios';
import Tokens from 'csrf';
import cookies from 'browser-cookies';
const { apiLocation } = envData;
const base = apiLocation;
const tokens = new Tokens();

View File

@ -1,4 +1,6 @@
import { clientLocale } from '../../../config/env.json';
import envData from '../../../config/env.json';
const { clientLocale } = envData;
const algoliaIndices = {
english: {

View File

@ -27,9 +27,11 @@ const removeWhiteSpace = (str = '') => {
return str.replace(/\s/g, '');
};
export default {
const curriculumHelpers = {
removeHtmlComments,
removeCssComments,
removeJSComments,
removeWhiteSpace
};
export default curriculumHelpers;

View File

@ -1,4 +1,6 @@
export default {
const reallyWeirdErrorMessage = {
type: 'danger',
message: 'flash.really-weird'
};
export default reallyWeirdErrorMessage;

View File

@ -1,4 +1,6 @@
export default {
const reportedErrorMessage = {
type: 'danger',
message: 'flash.not-right'
};
export default reportedErrorMessage;

View File

@ -1,4 +1,6 @@
export default {
const standardErrorMessage = {
type: 'danger',
message: 'flash.went-wrong'
};
export default standardErrorMessage;

View File

@ -0,0 +1,9 @@
import { withPrefix } from 'gatsby';
export default function toLearnPath({ superBlock, block, challenge }) {
let path = withPrefix('/learn');
if (superBlock) path += `/${superBlock}`;
if (block) path += `/${block}`;
if (challenge) path += `/${challenge}`;
return path;
}

View File

@ -6,7 +6,9 @@ const {
challengesDir,
getChallengesDirForLang
} = require('../../curriculum/getChallenges');
const { curriculumLocale } = require('../../config/env.json');
const envData = require('../../config/env.json');
const { curriculumLocale } = envData;
exports.localeChallengesRootDir = getChallengesDirForLang(curriculumLocale);

View File

@ -1,4 +1,5 @@
const path = require('path');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { writeFileSync } = require('fs');
@ -60,7 +61,21 @@ module.exports = (env = {}) => {
plugins: [
new CopyWebpackPlugin([
{ from: 'node_modules/sass.js/dist/sass.sync.js' }
])
]
]),
new webpack.ProvidePlugin({
process: 'process/browser'
}),
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer']
})
],
resolve: {
fallback: {
buffer: require.resolve('buffer'),
util: false,
stream: false,
process: require.resolve('process/browser')
}
}
};
};

View File

@ -61,7 +61,8 @@ const TRANSLATABLE_COMMENTS = getTranslatableComments(
// the config files are created during the build, but not before linting
// eslint-disable-next-line import/no-unresolved
const testEvaluator = require('../../config/client/test-evaluator').filename;
const testEvaluator = require('../../config/client/test-evaluator.json')
.filename;
const { inspect } = require('util');
const commentExtractors = {