Skip to content

Commit add6a10

Browse files
authored
feat: Support pnpm for firebase functions (#216)
* Update nx-firebase-versions.ts * Add @google-cloud/functions-framework to plugin workspace * Add googleCloudFunctionsFramework dependency * Ensure auto generated dependencies are clean semvers * Format cleanup * Add @google-cloud/functions-framework dep if pnpm * Add e2e tests * Unit test
1 parent 45fefbe commit add6a10

File tree

10 files changed

+299
-11
lines changed

10 files changed

+299
-11
lines changed

e2e/nx-firebase-e2e/tests/test-function.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,16 @@ export function testFunction() {
8888

8989
validateFunctionConfig(functionData, appData)
9090

91+
// check that google-cloud/functions-framework is added to package.json if pnpm being used
92+
const packageJson = readJson(
93+
`${functionData.projectDir}/package.json`,
94+
)
95+
if (detectPackageManager() === 'pnpm') {
96+
expect(packageJson.dependencies['@google-cloud/functions-framework']).toBeDefined()
97+
}else{
98+
expect(packageJson.dependencies['@google-cloud/functions-framework']).not.toBeDefined()
99+
}
100+
91101
// cleanup
92102
await cleanFunctionAsync(functionData)
93103
await cleanAppAsync(appData)
@@ -117,6 +127,17 @@ export function testFunction() {
117127
),
118128
).not.toThrow()
119129

130+
// check that nx preserves the function `package.json` dependencies in the output `package.json`
131+
const packageJson = readJson(
132+
`dist/${functionData.projectDir}/package.json`,
133+
)
134+
if (detectPackageManager() === 'pnpm') {
135+
expect(packageJson.dependencies['@google-cloud/functions-framework']).toBeDefined()
136+
}else{
137+
expect(packageJson.dependencies['@google-cloud/functions-framework']).not.toBeDefined()
138+
}
139+
140+
120141
// cleanup
121142
await cleanFunctionAsync(functionData)
122143
await cleanAppAsync(appData)

e2e/nx-firebase-e2e/tests/test-workspace.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
import {
66
safeRunNxCommandAsync,
77
} from '../test-utils'
8+
import { detectPackageManager } from '@nx/devkit'
89

910
//--------------------------------------------------------------------------------------------------
1011
// Test the workspace setup & init generator
@@ -48,9 +49,23 @@ export function testWorkspace() {
4849
expect(
4950
packageJson.devDependencies['firebase-functions-test'],
5051
).toBeDefined()
52+
53+
// check that plugin init generator adds @google-cloud/functions-framework if pnpm is being used
54+
if (detectPackageManager() === 'pnpm') {
55+
expect(
56+
packageJson.dependencies['@google-cloud/functions-framework'],
57+
).toBeDefined()
58+
} else {
59+
expect(
60+
packageJson.dependencies['@google-cloud/functions-framework'],
61+
).not.toBeDefined()
62+
}
63+
64+
// test that generator adds dev dependencies to workspace package.json
5165
expect(packageJson.devDependencies['firebase-tools']).toBeDefined()
5266
//SM: Mar'24: our plugin init generator now only add @nx/node
5367
expect(packageJson.devDependencies['@nx/node']).toBeDefined()
68+
5469
})
5570
})
5671
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
},
2020
"private": true,
2121
"devDependencies": {
22+
"@google-cloud/functions-framework": "^3.3.0",
2223
"@nx/devkit": "16.8.1",
2324
"@nx/eslint-plugin": "16.8.1",
2425
"@nx/jest": "16.8.1",

packages/nx-firebase/src/__generated__/nx-firebase-versions.ts

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/nx-firebase/src/generators/function/lib/create-files.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
import { offsetFromRoot, Tree } from '@nx/devkit'
1+
import {
2+
detectPackageManager,
3+
offsetFromRoot,
4+
Tree,
5+
updateJson,
6+
} from '@nx/devkit'
27
import { generateFiles, joinPathFragments } from '@nx/devkit'
38
import type { NormalizedSchema } from '../schema'
9+
import { packageVersions } from '../../../__generated__/nx-firebase-versions'
410

511
/**
612
* Generate the firebase app specific files
@@ -45,4 +51,23 @@ export function createFiles(host: Tree, options: NormalizedSchema): void {
4551
options.projectRoot,
4652
substitutions,
4753
)
54+
55+
// set dependencies for the firebase function
56+
const firebasePackageDependencies = {}
57+
if (detectPackageManager() === 'pnpm') {
58+
firebasePackageDependencies[
59+
'@google-cloud/functions-framework'
60+
] = `^${packageVersions.googleCloudFunctionsFramework}`
61+
}
62+
63+
if (Object.keys(firebasePackageDependencies).length > 0) {
64+
updateJson(
65+
host,
66+
joinPathFragments(options.projectRoot, 'package.json'),
67+
(json) => {
68+
json.dependencies = firebasePackageDependencies
69+
return json
70+
},
71+
)
72+
}
4873
}

packages/nx-firebase/src/generators/init/init.spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,17 @@ describe('init generator', () => {
9090
`^${packageVersions.killPort}`,
9191
)
9292

93+
// check that plugin init generator adds @google-cloud/functions-framework if pnpm is being used
94+
if (devkit.detectPackageManager() === 'pnpm') {
95+
expect(
96+
packageJson.dependencies['@google-cloud/functions-framework'],
97+
).toBe(`^${packageVersions.googleCloudFunctionsFramework}`)
98+
} else {
99+
expect(
100+
packageJson.dependencies['@google-cloud/functions-framework'],
101+
).not.toBeDefined()
102+
}
103+
93104
expect(packageJson.dependencies['tslib']).not.toBeDefined()
94105
})
95106

packages/nx-firebase/src/generators/init/init.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { addGitIgnore, addNxIgnore } from './lib/add-git-ignore-entry'
44
import type { InitGeneratorOptions } from './schema'
55

66
/**
7-
* `nx g @simondotm/nx-firebase:init`
8-
*
7+
* `nx g @simondotm/nx-firebase:init`
8+
*
99
* Ensures the necessary firebase packages are installed in the nx workspace
1010
* It also adds `@nx/node` if it is not already installed
1111
*
@@ -20,4 +20,3 @@ export async function initGenerator(
2020
}
2121

2222
export default initGenerator
23-

packages/nx-firebase/src/generators/init/lib/add-dependencies.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import {
33
readJson,
44
Tree,
55
addDependenciesToPackageJson,
6+
detectPackageManager,
7+
logger,
68
} from '@nx/devkit'
79
import { workspaceNxVersion } from '../../../utils'
810
import { packageVersions } from '../../../__generated__/nx-firebase-versions'
@@ -20,10 +22,12 @@ export function addDependencies(tree: Tree): GeneratorCallback {
2022
function addDependencyIfNotPresent(
2123
packageName: string,
2224
packageVersion: string,
23-
) {
25+
): boolean {
2426
if (!packageJson.dependencies || !packageJson.dependencies[packageName]) {
2527
dependencies[packageName] = packageVersion
28+
return true
2629
}
30+
return false
2731
}
2832
function addDevDependencyIfNotPresent(
2933
packageName: string,
@@ -34,7 +38,9 @@ export function addDependencies(tree: Tree): GeneratorCallback {
3438
!packageJson.devDependencies[packageName]
3539
) {
3640
devDependencies[packageName] = packageVersion
41+
return true
3742
}
43+
return false
3844
}
3945

4046
// Firebase packages are not managed by the plugin
@@ -49,8 +55,19 @@ export function addDependencies(tree: Tree): GeneratorCallback {
4955
`^${packageVersions.firebaseFunctions}`,
5056
)
5157

52-
//SM: not convinced we should be adding tslib in this plugin
53-
//addDependencyIfNotPresent('tslib', tsLibVersion)
58+
// if the workspace uses pnpm, we need to add the @google-cloud/functions-framework package
59+
if (detectPackageManager() === 'pnpm') {
60+
if (
61+
addDependencyIfNotPresent(
62+
'@google-cloud/functions-framework',
63+
`^${packageVersions.googleCloudFunctionsFramework}`,
64+
)
65+
) {
66+
logger.info(
67+
`This workspace is using pnpm, adding '@google-cloud/functions-framework' dependency for firebase functions compatibility\nSee https://github.com/firebase/firebase-tools/issues/5911#issuecomment-1730263400\n\n`,
68+
)
69+
}
70+
}
5471

5572
// firebase dev dependencies
5673
addDevDependencyIfNotPresent(

0 commit comments

Comments
 (0)