Skip to content

Instantly share code, notes, and snippets.

@idudinov
Last active June 7, 2021 22:55
Show Gist options
  • Save idudinov/ca12ba99f615a23776bed03aa662c29d to your computer and use it in GitHub Desktop.
Save idudinov/ca12ba99f615a23776bed03aa662c29d to your computer and use it in GitHub Desktop.
Firebase Functions: use outer npm package
/*
The idea of this script is to directly add some packages to Firebase [Functions] projects if they were used indirectly via parent node_modules.
Packages outlined in the `dependencies` array below will be installed as dependencies to `thisPackage`. Current versions (if any) of them will be stored in a `backup` file.
In `restore` mode the `backup` file created on the main usage mode will be used to restore packages initial version or remove them at all.
In an ideal word, after using this script in main and `restore` modes no file changes should left.
Usage:
yarn ts-node utils/install-ext-deps.ts
and for `restore` mode:
yarn ts-node utils/install-ext-deps.ts --restore
*/
import * as Path from 'path';
import * as FS from 'fs';
import { spawn } from 'child_process';
const dependencies = [
// your upper level dependencies here...
'mobx',
'firebase',
];
// these paths are hardocded but can be passed via argv in future
const thisPackage = require('../package.json');
const parentPackage = require('../../package.json');
const backupPath = Path.resolve(__dirname, 'install-ext-deps.backup.json');
console.log('Executing...');
function waitForClose(child: ReturnType<typeof spawn>) {
return new Promise(resolve => {
child.on('close', resolve);
});
}
export async function restore() {
if (!FS.existsSync(backupPath)) {
console.error('ERROR: no backup file found on path:', backupPath);
process.exit(1);
return;
}
const backup = require(backupPath) as { package: string, version: string }[];
console.log('restoring packages...', backup);
const add = backup.filter(b => b.version).map(b => `${b.package}@${b.version}`);
if (add.length) {
console.log('restoring packages:', add);
await waitForClose(
spawn('yarn', ['add', ...add], { stdio: 'inherit' }),
);
}
const remove = backup.filter(b => !b.version).map(b => b.package);
if (remove.length > 0) {
console.log('removing packages:', remove);
await waitForClose(
spawn('yarn', ['remove', ...remove], { stdio: 'inherit' }),
);
}
console.log('Finished! Cleaning backup file.');
FS.rmSync(backupPath);
}
export async function replace() {
console.log('Installing external dependencies locally:', dependencies);
const depsWithVersions = [];
const backup = [];
dependencies.forEach(d => {
const existingVersion = parentPackage.dependencies[d] || parentPackage.devDependencies[d];
if (!existingVersion) {
return;
}
depsWithVersions.push(`${d}@${existingVersion}`);
const currentVersion = thisPackage.dependencies[d];
backup.push({ package: d, version: currentVersion || '' });
});
FS.writeFileSync(backupPath, JSON.stringify(backup));
const executeCommands = [
'add',
...depsWithVersions,
];
console.log('Executing this: yarn', executeCommands.join(' '));
await waitForClose(
spawn('yarn', executeCommands, { stdio: 'inherit' }),
);
}
if (process.argv.includes('--restore')) {
restore();
} else {
replace();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment