Skip to content

Commit

Permalink
(MAJOR) Massive folder structure refactoring (`v2-mst-aptd-gcms-lcz-s…
Browse files Browse the repository at this point in the history
…ty`), using modular approach and module path aliases (#275)
  • Loading branch information
Vadorequest authored Jan 20, 2021
1 parent 01dd3df commit 13bee76
Show file tree
Hide file tree
Showing 343 changed files with 3,200 additions and 1,908 deletions.
4 changes: 2 additions & 2 deletions .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ checks:
method-complexity:
enabled: true
config:
threshold: 10
threshold: 25 # 10 by default
method-count:
enabled: true
config:
threshold: 20
method-lines:
enabled: true
config:
threshold: 200 # 25 by default
threshold: 300 # 25 by default
nested-control-flow:
enabled: true
config:
Expand Down
28 changes: 28 additions & 0 deletions .storybook/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/app/*": [
"../src/app/*"
],
"@/common/*": [
"../src/common/*"
],
"@/components/*": [
"../src/common/components/*"
],
"@/utils/*": [
"../src/common/utils/*"
],
"@/layouts/*": [
"../src/layouts/*"
],
"@/modules/*": [
"../src/modules/*"
],
"@/pages/*": [
"../src/pages/*"
]
}
}
}
18 changes: 18 additions & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,24 @@ module.exports = {
'@emotion/core': toPath('node_modules/@emotion/react'),
'@emotion/styled': toPath('node_modules/@emotion/styled'),
'emotion-theming': toPath('node_modules/@emotion/react'),

/**
* Map our module path aliases, so that Storybook can understand modules loaded using "@/common" and load the proper file.
* Required, or Storybook will fail to import dependencies from Stories.
*
* XXX The below list must match `tsconfig.json:compilerOptions.paths`, so the Next.js app and Storybook resolve all aliases the same way.
* The paths mapping must also match the `jsconfig.json:compilerOptions.paths` file, which is necessary for WebStorm to understand them for .js files.
*
* @see https://nextjs.org/docs/advanced-features/module-path-aliases
* @see https://intellij-support.jetbrains.com/hc/en-us/community/posts/360003361399/comments/360002636080
*/
"@/app": path.resolve(__dirname, "../src/app"),
"@/common": path.resolve(__dirname, "../src/common"),
"@/components": path.resolve(__dirname, "../src/common/components"),
"@/utils": path.resolve(__dirname, "../src/common/utils"),
"@/layouts": path.resolve(__dirname, "../src/layouts"),
"@/modules": path.resolve(__dirname, "../src/modules"),
"@/pages": path.resolve(__dirname, "../src/pages"),
},
},
};
Expand Down
34 changes: 17 additions & 17 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ import find from 'lodash.find';
import React from 'react';
import { withNextRouter } from 'storybook-addon-next-router';
import { withPerformance } from 'storybook-addon-performance';
import '../src/components/appBootstrap/MultiversalGlobalExternalStyles'; // Import the same 3rd party libraries global styles as the pages/_app.tsx (for UI consistency)
import MultiversalGlobalStyles from '../src/components/appBootstrap/MultiversalGlobalStyles';
import { defaultLocale, getLangFromLocale, supportedLocales } from '../src/i18nConfig';
import amplitudeContext from '../src/stores/amplitudeContext';
import customerContext from '../src/stores/customerContext';
import { cypressContext } from '../src/stores/cypressContext';
import datasetContext from '../src/stores/datasetContext';
import i18nContext from '../src/stores/i18nContext';
import previewModeContext from '../src/stores/previewModeContext';
import quickPreviewContext from '../src/stores/quickPreviewContext';
import userConsentContext from '../src/stores/userConsentContext';
import { userSessionContext } from '../src/stores/userSessionContext';
import { getAmplitudeInstance } from '../src/utils/analytics/amplitude';
import '../src/utils/app/ignoreNoisyWarningsHacks';
import { initCustomerTheme } from '../src/utils/data/theme';
import i18nextLocize from '../src/utils/i18n/i18nextLocize';
import '../src/utils/icons/font-awesome';
import '@/app/components/MultiversalGlobalExternalStyles'; // Import the same 3rd party libraries global styles as the pages/_app.tsx (for UI consistency)
import MultiversalGlobalStyles from '@/app/components/MultiversalGlobalStyles';
import { defaultLocale, getLangFromLocale, supportedLocales } from '@/modules/core/i18n/i18nConfig';
import amplitudeContext from '@/modules/core/amplitude/context/amplitudeContext';
import customerContext from '@/modules/core/data/contexts/customerContext';
import { cypressContext } from '@/modules/core/testing/contexts/cypressContext';
import datasetContext from '@/modules/core/data/contexts/datasetContext';
import i18nContext from '@/modules/core/i18n/contexts/i18nContext';
import previewModeContext from '@/modules/core/previewMode/contexts/previewModeContext';
import quickPreviewContext from '@/modules/core/quickPreview/contexts/quickPreviewContext';
import userConsentContext from '@/modules/core/userConsent/contexts/userConsentContext';
import { userSessionContext } from '@/modules/core/userSession/userSessionContext';
import { getAmplitudeInstance } from '@/modules/core/amplitude/amplitude';
import '@/common/utils/ignoreNoisyWarningsHacks';
import { initCustomerTheme } from '@/modules/core/theming/theme';
import i18nextLocize from '@/modules/core/i18n/i18nextLocize';
import '@/modules/core/fontAwesome/fontAwesome';
import dataset from './mock/sb-dataset';

