Skip to content
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

Reduce desktop app size #7744

Merged
merged 36 commits into from
Feb 25, 2022
Merged
Show file tree
Hide file tree
Changes from 35 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
02fd399
Make separate desktop package.json
kidroca Feb 11, 2022
03d6cb7
Set desktop build output directory
kidroca Jan 31, 2022
b9e02c0
Build for multiple desktop architectures
kidroca Feb 11, 2022
1550017
Ignore build artifacts
kidroca Jan 31, 2022
f3b03ac
Change file structure - files from parent folders cannot be included
kidroca Feb 11, 2022
77361f3
New webpack.web.js configuration to substitute prod/staging
kidroca Feb 11, 2022
844309e
New webpack.desktop.js configuration
kidroca Feb 11, 2022
645f82e
Simplify webpack configs
kidroca Feb 12, 2022
0500f4c
Add documentation regarding packaging
kidroca Feb 12, 2022
9625529
Fix main USE_WEB_PROXY check
kidroca Feb 12, 2022
922b661
Get rid of the nested package folder
kidroca Feb 14, 2022
67cb30b
Remove unneeded stuff from webpack.desktop
kidroca Feb 14, 2022
1e653bd
One electronBuilder config
kidroca Feb 15, 2022
4e9d972
Extract desktop/build.sh script
kidroca Feb 15, 2022
8a09b0e
use CustomVersionPlugin only on web
kidroca Feb 15, 2022
b8cf68e
Fix ELECTRON_ENVIRONMENT.js
kidroca Feb 15, 2022
8ef2317
Fix local desktop dev
kidroca Feb 15, 2022
d79a594
Apply dotenv in desktop/start
kidroca Feb 16, 2022
8ad7d2b
Move shell scripts to scripts/
kidroca Feb 21, 2022
21fa1cc
Move desktop/build to scripts
kidroca Feb 21, 2022
5991c9b
Move build/react-native-web.sh to scripts/
kidroca Feb 21, 2022
850a6ef
Change postinstall script to use `npm install` instead of electron-bu…
kidroca Feb 21, 2022
06213f0
Install package dependencies (desktop dependencies moved to desktop/)
kidroca Feb 21, 2022
91a6800
Make it possible to use CONFIG in desktop/main.js
kidroca Feb 21, 2022
8fb10d1
Remove `electron-reloader` - does not work with transpiled `main.js`
kidroca Feb 21, 2022
d65d0be
Remove webproxy check from desktop
kidroca Feb 21, 2022
b038647
Fix SCRIPTS_DIR failing on CI
kidroca Feb 22, 2022
622e41d
Apply suggestions from code review
kidroca Feb 23, 2022
8fcf32c
Move `getPullRequestsMergedBetweenTests.sh` back to `tests/unit/`
kidroca Feb 23, 2022
bfa2b81
Covert follow up `if` to an `else` statement
kidroca Feb 23, 2022
d248078
Revert change to test workflow
kidroca Feb 23, 2022
781c8d5
Fix scripts relative path
kidroca Feb 23, 2022
f48301f
Fix documentation typo
kidroca Feb 24, 2022
bf345de
Delete ENVIRONMENT.js and move definitions back inside CONST/index.js
kidroca Feb 24, 2022
e1b0861
Expand on desktop packaging documentation
kidroca Feb 24, 2022
e6df824
Merge branch 'main' into kidroca/feature/new-desktop-config
kidroca Feb 25, 2022
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ android/app/src/main/java/com/expensify/chat/generated/
node_modules/
npm-debug.log
yarn-error.log

# Bundled code
dist/
desktop-build/

# BUCK
buck-out/
Expand Down
44 changes: 44 additions & 0 deletions config/electronBuilder/electronBuilder.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const {version} = require('../../package.json');

const isStaging = process.env.ELECTRON_ENV === 'staging';
const isPublishing = process.argv.includes('--publish');

/**
* The configuration for the production and staging Electron builds.
* It can be used to create local builds of the same, by omitting the `--publish` flag
*/
module.exports = {
appId: 'com.expensifyreactnative.chat',
productName: 'New Expensify',
extraMetadata: {
version,
},
mac: {
category: 'public.app-category.finance',
target: [
{target: 'dmg', arch: ['x64', 'arm64', 'universal']},
],
icon: isStaging ? './desktop/icon-stg.png' : './desktop/icon.png',
hardenedRuntime: true,
entitlements: 'desktop/entitlements.mac.plist',
entitlementsInherit: 'desktop/entitlements.mac.plist',
type: 'distribution',
},
dmg: {
internetEnabled: true,
},
publish: [{
provider: 's3',
bucket: isStaging ? 'staging-expensify-cash' : 'expensify-cash',
channel: 'latest',
}],
afterSign: isPublishing ? './desktop/notarize.js' : undefined,
files: [
'dist',
'!dist/www/{.well-known,favicon*}',
],
directories: {
app: 'desktop',
output: 'desktop-build',
},
};
11 changes: 0 additions & 11 deletions config/electronBuilder/electronBuilder.ghactions.config.js

This file was deleted.

37 changes: 0 additions & 37 deletions config/electronBuilder/electronBuilder.local.config.js

This file was deleted.

29 changes: 0 additions & 29 deletions config/webpack/productionConfig.js

This file was deleted.

42 changes: 29 additions & 13 deletions config/webpack/webpack.common.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
const _ = require('underscore');
const path = require('path');
const {IgnorePlugin} = require('webpack');
const {IgnorePlugin, DefinePlugin} = 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');
const CustomVersionFilePlugin = require('./CustomVersionFilePlugin');

