Skip to content

Commit

Permalink
Merge pull request #6 from NerdWalletOSS/clangen/fix-release-preloads
Browse files Browse the repository at this point in the history
Fix preload module loading in release builds.
  • Loading branch information
clangen-nw authored Apr 18, 2022
2 parents 7140dc7 + 45d6f55 commit 839a201
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 18 deletions.
4 changes: 4 additions & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ node_modules
/build
/dist

# generated files
public/preload-manifest.js
public/preload-module-*

# misc
.DS_Store
.env.local
Expand Down
42 changes: 25 additions & 17 deletions app/public/preload.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const { app, dialog } = remote;
const { spawn } = require('child_process');

const version = remote.app.getVersion();
const { isPackaged, getAppPath } = remote.app;

const adb = require('@devicefarmer/adbkit').Adb;

Expand Down Expand Up @@ -55,7 +56,6 @@ const IS_MACOS = getPlatform() === 'mac';
const getPathToBinary = (name) => {
const resolvedName = IS_WINDOWS ? `${name}.exe` : name;
const root = process.cwd();
const { isPackaged, getAppPath } = remote.app;
const binariesPath = isPackaged
? path.join(path.dirname(getAppPath()), '..', './Resources', './bin')
: path.join(root, './resources', getPlatform(), './bin');
Expand Down Expand Up @@ -410,23 +410,31 @@ global.ipc = {
* JS modules, so they must use `require` and not `import`.
*/

const PRELOADS_PATH = path.join(__dirname, '../src/App/Plugins/preloads.js');
/* eslint-disable-next-line import/no-dynamic-require */
const PRELOADS = require(PRELOADS_PATH).default();
let PRELOADS;
if (isPackaged) {
/* release builds cannot load preload scripts outside of the current working
directory; we have a build process to aggregate these all together at build
time, and place them in ./preload-modules.js. */
PRELOADS = require('./preload-manifest').default || [];
} else {
/* debug builds load directly from the filesystem for quicker iteration and
easier debugging... */
const PRELOADS_PATH = '../src/App/Plugins/preloads.js';
/* eslint-disable-next-line import/no-dynamic-require */
PRELOADS = require(PRELOADS_PATH).default() || [];
}

console.log('[plugin-preloads', 'resolved', PRELOADS);
PRELOADS.forEach((preloadPath) => {
if (fs.existsSync(preloadPath)) {
console.log('[plugin-preloads]', 'trying to load', preloadPath);
try {
/* eslint-disable-next-line import/no-dynamic-require */
const preload = require(preloadPath);
if (preload && preload.default && preload.default.start) {
console.log('[plugin-preloads]', 'starting', preloadPath);
preload.default.start(global.ipc);
}
} catch (e) {
console.warn('[plugin-preloads]', preloadPath, 'failed', e);
console.log('[plugin-preloads]', 'trying to load', preloadPath);
try {
/* eslint-disable-next-line import/no-dynamic-require */
const preload = require(preloadPath);
if (preload && preload.default && preload.default.start) {
console.log('[plugin-preloads]', 'starting', preloadPath);
preload.default.start(global.ipc);
}
} else {
console.warn('[plugin-preloads]', `'${preloadPath}' file not found`);
} catch (e) {
console.warn('[plugin-preloads]', preloadPath, 'failed', e);
}
});
3 changes: 3 additions & 0 deletions app/script/build-release.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#!/bin/bash
yarn install-patch
yarn forwarder:build
rm public/preload-manifest.js
rm public/preload-module-*.js
node script/collect-preload-scripts.js
yarn build
yarn package
63 changes: 63 additions & 0 deletions app/script/collect-preload-scripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
const path = require('path');
const crypto = require('crypto');
const fs = require('fs');

console.log('\n\ncollecting preload scripts and generating manifest...\n\n');

const preloadsModuleFn = path.join(
__dirname,
'..',
'src/App/Plugins/preloads.js'
);

const outDir = path.join(__dirname, '..', 'public');
const outManifestFn = path.normalize(`${outDir}/preload-manifest.js`);

const MANIFEST_TEMPLATE = `/* this is an automatically generated file, DO NOT MODIFY! */
exports.default = [{{MODULES}}];`;

/* eslint-disable-next-line import/no-dynamic-require */
const preloadFilenames = require(preloadsModuleFn).default();
const outputFilenames = new Set([]);

console.log(preloadsModuleFn, preloadFilenames);

const rmFile = (fn) => {
if (fs.existsSync(fn)) {
try {
fs.rmSync(fn);
} catch (e) {}
try {
fs.unlinkSync(fn);
} catch (e) {}
}
};

const copyFile = (inFn) => {
const hash = crypto
.createHash('sha256')
.update(inFn)
.digest('hex')
.toString();
const leaf = `preload-module-${hash}.js`;
const outFn = path.normalize(`${outDir}/${leaf}`);
rmFile(outFn);
outputFilenames.add(`'./${leaf}'`);
fs.copyFileSync(inFn, outFn);
};

for (let i = 0; i < preloadFilenames.length; i++) {
copyFile(preloadFilenames[i]);
}

const manifestEntries = Array.from(outputFilenames).join(', ');
const manifestDocument = MANIFEST_TEMPLATE.replace(
'{{MODULES}}',
manifestEntries
);
rmFile(outManifestFn);
fs.writeFileSync(outManifestFn, manifestDocument);

console.log(
`\n\nwrote manifest to ${outManifestFn} with scripts: ${manifestEntries}\n\n`
);
3 changes: 2 additions & 1 deletion app/src/App/Plugins/preloads.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ const resolveExternalPreloads = () => {
return resolver() || [];
}
} catch (e) {
console.error('failed to load external preloads', e);
console.warn('failed to load external preloads', e);
console.warn('the warning above can probably be safely ignored...');
}
return [];
};
Expand Down

0 comments on commit 839a201

Please sign in to comment.