Skip to content

Commit ec832ba

Browse files
feat: update Firebase project generator to add dependencies to workspace package.json
1 parent b3a0709 commit ec832ba

File tree

2 files changed

+77
-17
lines changed

2 files changed

+77
-17
lines changed

tools/nx/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@firemono/nx",
3-
"version": "1.2.9",
3+
"version": "1.3.0",
44
"description": "Nx plugin for Firebase development with proper architecture - Functions as Nx apps building to dist, live reloading, and auto-persisted emulator data",
55
"author": "Johannes Firemono",
66
"license": "MIT",

tools/nx/src/generators/init/init.ts

Lines changed: 76 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,68 @@ ${features.includes('storage') ? `├── storage.rules # Storage secu
236236
tree.write(joinPathFragments(projectRoot, 'README.md'), readmeContent);
237237
}
238238

239+
function addFirebaseDependenciesToWorkspace(tree: Tree, functionsSourceDir: string): { dependencies: Record<string, string>, devDependencies: Record<string, string> } {
240+
const functionsPackageJsonPath = join(functionsSourceDir, 'package.json');
241+
let functionsDeps = { dependencies: {}, devDependencies: {} };
242+
243+
// Read existing functions dependencies if available
244+
if (existsSync(functionsPackageJsonPath)) {
245+
try {
246+
const functionsPackageJson = JSON.parse(require('fs').readFileSync(functionsPackageJsonPath, 'utf8'));
247+
functionsDeps = {
248+
dependencies: functionsPackageJson.dependencies || {},
249+
devDependencies: functionsPackageJson.devDependencies || {}
250+
};
251+
} catch (error) {
252+
logger.warn(`Could not parse functions package.json: ${error}`);
253+
}
254+
}
255+
256+
// Add default Firebase dependencies if not present
257+
const defaultDeps = {
258+
'firebase-admin': '^13.2.0',
259+
'firebase-functions': '^6.0.1'
260+
};
261+
262+
const defaultDevDeps = {
263+
'@typescript-eslint/eslint-plugin': '^5.12.0',
264+
'@typescript-eslint/parser': '^5.12.0',
265+
'eslint-config-google': '^0.14.0',
266+
'eslint-plugin-import': '^2.25.4',
267+
'firebase-functions-test': '^3.1.0'
268+
};
269+
270+
// Merge with defaults
271+
functionsDeps.dependencies = { ...defaultDeps, ...functionsDeps.dependencies };
272+
functionsDeps.devDependencies = { ...defaultDevDeps, ...functionsDeps.devDependencies };
273+
274+
// Read workspace package.json
275+
const workspacePackageJsonPath = join(workspaceRoot, 'package.json');
276+
if (existsSync(workspacePackageJsonPath)) {
277+
try {
278+
const workspacePackageJson = JSON.parse(require('fs').readFileSync(workspacePackageJsonPath, 'utf8'));
279+
const updatedWorkspacePackage = {
280+
...workspacePackageJson,
281+
dependencies: {
282+
...workspacePackageJson.dependencies,
283+
...functionsDeps.dependencies
284+
},
285+
devDependencies: {
286+
...workspacePackageJson.devDependencies,
287+
...functionsDeps.devDependencies
288+
}
289+
};
290+
291+
require('fs').writeFileSync(workspacePackageJsonPath, JSON.stringify(updatedWorkspacePackage, null, 2));
292+
logger.info('✅ Added Firebase dependencies to workspace package.json');
293+
} catch (error) {
294+
logger.warn(`Could not update workspace package.json: ${error}`);
295+
}
296+
}
297+
298+
return functionsDeps;
299+
}
300+
239301
function createFunctionsNxApp(tree: Tree, baseProjectName: string, projectDir: string, initDir: string) {
240302
const functionsAppName = `${baseProjectName}-functions`;
241303
const functionsAppRoot = joinPathFragments(projectDir, 'functions');
@@ -246,6 +308,9 @@ function createFunctionsNxApp(tree: Tree, baseProjectName: string, projectDir: s
246308
return null;
247309
}
248310

311+
// Add Firebase dependencies to workspace package.json
312+
addFirebaseDependenciesToWorkspace(tree, functionsSourceDir);
313+
249314
// Create Functions app project.json
250315
const functionsProjectConfig = {
251316
name: functionsAppName,
@@ -400,24 +465,15 @@ export default defineConfig(() => ({
400465

401466
tree.write(joinPathFragments(functionsAppRoot, 'vite.config.ts'), viteConfig);
402467

403-
// Create package.json for development
468+
// Create minimal package.json for functions (dependencies are managed at workspace level)
404469
const functionsPackageJson = {
405-
name: 'functions',
406-
engines: { node: '22' },
407-
main: 'index.cjs',
408-
dependencies: {
409-
'firebase-admin': '^13.2.0',
410-
'firebase-functions': '^6.0.1'
411-
},
412-
devDependencies: {
413-
'@typescript-eslint/eslint-plugin': '^5.12.0',
414-
'@typescript-eslint/parser': '^5.12.0',
415-
eslint: '^8.9.0',
416-
'eslint-config-google': '^0.14.0',
417-
'eslint-plugin-import': '^2.25.4',
418-
'firebase-functions-test': '^3.1.0',
419-
typescript: '^4.9.0'
470+
name: functionsAppName,
471+
engines: {
472+
node: '22'
420473
},
474+
main: 'index.cjs',
475+
dependencies: {},
476+
devDependencies: {},
421477
private: true
422478
};
423479

@@ -700,6 +756,7 @@ emulator-data/
700756
console.log(` - Builds to: dist/${baseProjectName}/functions/`);
701757
console.log(` - Firebase uses dist directory directly (no copying needed!)`);
702758
console.log(` - Watch mode available for live development`);
759+
console.log(` - Dependencies added to workspace package.json`);
703760
}
704761
console.log(`\n🔥 Detected Firebase features: ${features.join(', ') || 'none'}`);
705762
console.log(`\n📂 Project created at: ${projectRoot}`);
@@ -717,4 +774,7 @@ emulator-data/
717774
console.log(` - nx logs ${firebaseProjectName} # View function logs`);
718775
}
719776
console.log(`\n📖 See ${projectRoot}/README.md for detailed usage instructions`);
777+
if (functionsAppName) {
778+
console.log(`\n💡 Don't forget to run 'npm install' to install the Firebase dependencies`);
779+
}
720780
}

0 commit comments

Comments
 (0)