Repository navigation
[No QA] [TS migration] Migrate 'Config' files to TypeScript #37718
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7b98ae0
630b8ae
1dbe373
c6a484f
866211c
847b4b7
b29a9b3
7ad015d
ffc7b3d
21f6328
5a6b1ee
59522b7
1819da7
05b5c43
8bcb078
56e5b17
b80efcc
7649b02
a0ba014
512cf42
5ef518a
677243b
77a9b0d
0141669
3c29359
ca48f2c
dafc6bb
21721cf
ec234b6
a3e32ed
73406a6
d11e749
e09aadf
acedc7f
1a31c28
b2fb18f
7dc8d4d
0984f64
b05ea1a
433c321
ffdcc2b
55eb2d3
bbe50b6
cc93841
e059dd1
0781659
b44cd0f
170b3fe
6ec96dd
5bb52b4
d38ea29
bfa7795
39fe477
80796d3
0756e49
4c9144b
ed108c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import fs from 'fs'; | ||
| import path from 'path'; | ||
| import type {Compiler} from 'webpack'; | ||
| import {version as APP_VERSION} from '../../package.json'; | ||
|
|
||
| /** | ||
| * Simple webpack plugin that writes the app version (from package.json) and the webpack hash to './version.json' | ||
| */ | ||
| class CustomVersionFilePlugin { | ||
| apply(compiler: Compiler) { | ||
| compiler.hooks.done.tap(this.constructor.name, () => { | ||
| const versionPath = path.join(__dirname, '/../../dist/version.json'); | ||
| fs.mkdir(path.dirname(versionPath), {recursive: true}, (directoryError) => { | ||
| if (directoryError) { | ||
| throw directoryError; | ||
| } | ||
| fs.writeFile(versionPath, JSON.stringify({version: APP_VERSION}), {encoding: 'utf8'}, (error) => { | ||
| if (!error) { | ||
| return; | ||
| } | ||
| throw error; | ||
| }); | ||
| }); | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| export default CustomVersionFilePlugin; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| type Environment = { | ||
| file?: string; | ||
| platform?: 'web' | 'desktop'; | ||
| }; | ||
|
|
||
| export default Environment; |
|
JKobrynski marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,13 +1,17 @@ | ||
| const path = require('path'); | ||
| const fs = require('fs'); | ||
| const {IgnorePlugin, DefinePlugin, ProvidePlugin, EnvironmentPlugin} = require('webpack'); | ||
| const {CleanWebpackPlugin} = require('clean-webpack-plugin'); | ||
| const HtmlWebpackPlugin = require('html-webpack-plugin'); | ||
| const CopyPlugin = require('copy-webpack-plugin'); | ||
| const dotenv = require('dotenv'); | ||
| const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer'); | ||
| import {CleanWebpackPlugin} from 'clean-webpack-plugin'; | ||
| import CopyPlugin from 'copy-webpack-plugin'; | ||
| import dotenv from 'dotenv'; | ||
| import fs from 'fs'; | ||
| import HtmlWebpackPlugin from 'html-webpack-plugin'; | ||
| import path from 'path'; | ||
| import type {Configuration} from 'webpack'; | ||
| import {DefinePlugin, EnvironmentPlugin, IgnorePlugin, ProvidePlugin} from 'webpack'; | ||
| import {BundleAnalyzerPlugin} from 'webpack-bundle-analyzer'; | ||
| import CustomVersionFilePlugin from './CustomVersionFilePlugin'; | ||
| import type Environment from './types'; | ||
|
|
||
| // require is necessary, there are no types for this package and the declaration file can't be seen by the build process which causes an error. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💚 |
||
| const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin'); | ||
|
JKobrynski marked this conversation as resolved.
|
||
| const CustomVersionFilePlugin = require('./CustomVersionFilePlugin'); | ||
|
|
||
| const includeModules = [ | ||
| 'react-native-animatable', | ||
|
|
@@ -25,29 +29,25 @@ const includeModules = [ | |
| 'expo-av', | ||
| ].join('|'); | ||
|
|
||
| const envToLogoSuffixMap = { | ||
| const environmentToLogoSuffixMap: Record<string, string> = { | ||
| production: '', | ||
| staging: '-stg', | ||
| dev: '-dev', | ||
| adhoc: '-adhoc', | ||
| }; | ||
|
|
||
| function mapEnvToLogoSuffix(envFile) { | ||
| let env = envFile.split('.')[2]; | ||
| if (typeof env === 'undefined') { | ||
| env = 'dev'; | ||
| function mapEnvironmentToLogoSuffix(environmentFile: string): string { | ||
| let environment = environmentFile.split('.')[2]; | ||
| if (typeof environment === 'undefined') { | ||
| environment = 'dev'; | ||
| } | ||
| return envToLogoSuffixMap[env]; | ||
| return environmentToLogoSuffixMap[environment]; | ||
| } | ||
|
|
||
| /** | ||
| * Get a production grade config for web or desktop | ||
| * @param {Object} env | ||
| * @param {String} env.envFile path to the env file to be used | ||
| * @param {'web'|'desktop'} env.platform | ||
| * @returns {Configuration} | ||
| */ | ||
| const webpackConfig = ({envFile = '.env', platform = 'web'}) => ({ | ||
| const getCommonConfiguration = ({file = '.env', platform = 'web'}: Environment): Configuration => ({ | ||
| mode: 'production', | ||
| devtool: 'source-map', | ||
| entry: { | ||
|
|
@@ -68,10 +68,10 @@ const webpackConfig = ({envFile = '.env', platform = 'web'}) => ({ | |
| new HtmlWebpackPlugin({ | ||
| template: 'web/index.html', | ||
| filename: 'index.html', | ||
| splashLogo: fs.readFileSync(path.resolve(__dirname, `../../assets/images/new-expensify${mapEnvToLogoSuffix(envFile)}.svg`), 'utf-8'), | ||
| splashLogo: fs.readFileSync(path.resolve(__dirname, `../../assets/images/new-expensify${mapEnvironmentToLogoSuffix(file)}.svg`), 'utf-8'), | ||
| isWeb: platform === 'web', | ||
| isProduction: envFile === '.env.production', | ||
| isStaging: envFile === '.env.staging', | ||
| isProduction: file === '.env.production', | ||
| isStaging: file === '.env.staging', | ||
| }), | ||
| new PreloadWebpackPlugin({ | ||
| rel: 'preload', | ||
|
|
@@ -121,12 +121,14 @@ const webpackConfig = ({envFile = '.env', platform = 'web'}) => ({ | |
| ...(platform === 'web' ? [new CustomVersionFilePlugin()] : []), | ||
| new DefinePlugin({ | ||
| ...(platform === 'desktop' ? {} : {process: {env: {}}}), | ||
| __REACT_WEB_CONFIG__: JSON.stringify(dotenv.config({path: envFile}).parsed), | ||
| // 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 | ||
| __DEV__: /staging|prod|adhoc/.test(envFile) === false, | ||
| // eslint-disable-next-line @typescript-eslint/naming-convention | ||
| __DEV__: /staging|prod|adhoc/.test(file) === false, | ||
| }), | ||
|
|
||
| // This allows us to interactively inspect JS bundle contents | ||
|
|
@@ -203,21 +205,34 @@ const webpackConfig = ({envFile = '.env', platform = 'web'}) => ({ | |
| }, | ||
| resolve: { | ||
| alias: { | ||
| // 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', | ||
| // eslint-disable-next-line @typescript-eslint/naming-convention | ||
| 'react-native-sound': 'react-native-web-sound', | ||
| // 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 | ||
| '@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'), | ||
| }, | ||
|
|
||
|
|
@@ -242,6 +257,7 @@ const webpackConfig = ({envFile = '.env', platform = 'web'}) => ({ | |
| '.tsx', | ||
| ], | ||
| fallback: { | ||
| // eslint-disable-next-line @typescript-eslint/naming-convention | ||
| 'process/browser': require.resolve('process/browser'), | ||
| crypto: false, | ||
| }, | ||
|
|
@@ -275,4 +291,4 @@ const webpackConfig = ({envFile = '.env', platform = 'web'}) => ({ | |
| }, | ||
| }); | ||
|
|
||
| module.exports = webpackConfig; | ||
| export default getCommonConfiguration; | ||
|
JKobrynski marked this conversation as resolved.
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,29 +1,28 @@ | ||
| const path = require('path'); | ||
| const webpack = require('webpack'); | ||
| const _ = require('underscore'); | ||
|
|
||
| const desktopDependencies = require('../../desktop/package.json').dependencies; | ||
| const getCommonConfig = require('./webpack.common'); | ||
| import path from 'path'; | ||
| import type {Configuration} from 'webpack'; | ||
| import webpack from 'webpack'; | ||
| // eslint-disable-next-line @dword-design/import-alias/prefer-alias, import/no-relative-packages -- alias imports don't work for webpack | ||
| import {dependencies as desktopDependencies} from '../../desktop/package.json'; | ||
| import type Environment from './types'; | ||
| import getCommonConfiguration from './webpack.common'; | ||
|
|
||
| /** | ||
| * Desktop creates 2 configurations in parallel | ||
| * 1. electron-main - the core that serves the app content | ||
| * 2. web - the app content that would be rendered in electron | ||
| * Everything is placed in desktop/dist and ready for packaging | ||
| * @param {Object} env | ||
| * @returns {webpack.Configuration[]} | ||
| */ | ||
| module.exports = (env) => { | ||
| const rendererConfig = getCommonConfig({...env, platform: 'desktop'}); | ||
| const getConfiguration = (environment: Environment): Configuration[] => { | ||
| const rendererConfig = getCommonConfiguration({...environment, platform: 'desktop'}); | ||
| const outputPath = path.resolve(__dirname, '../../desktop/dist'); | ||
|
|
||
| rendererConfig.name = 'renderer'; | ||
| rendererConfig.output.path = path.join(outputPath, 'www'); | ||
| (rendererConfig.output ??= {}).path = path.join(outputPath, 'www'); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this is the only place we use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would you suggest we change it?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Up to you, I don't feel very strongly, specially given the file it's in |
||
|
|
||
| // Expose react-native-config to desktop-main | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this comment above the line below it?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's above, not 100% sure what the author had in mind though
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🙈 I phrased that very poorly, but I think you got it. How does this line expose react-native-config to desktop-main? Isn't that done by
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By "author" I meant the person that added the comment 😄 |
||
| const definePlugin = _.find(rendererConfig.plugins, (plugin) => plugin.constructor === webpack.DefinePlugin); | ||
| const definePlugin = rendererConfig.plugins?.find((plugin) => plugin?.constructor === webpack.DefinePlugin); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes,
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting. I quickly searched for the type of |
||
|
|
||
| const mainProcessConfig = { | ||
| const mainProcessConfig: Configuration = { | ||
| mode: 'production', | ||
| name: 'desktop-main', | ||
| target: 'electron-main', | ||
|
|
@@ -38,13 +37,15 @@ module.exports = (env) => { | |
| }, | ||
| resolve: rendererConfig.resolve, | ||
| plugins: [definePlugin], | ||
| externals: [..._.keys(desktopDependencies), 'fsevents'], | ||
| externals: [...Object.keys(desktopDependencies), 'fsevents'], | ||
| node: { | ||
| /** | ||
| * Disables webpack processing of __dirname and __filename, so it works like in node | ||
| * https://github.com/webpack/webpack/issues/2010 | ||
| */ | ||
| // eslint-disable-next-line @typescript-eslint/naming-convention | ||
| __dirname: false, | ||
| // eslint-disable-next-line @typescript-eslint/naming-convention | ||
| __filename: false, | ||
| }, | ||
| module: { | ||
|
|
@@ -60,3 +61,5 @@ module.exports = (env) => { | |
|
|
||
| return [mainProcessConfig, rendererConfig]; | ||
| }; | ||
|
|
||
| export default getConfiguration; | ||
Uh oh!
There was an error while loading. Please reload this page.