// Check for a --platform command line argument (default to 'web')
// If it is 'web', we want to ignore .desktop.js files, and if it is 'desktop', we want to ignore .website.js files.
const platformIndex = _.findIndex(process.argv, arg => arg === '--platform');
const platform = (platformIndex > 0) ? process.argv[platformIndex + 1] : 'web';
const platformExclude = platform === 'web' ? new RegExp(/\.desktop\.js$/) : new RegExp(/\.website\.js$/);

kidroca marked this conversation as resolved.
Show resolved Hide resolved
const includeModules = [
'react-native-animatable',
'react-native-reanimated',
Expand All @@ -25,7 +20,16 @@ const includeModules = [
'react-native-google-places-autocomplete',
].join('|');

const webpackConfig = {
/**
* 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'}) => ({
mode: 'production',
devtool: 'source-map',
entry: {
app: './index.js',
},
Expand Down Expand Up @@ -59,7 +63,20 @@ const webpackConfig = {
],
}),
new IgnorePlugin(/^\.\/locale$/, /moment$/),
new CustomVersionFilePlugin(),
...(platform === 'web' ? [new CustomVersionFilePlugin()] : []),
kidroca marked this conversation as resolved.
Show resolved Hide resolved
new DefinePlugin({
__REACT_WEB_CONFIG__: JSON.stringify(
dotenv.config({path: envFile}).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/.test(envFile) === false,
}),

// This allows us to interactively inspect JS bundle contents
...(process.env.ANALYZE_BUNDLE === 'true' ? [new BundleAnalyzerPlugin()] : []),
],
module: {
rules: [
Expand All @@ -78,15 +95,13 @@ const webpackConfig = {
*/
exclude: [
new RegExp(`node_modules/(?!(${includeModules})/).*|.native.js$`),
platformExclude,
],
},
{
test: /\.js$/,
loader: 'eslint-loader',
exclude: [
/node_modules|\.native\.js$/,
platformExclude,
],
options: {
cache: false,
Expand Down Expand Up @@ -142,8 +157,9 @@ const webpackConfig = {
// without this, web will try to use native implementations and break in not very obvious ways.
// This is also why we have to use .website.js for our own web-specific files...
// Because desktop also relies on "web-specific" module implementations
// This also skips packing web only dependencies to desktop and vice versa
extensions: ['.web.js', (platform === 'web') ? '.website.js' : '.desktop.js', '.js', '.jsx'],
},
};
});

module.exports = webpackConfig;
56 changes: 56 additions & 0 deletions config/webpack/webpack.desktop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const path = require('path');
const webpack = require('webpack');
const _ = require('underscore');

const desktopDependencies = require('../../desktop/package.json').dependencies;
const getCommonConfig = require('./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 outputPath = path.resolve(__dirname, '../../desktop/dist');
kidroca marked this conversation as resolved.
Show resolved Hide resolved

rendererConfig.name = 'renderer';
rendererConfig.output.path = path.join(outputPath, 'www');

// Expose react-native-config to desktop-main
const definePlugin = _.find(rendererConfig.plugins, plugin => plugin.constructor === webpack.DefinePlugin);

const mainProcessConfig = {
mode: 'production',
name: 'desktop-main',
target: 'electron-main',
entry: {
main: './desktop/main.js',
contextBridge: './desktop/contextBridge.js',
},
output: {
filename: '[name].js',
path: outputPath,
libraryTarget: 'commonjs2',
},
resolve: rendererConfig.resolve,
plugins: [definePlugin],
externals: [
..._.keys(desktopDependencies),
'fsevents',
],
node: {
/**
* Disables webpack processing of __dirname and __filename, so it works like in node
* https://github.com/webpack/webpack/issues/2010
*/
__dirname: false,
__filename: false,
},
};

return [mainProcessConfig, rendererConfig];
};
27 changes: 10 additions & 17 deletions config/webpack/webpack.dev.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
const path = require('path');
const webpack = require('webpack');
const {merge} = require('webpack-merge');
const dotenv = require('dotenv');
const common = require('./webpack.common');
const getCommonConfig = require('./webpack.common');

const env = dotenv.config({path: path.resolve(__dirname, '../../.env')}).parsed;

module.exports = () => {
/**
* Configuration for the local dev server
* @param {Object} env
* @returns {Configuration}
*/
module.exports = (env = {}) => {
// Check if the USE_WEB_PROXY variable has been provided
// and rewrite any requests to the local proxy server
const proxySettings = process.env.USE_WEB_PROXY === 'false'
Expand All @@ -18,7 +19,9 @@ module.exports = () => {
},
};

return merge(common, {
const baseConfig = getCommonConfig(env);

return merge(baseConfig, {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
Expand All @@ -27,15 +30,5 @@ module.exports = () => {
...proxySettings,
historyApiFallback: true,
},
plugins: [
new webpack.DefinePlugin({
__REACT_WEB_CONFIG__: JSON.stringify(env),

// 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__: true,
}),
],
});
};
9 changes: 0 additions & 9 deletions config/webpack/webpack.prod.js

This file was deleted.

9 changes: 0 additions & 9 deletions config/webpack/webpack.staging.js

This file was deleted.

30 changes: 0 additions & 30 deletions desktop/ELECTRON_ENVIRONMENT.js

This file was deleted.

Loading