Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 4 additions & 3 deletions src/schematics/deploy/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import * as winston from 'winston';
import { BuildTarget, CloudRunOptions, DeployBuilderSchema, FSHost, FirebaseTools } from '../interfaces';
import { DEFAULT_FUNCTION_NAME, defaultFunction, defaultPackage, dockerfile, functionGen2 } from './functions-templates.js';

// @ts-ignore
const __dirname = dirname(fileURLToPath(import.meta.url));
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore `import.meta` is rejected by the --module es2015 pass of `npm run build:jasmine`.
const moduleDirectory = typeof __dirname === 'string' ? __dirname : dirname(fileURLToPath(import.meta.url));

const { copySync, removeSync, readJsonSync } = fsExtra;

Expand Down Expand Up @@ -128,7 +129,7 @@ const findPackageVersion = (packageManager: string, name: string) => {
const getPackageJson = (context: BuilderContext, workspaceRoot: string, options: DeployBuilderOptions, main?: string) => {
const dependencies: Record<string, string> = {};
const devDependencies: Record<string, string> = {};
const { firebaseFunctionsDependencies } = readJsonSync(join(__dirname, '..', 'versions.json'));
const { firebaseFunctionsDependencies } = readJsonSync(join(moduleDirectory, '..', 'versions.json'));
if (options.ssr !== 'cloud-run') {
Object.keys(firebaseFunctionsDependencies).forEach(name => {
const { version, dev } = firebaseFunctionsDependencies[name];
Expand Down
41 changes: 32 additions & 9 deletions tools/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,17 +313,21 @@ function spawnPromise(command: string, args: string[]) {
.on('error', reject));
}

// Path segments of each schematic entry point, relative to `schematics/` and without the file
// extension: esbuild compiles the `.ts` and loadCompiledSchematics requires the emitted `.js`.
const schematicEntryPoints = [
['update', 'index'],
['deploy', 'actions'],
['deploy', 'builder'],
['add', 'index'],
['setup', 'index'],
['update', 'v7', 'index'],
['update', 'v21', 'index'],
];

async function compileSchematics() {
await esbuild.build({
entryPoints: [
src('schematics', "update", "index.ts"),
src('schematics', "deploy", "actions.ts"),
src('schematics', "deploy", "builder.ts"),
src('schematics', "add", "index.ts"),
src('schematics', "setup", "index.ts"),
src('schematics', "update", "v7", "index.ts"),
src('schematics', "update", "v21", "index.ts"),
],
entryPoints: schematicEntryPoints.map(segments => `${src('schematics', ...segments)}.ts`),
format: "cjs",
// turns out schematics don't support ESM, need to use webpack or shim these
// format: "esm",
Expand Down Expand Up @@ -357,6 +361,25 @@ async function compileSchematics() {
copy(src('schematics', 'setup', 'schema.json'), dest('schematics', 'setup', 'schema.json')),
]);
await replaceSchematicVersions();
await loadCompiledSchematics();
}

/**
* Loads every compiled schematic entry point, so a bundle that cannot even be required fails the
* build instead of shipping.
*/
async function loadCompiledSchematics() {
const failures: string[] = [];
for (const segments of schematicEntryPoints) {
try {
require(`${dest('schematics', ...segments)}.js`);
} catch (error) {
failures.push(` ${join(...segments)}.js: ${error}`);
}
}
if (failures.length) {
throw new Error(`Compiled schematics failed to load:\n${failures.join('\n')}`);
}
}

async function buildLibrary() {
Expand Down
Loading