// Loads translations from local file cache (Locize)
Expand Down
16 changes: 16 additions & 0 deletions cypress/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,19 @@ The files `cypress/config-*` are used for different purposes.
_[Source](https://docs.cypress.io/faq/questions/using-cypress-faq.html#What-are-your-best-practices-for-organizing-tests)_

[Cypress releases "Real World App" (RWA) - Blog post](https://www.cypress.io/blog/2020/06/11/introducing-the-cypress-real-world-app/)

## Module path alias mapping

We use module alias path mappings, to avoid using relative paths (e.g: `../../src/common`) but absolute paths (AKA "module paths") instead (e.g: `@/common`).

Although it's simpler to use, it's harder to configure because it affects several configuration files:
- The paths mapping in `tsconfig.json:compilerOptions.paths` must match those in `../tsconfig.json:compilerOptions.paths`
- They must also match those in `jsconfig.json` file, which is necessary for WebStorm to understand them for .js files.

If the module path mappings aren't properly set everywhere, it won't work.

> You can still use relative paths.
Reference:
- See [Next.js "Module path aliases" documentation](https://nextjs.org/docs/advanced-features/module-path-aliases)
- See [WebStorm issue](https://intellij-support.jetbrains.com/hc/en-us/community/posts/360003361399/comments/360002636080)
4 changes: 2 additions & 2 deletions cypress/integration/app/_sanity/2-customer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Customer } from '../../../../src/types/data/Customer';
import { CYPRESS_WINDOW_NS } from '../../../../src/utils/testing/cypress';
import { Customer } from '@/modules/core/data/types/Customer';
import { CYPRESS_WINDOW_NS } from '@/modules/core/testing/cypress';

describe('Sanity checks > Browser data', () => {
/**
Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/app/common/footer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Customer } from '../../../../src/types/data/Customer';
import { Customer } from '@/modules/core/data/types/Customer';

const baseUrl = Cypress.config().baseUrl;

Expand Down
2 changes: 1 addition & 1 deletion cypress/integration/app/common/nav.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Customer } from '../../../../src/types/data/Customer';
import { Customer } from '@/modules/core/data/types/Customer';

const baseUrl = Cypress.config().baseUrl;

Expand Down
28 changes: 28 additions & 0 deletions cypress/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/app/*": [
"../src/app/*"
],
"@/common/*": [
"../src/common/*"
],
"@/components/*": [
"../src/common/components/*"
],
"@/utils/*": [
"../src/common/utils/*"
],
"@/layouts/*": [
"../src/layouts/*"
],
"@/modules/*": [
"../src/modules/*"
],
"@/pages/*": [
"../src/pages/*"
]
}
}
}
2 changes: 1 addition & 1 deletion cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// https://on.cypress.io/custom-commands
// ***********************************************

import { CYPRESS_WINDOW_NS } from '../../src/utils/testing/cypress';
import { CYPRESS_WINDOW_NS } from '@/modules/core/testing/cypress';

/**
* Prepare DOM aliases by fetching the customer data from the browser window and aliasing them for later use.
Expand Down
23 changes: 23 additions & 0 deletions cypress/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,29 @@
"exclude": [],
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/app/*": [
"../src/app/*"
],
"@/common/*": [
"../src/common/*"
],
"@/components/*": [
"../src/common/components/*"
],
"@/utils/*": [
"../src/common/utils/*"
],
"@/layouts/*": [
"../src/layouts/*"
],
"@/modules/*": [
"../src/modules/*"
],
"@/pages/*": [
"../src/pages/*"
]
},
"types": [
"cypress"
],
Expand Down
19 changes: 19 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,25 @@ module.exports = {
tsconfig: 'tsconfig.jest.json',
},
},

/**
* Map our module path aliases, so that Jest can understand modules loaded using "@/common" and load the proper file.
* Required, or Jest will fail to import dependencies from tests.
*
* XXX The below list must match `tsconfig.json:compilerOptions.paths`, so the Next.js app and Jest resolve all aliases the same way.
*
* @see https://nextjs.org/docs/advanced-features/module-path-aliases
* @see https://github.com/ilearnio/module-alias/issues/46#issuecomment-546154015
*/
moduleNameMapper: {
'^@/app/(.*)$': '<rootDir>/src/app/$1',
'^@/common/(.*)$': '<rootDir>/src/common/$1',
'^@/components/(.*)$': '<rootDir>/src/common/components/$1',
'^@/utils/(.*)$': '<rootDir>/src/common/utils/$1',
'^@/layouts/(.*)$': '<rootDir>/src/layouts/$1',
'^@/modules/(.*)$': '<rootDir>/src/modules/$1',
'^@/pages/(.*)$': '<rootDir>/src/pages/$1',
},
modulePathIgnorePatterns: [
'.next/',
'cypress',
Expand Down
8 changes: 7 additions & 1 deletion jest.extends.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import { toMatchOneOf, toMatchShapeOf } from 'jest-to-match-shape-of'; // See https://www.npmjs.com/package/jest-to-match-shape-of
// XXX All expect.extend() utilities loaded here will be available for all tests, they also might need to be declared in jest.d.ts
import {
toMatchOneOf,
toMatchShapeOf,
} from 'jest-to-match-shape-of'; // See https://www.npmjs.com/package/jest-to-match-shape-of
// Import utilities that extend Jest "expect" function by themselves
import '@/modules/core/testing/toContainObject';

// Extend Jest "expect" function
expect.extend({
Expand Down
18 changes: 1 addition & 17 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const bundleAnalyzer = require('@next/bundle-analyzer');
const nextSourceMaps = require('@zeit/next-source-maps');
const packageJson = require('./package');
const i18nConfig = require('./src/i18nConfig');
const i18nConfig = require('./src/modules/core/i18n/i18nConfig');

const withSourceMaps = nextSourceMaps();
const withBundleAnalyzer = bundleAnalyzer({ // Run with "yarn analyse:bundle" - See https://www.npmjs.com/package/@next/bundle-analyzer
Expand Down Expand Up @@ -102,22 +102,6 @@ module.exports = withBundleAnalyzer(withSourceMaps({
async headers() {
const headers = [];

// XXX Forbid usage in iframes from external 3rd parties, for non-production site
// This is meant to avoid customers using the preview in their production website, which would incur uncontrolled costs on our end
// Also, our preview env cannot scale considering each request send many airtable API calls and those are rate limited and out of our control
if (process.env.NEXT_PUBLIC_APP_STAGE !== 'production') {
headers.push({
source: '/(.*?)', // Match all paths, including "/" - See https://github.com/vercel/next.js/discussions/17991#discussioncomment-112028
// source: '/:path*', // Match all paths, excluding "/"
headers: [
{
key: 'Content-Security-Policy',
value: 'frame-ancestors *.stacker.app',
},
],
});
}

console.info('Using headers:', JSON.stringify(headers, null, 2));

return headers;
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"analyse:bundle:development": "ANALYZE_BUNDLE=true yarn start",
"analyse:bundle:production": ". ./scripts/populate-git-env.sh && ANALYZE_BUNDLE=true next build",
"analyse:unused": "next-unused",
"svg": "npx svgr -d src/svg src/svg --ext tsx --template src/utils/svg/svgTemplate.ts",
"svg": "npx svgr -d svg-to-react svg-to-react --ext tsx --template svg-to-react/svgTemplate.ts",
"deploy": "yarn deploy:customer1",
"deploy:all": "yarn deploy:customer1 && yarn deploy:customer2",
"deploy:all:production": "yarn deploy:customer1:production && yarn deploy:customer2:production",
Expand Down Expand Up @@ -81,6 +81,10 @@
"codemod:update-react-imports": "npx react-codemod update-react-imports src/",
"codemod:name-default-component": "npx @next/codemod name-default-component src/",
"codemod:withamp-to-config": "npx @next/codemod withamp-to-config src/",
"codemod:module-path-aliases": "yarn codemod:module-path-aliases:src && yarn codemod:module-path-aliases:cypress && yarn codemod:module-path-aliases:sb",
"codemod:module-path-aliases:src": "npx relative-to-alias --src 'src' --alias '@/app' --alias-path './src/app' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src 'src' --alias '@/common' --alias-path './src/common' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src 'src' --alias '@/components' --alias-path './src/common/components' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src 'src' --alias '@/utils' --alias-path './src/common/utils' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src 'src' --alias '@/layouts' --alias-path './src/layouts' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src 'src' --alias '@/modules' --alias-path './src/modules' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src 'src' --alias '@/pages' --alias-path './src/pages' --extensions 'js,ts,tsx' --language 'typescript'",
"codemod:module-path-aliases:cypress": "npx relative-to-alias --src 'cypress' --alias '@/app' --alias-path './src/app' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src 'cypress' --alias '@/common' --alias-path './src/common' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src 'cypress' --alias '@/components' --alias-path './src/common/components' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src 'cypress' --alias '@/utils' --alias-path './src/common/utils' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src 'cypress' --alias '@/layouts' --alias-path './src/layouts' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src 'cypress' --alias '@/modules' --alias-path './src/modules' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src 'cypress' --alias '@/pages' --alias-path './src/pages' --extensions 'js,ts,tsx' --language 'typescript'",
"codemod:module-path-aliases:sb": "npx relative-to-alias --src '.storybook' --alias '@/app' --alias-path './src/app' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src '.storybook' --alias '@/common' --alias-path './src/common' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src '.storybook' --alias '@/components' --alias-path './src/common/components' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src '.storybook' --alias '@/utils' --alias-path './src/common/utils' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src '.storybook' --alias '@/layouts' --alias-path './src/layouts' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src '.storybook' --alias '@/modules' --alias-path './src/modules' --extensions 'js,ts,tsx' --language 'typescript' && npx relative-to-alias --src '.storybook' --alias '@/pages' --alias-path './src/pages' --extensions 'js,ts,tsx' --language 'typescript'",
"security:audit": "yarn audit",
"packages:upgrade": "yarn upgrade-interactive --latest"
},
Expand Down Expand Up @@ -216,6 +220,7 @@
"@types/lodash.xorby": "4.7.6",
"@types/popper.js": "1.11.0",
"@types/react": "17.0.0",
"@types/react-dom": "17.0.0",
"@types/react-test-renderer": "17.0.0",
"@types/reactstrap": "8.7.2",
"@types/uuid": "8.3.0",
Expand Down Expand Up @@ -248,6 +253,7 @@
"node-mocks-http": "1.10.0",
"open-cli": "6.0.1",
"react-test-renderer": "17.0.1",
"relative-to-alias": "2.0.1",
"storybook-addon-designs": "5.4.3",
"storybook-addon-next-router": "2.0.3",
"storybook-addon-performance": "0.14.0",
Expand Down
Loading

1 comment on commit 13bee76

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.