Last active
March 11, 2021 14:53
-
-
Save mike-hogan/336de1a55ad1a776398ea85c2691dfd2 to your computer and use it in GitHub Desktop.
Prep a rushjs project for deployment in Firebase Functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This script will makes a rushjs project ready for deployment in Firebase Cloud Functions. | |
* | |
* It creates a staging directory with rewritten package.json files, and all local rushjs dependencies copied. | |
* | |
* It requires ./firebase-files to contain: | |
* .firebaserc | |
* .firebase.json | |
* functions/tsconfig.json | |
* | |
* These three files should be exactly as "firebase init functions" created them. | |
* | |
* Store this file as scripts/deploy.ts | |
* | |
* You run it using "npx ts-node scripts/deploy.ts" | |
* | |
* Then: | |
* | |
* cd staging/functions | |
* npm i | |
* npm run build | |
* cd .. | |
* firebase deploy --only function | |
*/ | |
import rush from '../../../rush.json' | |
import pkg from '../package.json' | |
import {exec} from "child_process"; | |
import * as fs from "fs"; | |
import stripAnsi = require("strip-ansi"); | |
// Change this | |
const organisation = "@docsndata" | |
function shell(line: string): Promise<string> { | |
return new Promise<string>((resolve, reject) => { | |
exec(line, (error, stdout, stderr) => { | |
if (error) { | |
reject(error) | |
} | |
if (stdout !== "") { | |
console.log(stdout) | |
} | |
if (stderr !== "") { | |
console.log(stderr) | |
} | |
console.log(`Done: ${line}`) | |
resolve(stdout) | |
}) | |
}) | |
} | |
export type RushProject = { packageName: string, projectFolder: string } | |
function copyPackageDotJson(project: RushProject, allProjects: RushProject[], ) { | |
const packageDotJson:any = JSON.parse(fs.readFileSync(`../../${project.projectFolder}/package.json`, 'utf8')) | |
const rewrittenPackageDotJson = allProjects.reduce((acc:any, current) => { | |
if(acc.dependencies && acc.dependencies[current.packageName]) { | |
acc.dependencies[current.packageName] = `file:../../${current.projectFolder}` | |
} | |
return acc | |
}, packageDotJson) | |
fs.writeFileSync(`staging/functions/local_deps/${project.projectFolder}/package.json`, JSON.stringify(rewrittenPackageDotJson, null, 2)) | |
} | |
async function main() { | |
await shell("mkdir -p staging/functions/local_deps") | |
const localDeps = stripAnsi(await shell("rush build -t .")) | |
.split("\n") | |
.filter(line => line.startsWith(organisation + "/")) | |
.filter(line => line !== pkg.name) | |
const referencedProjects = rush.projects.filter(p => localDeps.includes(p.packageName)) | |
const mkdirLines = referencedProjects.map(rp => `mkdir -p staging/functions/local_deps/${rp.projectFolder}`) | |
await Promise.all(mkdirLines.map(shell)) | |
const copyDistLines = referencedProjects.map(rp => `cp -r ../../${rp.projectFolder}/dist staging/functions/local_deps/${rp.projectFolder}/`) | |
await Promise.all(copyDistLines.map(shell)) | |
referencedProjects.map(rp => copyPackageDotJson(rp, referencedProjects)) | |
await Promise.all([ | |
shell("cp -r firebase-files/* staging/"), | |
shell("cp firebase-files/.firebaserc staging/"), | |
shell("cp -r src staging/functions") | |
]) | |
const rewrittenDependencies: { [key: string]: string } = {...pkg.dependencies} | |
for (const localDep of localDeps) { | |
const rushDef = referencedProjects.find(rp => rp.packageName === localDep)! | |
rewrittenDependencies[localDep] = `file:./local_deps/${rushDef.projectFolder}` | |
} | |
// @ts-ignore | |
pkg.dependencies = rewrittenDependencies | |
fs.writeFileSync(`staging/functions/package.json`, JSON.stringify(pkg, null, 2)) | |
} | |
main().catch(err => console.error(err)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment