Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,936 changes: 1,670 additions & 1,266 deletions .github/actions/javascript/authorChecklist/index.js

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ index.js
# We need to modify the import here specifically, hence we disable prettier to get rid of the sorted imports
src/libs/E2E/reactNativeLaunchingTest.ts

# Disable prettier in 3rd-party snippets
web/snippets/**

# Automatically generated files
src/libs/SearchParser/searchParser.js
src/libs/SearchParser/autocompleteParser.js
Expand Down
4 changes: 4 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ module.exports = {
printWidth: 190,
singleAttributePerLine: true,
plugins: [require.resolve('@trivago/prettier-plugin-sort-imports')],
// Parser plugins to support TypeScript and JSX
importOrderParserPlugins: ['typescript', 'jsx'],
// Use modern 'with' syntax for import assertions
importOrderImportAttributesKeyword: 'with',
/** `importOrder` should be defined in an alphabetical order. */
importOrder: [
'@assets/(.*)$',
Expand Down
2 changes: 1 addition & 1 deletion .storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type {StorybookConfig} from 'storybook/internal/types';

const main: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: ['@storybook/addon-essentials', '@storybook/addon-a11y', '@storybook/addon-webpack5-compiler-babel'],
addons: ['@storybook/addon-a11y', '@storybook/addon-webpack5-compiler-babel', '@storybook/addon-docs'],
staticDirs: ['./public', {from: '../assets/css', to: 'css'}, {from: '../assets/fonts/web', to: 'fonts'}],
core: {},

Expand Down
2 changes: 1 addition & 1 deletion .storybook/manager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {addons} from '@storybook/manager-api';
import {addons} from 'storybook/manager-api';
import theme from './theme';

addons.setConfig({
Expand Down
4 changes: 2 additions & 2 deletions .storybook/theme.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {ThemeVars} from '@storybook/theming';
import {create} from '@storybook/theming/create';
import type {ThemeVars} from 'storybook/theming';
import {create} from 'storybook/theming/create';
// eslint-disable-next-line @dword-design/import-alias/prefer-alias
import colors from '../src/styles/theme/colors';

Expand Down
42 changes: 22 additions & 20 deletions .storybook/webpack.config.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
/* eslint-disable no-underscore-dangle */

/* eslint-disable no-param-reassign */

/* eslint-disable @typescript-eslint/naming-convention */
import type Environment from 'config/webpack/types';
import dotenv from 'dotenv';
import {createRequire} from 'module';
import path from 'path';
import {DefinePlugin} from 'webpack';
import {fileURLToPath} from 'url';
import webpack from 'webpack';
import type {Configuration, RuleSetRule} from 'webpack';
import webpackMockPaths from './webpackMockPaths';
// Storybook 10 loads TS files directly and requires .ts extension for ESM imports
// @ts-expect-error -- Can't use .ts extensions without allowImportingTsExtensions in tsconfig
// eslint-disable-next-line import/extensions
import webpackMockPaths from './webpackMockPaths.ts';

const require = createRequire(import.meta.url);
const filename = fileURLToPath(import.meta.url);
const dirname = path.dirname(filename);

type CustomWebpackConfig = {
resolve: {
Expand All @@ -20,12 +26,6 @@ type CustomWebpackConfig = {
};
};

type CustomWebpackFunction = ({file, platform}: Environment) => CustomWebpackConfig;

type WebpackModule = {
default: CustomWebpackFunction;
};

let envFile: string;
switch (process.env.ENV) {
case 'production':
Expand All @@ -38,12 +38,14 @@ switch (process.env.ENV) {
envFile = '.env';
}

const env = dotenv.config({path: path.resolve(__dirname, `../${envFile}`)});
const customFunction = require<WebpackModule>('../config/webpack/webpack.common').default;

const custom: CustomWebpackConfig = customFunction({file: envFile});
const env = dotenv.config({path: path.resolve(dirname, `../${envFile}`)});

const webpackConfig = ({config}: {config: Configuration}) => {
const webpackConfig = async ({config}: {config: Configuration}) => {
// Storybook 10 loads TS files directly and requires .ts extension for ESM imports
// @ts-expect-error -- Can't use .ts extensions without allowImportingTsExtensions in tsconfig
// eslint-disable-next-line import/extensions
const {default: customFunction} = await import('../config/webpack/webpack.common.ts');
const custom = customFunction({file: envFile}) as CustomWebpackConfig;
if (!config.resolve) {
config.resolve = {};
}
Expand All @@ -64,9 +66,9 @@ const webpackConfig = ({config}: {config: Configuration}) => {
config.ignoreWarnings = [{module: new RegExp('node_modules/lottie-react-native/lib/module/LottieView/index.web.js')}];

// Necessary to overwrite the values in the existing DefinePlugin hardcoded to the Config staging values
const definePluginIndex = config.plugins.findIndex((plugin) => plugin instanceof DefinePlugin);
if (definePluginIndex !== -1 && config.plugins.at(definePluginIndex) instanceof DefinePlugin) {
const definePlugin = config.plugins.at(definePluginIndex) as DefinePlugin;
const definePluginIndex = config.plugins.findIndex((plugin) => plugin instanceof webpack.DefinePlugin);
if (definePluginIndex !== -1 && config.plugins.at(definePluginIndex) instanceof webpack.DefinePlugin) {
const definePlugin = config.plugins.at(definePluginIndex) as webpack.DefinePlugin;
if (definePlugin.definitions) {
definePlugin.definitions.__REACT_WEB_CONFIG__ = JSON.stringify(env);
}
Expand Down Expand Up @@ -98,7 +100,7 @@ const webpackConfig = ({config}: {config: Configuration}) => {
});

config.plugins.push(
new DefinePlugin({
new webpack.DefinePlugin({
__DEV__: process.env.NODE_ENV === 'development',
}),
);
Expand Down
8 changes: 6 additions & 2 deletions .storybook/webpackMockPaths.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import path from 'path';
import {fileURLToPath} from 'url';

const filename = fileURLToPath(import.meta.url);
const dirname = path.dirname(filename);

/* eslint-disable @typescript-eslint/naming-convention */
export default {
'react-native-config': 'react-web-config',
'react-native$': 'react-native-web',
'@react-native-community/netinfo': path.resolve(__dirname, '../__mocks__/@react-native-community/netinfo.ts'),
'@react-navigation/native': path.resolve(__dirname, '../__mocks__/@react-navigation/native'),
'@react-native-community/netinfo': path.resolve(dirname, '../__mocks__/@react-native-community/netinfo.ts'),
'@react-navigation/native': path.resolve(dirname, '../__mocks__/@react-navigation/native'),
};
/* eslint-enable @typescript-eslint/naming-convention */
1 change: 0 additions & 1 deletion __mocks__/react-native-onyx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
* We are disabling the lint rule that doesn't allow the usage of Onyx.connect outside libs
* because the intent of this file is to mock the usage of react-native-onyx so we will have to mock the connect function
*/

/* eslint-disable rulesdir/prefer-onyx-connect-in-libs */
import type {ConnectOptions, OnyxKey} from 'react-native-onyx';
// eslint-disable-next-line no-restricted-imports
Expand Down
4 changes: 3 additions & 1 deletion config/webpack/CustomVersionFilePlugin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import fs from 'fs';
import path from 'path';
import type {Compiler} from 'webpack';
import {version as APP_VERSION} from '../../package.json';
import packageJson from '../../package.json' with {type: 'json'};

const APP_VERSION = packageJson.version;

/**
* Custom webpack plugin that writes the app version (from package.json) and the webpack hash to './version.json'
Expand Down
79 changes: 36 additions & 43 deletions config/webpack/webpack.common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,24 @@ import dotenv from 'dotenv';
import fs from 'fs';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import {createRequire} from 'module';
import path from 'path';
import TerserPlugin from 'terser-webpack-plugin';
import type {Class} from 'type-fest';
import {fileURLToPath} from 'url';
import webpack from 'webpack';
import type {Configuration, WebpackPluginInstance} from 'webpack';
import {DefinePlugin, EnvironmentPlugin, IgnorePlugin, ProvidePlugin} from 'webpack';
import {BundleAnalyzerPlugin} from 'webpack-bundle-analyzer';
import CustomVersionFilePlugin from './CustomVersionFilePlugin';
import type Environment from './types';
// Storybook 10 loads TS files directly and requires .ts extension for ESM imports
// @ts-expect-error -- Can't use .ts extensions without allowImportingTsExtensions in tsconfig
// eslint-disable-next-line import/extensions
import CustomVersionFilePlugin from './CustomVersionFilePlugin.ts';
// eslint-disable-next-line import/extensions
import type Environment from './types.ts';

const require = createRequire(import.meta.url);
const filename = fileURLToPath(import.meta.url);
const dirname = path.dirname(filename);

dotenv.config();

Expand Down Expand Up @@ -77,6 +87,7 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment):
console.debug(`[SENTRY ${platform.toUpperCase()}] Assets Path: ${platform === 'desktop' ? './desktop/dist/www/**/*.{js,map}' : './dist/**/*.{js,map}'}`);
}

/* eslint-disable @typescript-eslint/naming-convention */
return {
mode: isDevelopment ? 'development' : 'production',
devtool: 'source-map',
Expand All @@ -86,7 +97,7 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment):
output: {
// Use simple filenames in development to prevent memory leaks from contenthash changes
filename: isDevelopment ? '[name].bundle.js' : '[name]-[contenthash].bundle.js',
path: path.resolve(__dirname, '../../dist'),
path: path.resolve(dirname, '../../dist'),
publicPath: '/',
},
stats: {
Expand All @@ -99,7 +110,7 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment):
new HtmlWebpackPlugin({
template: 'web/index.html',
filename: 'index.html',
splashLogo: fs.readFileSync(path.resolve(__dirname, `../../assets/images/new-expensify${mapEnvironmentToLogoSuffix(file)}.svg`), 'utf-8'),
splashLogo: fs.readFileSync(path.resolve(dirname, `../../assets/images/new-expensify${mapEnvironmentToLogoSuffix(file)}.svg`), 'utf-8'),
isWeb: platform === 'web',
isProduction: file === '.env.production',
isStaging: file === '.env.staging',
Expand All @@ -117,7 +128,7 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment):
fileWhitelist: [/\.lottie$/],
include: 'allAssets',
}),
new ProvidePlugin({
new webpack.ProvidePlugin({
process: 'process/browser',
}),

Expand Down Expand Up @@ -148,31 +159,28 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment):
{from: 'web/snippets/gib.js', to: 'gib.js'},
],
}),
new EnvironmentPlugin({JEST_WORKER_ID: ''}),
new IgnorePlugin({
new webpack.EnvironmentPlugin({JEST_WORKER_ID: ''}),
new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
}),
...(file === '.env.production' || file === '.env.staging'
? [
new IgnorePlugin({
new webpack.IgnorePlugin({
resourceRegExp: /@welldone-software\/why-did-you-render/,
}),
]
: []),
...(platform === 'web' ? [new CustomVersionFilePlugin()] : []),
new DefinePlugin({
new webpack.DefinePlugin({
...(platform === 'desktop' ? {} : {process: {env: {}}}),
// Define EXPO_OS for web platform to fix expo-modules-core warning
// eslint-disable-next-line @typescript-eslint/naming-convention
'process.env.EXPO_OS': JSON.stringify('web'),
// eslint-disable-next-line @typescript-eslint/naming-convention
__REACT_WEB_CONFIG__: JSON.stringify(dotenv.config({path: file}).parsed),

// React Native JavaScript environment requires the global __DEV__ variable to be accessible.
// react-native-render-html uses variable to log exclusively during development.
// See https://reactnative.dev/docs/javascript-environment
// eslint-disable-next-line @typescript-eslint/naming-convention
__DEV__: /staging|prod|adhoc/.test(file) === false,
}),
...(isDevelopment ? [] : [new MiniCssExtractPlugin()]),
Expand Down Expand Up @@ -289,44 +297,30 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment):
resolve: {
fullySpecified: false,
},
include: [path.resolve(__dirname, '../../node_modules/react-native-tab-view/lib/module/TabView.js')],
include: [path.resolve(dirname, '../../node_modules/react-native-tab-view/lib/module/TabView.js')],
},
],
},
resolve: {
alias: {
lodash: 'lodash-es',
// eslint-disable-next-line @typescript-eslint/naming-convention
'react-native-config': 'react-web-config',
// eslint-disable-next-line @typescript-eslint/naming-convention
'react-native$': 'react-native-web',
// Module alias for web & desktop
// https://webpack.js.org/configuration/resolve/#resolvealias
// eslint-disable-next-line @typescript-eslint/naming-convention
'@assets': path.resolve(__dirname, '../../assets'),
// eslint-disable-next-line @typescript-eslint/naming-convention
'@components': path.resolve(__dirname, '../../src/components/'),
// eslint-disable-next-line @typescript-eslint/naming-convention
'@hooks': path.resolve(__dirname, '../../src/hooks/'),
// eslint-disable-next-line @typescript-eslint/naming-convention
'@libs': path.resolve(__dirname, '../../src/libs/'),
// eslint-disable-next-line @typescript-eslint/naming-convention
'@navigation': path.resolve(__dirname, '../../src/libs/Navigation/'),
// eslint-disable-next-line @typescript-eslint/naming-convention
'@pages': path.resolve(__dirname, '../../src/pages/'),
// eslint-disable-next-line @typescript-eslint/naming-convention
'@prompts': path.resolve(__dirname, '../../prompts'),
// eslint-disable-next-line @typescript-eslint/naming-convention
'@styles': path.resolve(__dirname, '../../src/styles/'),
'@assets': path.resolve(dirname, '../../assets'),
'@components': path.resolve(dirname, '../../src/components/'),
'@hooks': path.resolve(dirname, '../../src/hooks/'),
'@libs': path.resolve(dirname, '../../src/libs/'),
'@navigation': path.resolve(dirname, '../../src/libs/Navigation/'),
'@pages': path.resolve(dirname, '../../src/pages/'),
'@prompts': path.resolve(dirname, '../../prompts'),
'@styles': path.resolve(dirname, '../../src/styles/'),
// This path is provide alias for files like `ONYXKEYS` and `CONST`.
// eslint-disable-next-line @typescript-eslint/naming-convention
'@src': path.resolve(__dirname, '../../src/'),
// eslint-disable-next-line @typescript-eslint/naming-convention
'@userActions': path.resolve(__dirname, '../../src/libs/actions/'),
// eslint-disable-next-line @typescript-eslint/naming-convention
'@desktop': path.resolve(__dirname, '../../desktop'),
// eslint-disable-next-line @typescript-eslint/naming-convention
'@selectors': path.resolve(__dirname, '../../src/selectors/'),
'@src': path.resolve(dirname, '../../src/'),
'@userActions': path.resolve(dirname, '../../src/libs/actions/'),
'@desktop': path.resolve(dirname, '../../desktop'),
'@selectors': path.resolve(dirname, '../../src/selectors/'),
},

// React Native libraries may have web-specific module implementations that appear with the extension `.web.js`
Expand All @@ -350,7 +344,6 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment):
'.tsx',
],
fallback: {
// eslint-disable-next-line @typescript-eslint/naming-convention
'process/browser': require.resolve('process/browser'),
crypto: false,
},
Expand All @@ -365,10 +358,8 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment):
compress: {
passes: 2,
},
// eslint-disable-next-line @typescript-eslint/naming-convention
keep_classnames: /ImageManipulator|ImageModule/,
mangle: {
// eslint-disable-next-line @typescript-eslint/naming-convention
keep_fnames: true,
},
},
Expand Down Expand Up @@ -422,4 +413,6 @@ const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment):
};
};

/* eslint-enable @typescript-eslint/naming-convention */

export default getCommonConfiguration;
3 changes: 0 additions & 3 deletions desktop/electron-serve.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/* eslint-disable @typescript-eslint/naming-convention */

/* eslint-disable @typescript-eslint/no-misused-promises */

/* eslint-disable rulesdir/no-negated-variables */

/**
* This file is a modified version of the electron-serve package.
* We keep the same interface, but instead of file protocol we use buffer protocol (with support of JS self profiling).
Expand Down
Loading
Loading