Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google Cloud functions framework not working when upgrading Nx from 17.0.3 -> 17.1.3 #182

Closed
abedzantout opened this issue Nov 23, 2023 · 30 comments · Fixed by nrwl/nx#20505

Comments

@abedzantout
Copy link

abedzantout commented Nov 23, 2023

Running a cloud function used to work with v17.0.x

npx @google-cloud/functions-framework --source=dist/apps/cloud-functions --target=CloudFunctions

Function 'CloudFunctions' is not defined in the provided module.
Did you specify the correct target function to execute?
Could not load the function, shutting down.

From what I realized: the build in the dist is different between the two versions:

Nx Report (17.0.3):

 Node   : 20.9.0
   OS     : darwin-arm64
   npm    : 10.2.4
   
   nx (global)        : 17.0.3
   nx                 : 17.0.3
   @nx/js             : 17.0.3
   @nx/jest           : 17.0.3
   @nx/linter         : 17.0.3
   @nx/eslint         : 17.0.3
   @nx/workspace      : 17.0.3
   @nx/angular        : 17.0.3
   @nx/cypress        : 17.0.3
   @nx/devkit         : 17.0.3
   @nx/esbuild        : 17.0.3
   @nx/eslint-plugin  : 17.0.3
   @nx/nest           : 17.0.3
   @nx/node           : 17.0.3
   @nrwl/tao          : 17.0.3
   @nx/web            : 17.0.3
   @nx/webpack        : 17.0.3
   typescript         : 5.1.6
   ---------------------------------------
   Community plugins:
   @nx-extend/gcp-functions : 10.0.1

Compiled version before update (17.0.3):

/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it uses a non-standard name for the exports (exports).
(() => {
var exports = __webpack_exports__;

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.CloudFunctions = void 0;
const { foo = 'testBar' } = process.env;
const CloudFunctions = async (req, res) => {
    res.status(200).send(foo);
};
exports.CloudFunctions = CloudFunctions;

})();

var __webpack_export_target__ = exports;
for(var i in __webpack_exports__) __webpack_export_target__[i] = __webpack_exports__[i];
if(__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true });
/******/ })()
;
//# sourceMappingURL=main.js.map

Nx Report (17.1.3):

 Node   : 20.9.0
   OS     : darwin-arm64
   npm    : 10.2.4
   
   nx (global)        : 17.1.3
   nx                 : 17.1.3
   @nx/js             : 17.1.3
   @nx/jest           : 17.1.3
   @nx/linter         : 17.1.3
   @nx/eslint         : 17.1.3
   @nx/workspace      : 17.1.3
   @nx/angular        : 17.1.3
   @nx/cypress        : 17.1.3
   @nx/devkit         : 17.1.3
   @nx/esbuild        : 17.1.3
   @nx/eslint-plugin  : 17.1.3
   @nx/nest           : 17.1.3
   @nx/node           : 17.1.3
   @nrwl/tao          : 17.1.3
   @nx/web            : 17.1.3
   @nx/webpack        : 17.1.3
   nx-cloud           : 16.5.2
   typescript         : 5.2.2
   ---------------------------------------
   Community plugins:
   @nx-extend/gcp-functions : 10.0.1

Compiled version after update (17.1.3):

/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it uses a non-standard name for the exports (exports).
(() => {
var exports = __webpack_exports__;

Object.defineProperty(exports, "__esModule", ({ value: true }));
const { foo = 'testBar' } = process.env;
const CloudFunctions = async (req, res) => {
    res.status(200).send(foo);
};
exports.CloudFunctions = CloudFunctions;

})();

/******/ })()
;
//# sourceMappingURL=main.js.map

@TriPSs
Copy link
Owner

TriPSs commented Nov 23, 2023

Could you elaborate a bit more? What are the differences, what version of nx-extend (run nx report).

PS: There is also a runner inside the nx-extend package that can run all your functions instead of only one at a time,

@abedzantout
Copy link
Author

abedzantout commented Nov 23, 2023

@TriPSs Updated my original post.

Will check the runner out thanks! is it part of the same package or a different one?

@TriPSs TriPSs changed the title Error when upgrading to nx 17.1.3 Google Cloud functions framework not working when upgrading Nx from 17.0.3 -> 17.1.3 Nov 23, 2023
@TriPSs
Copy link
Owner

TriPSs commented Nov 23, 2023

It is, you can generate the runner project with nx g @nx-extend/gcp-functions:init-runner, this will generate a project with an main.ts file where you can import all your functions, note: the runner uses the deploy target of the project to set it up correctly (for pub/sub, bucket event or http, see the code here).

Regarding your issue: could it be that something within your tsconfig.json changed that caused the difference in ouput or is everything the same but only the nx version difference? Will check what Nx did with the webpack package as the build of gcp-functions uses that one to build.

@abedzantout
Copy link
Author

Createing a completely brand new project - same error.

Will give your runner a try, thank you!

@TriPSs
Copy link
Owner

TriPSs commented Nov 23, 2023

Could you also give it a try typescript: 5.1.6 (same version when the build was still ok)

@TriPSs
Copy link
Owner

TriPSs commented Nov 23, 2023

Also wondering if it works if you do the following:

const functions = require('@google-cloud/functions-framework');

functions.http('helloWorld', (req, res) => {
  res.send('Hello, World');
});

@abedzantout
Copy link
Author

abedzantout commented Nov 23, 2023

Could you also give it a try typescript: 5.1.6 (same version when the build was still ok)

This one works. The new angular however forces us to use to use >=5.2

@abedzantout
Copy link
Author

Also wondering if it works if you do the following:

const functions = require('@google-cloud/functions-framework');

functions.http('helloWorld', (req, res) => {
  res.send('Hello, World');
});

this does not

@TriPSs
Copy link
Owner

TriPSs commented Nov 24, 2023

Could you also give it a try typescript: 5.1.6 (same version when the build was still ok)

This one works. The new angular however forces us to use to use >=5.2

Interesting, not sure if we can do something about it here.

@abedzantout
Copy link
Author

abedzantout commented Nov 29, 2023

Hey @TriPSs,

I think until google updates their typescript package to the latest typescript, you're right there isn't much we can do.

I tried running your runner, I'm encountering this error:

The "@nx/node" package does not support Nx executors.
Error: Unable to resolve @nx/node:execute.
The "@nx/node" package does not support Nx executors.

Here's my main.ts:

import { bootstrapRunner } from '@nx-extend/gcp-functions/runner';

/* eslint-disable @nx/enforce-module-boundaries */
bootstrapRunner(
  new Map([['cloud-functions', import('../../cloud-functions/src/main')]]),
);

Here's the generated project.json:

{
  "name": "cloud-functions-runner",
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "projectType": "application",
  "sourceRoot": "apps/cloud-functions-runner/src",
  "targets": {
    "_build": {
      "executor": "@nx/node:build",
      "outputs": ["{options.outputPath}"],
      "options": {
        "outputPath": "dist/apps/cloud-functions-runner",
        "main": "apps/cloud-functions-runner/src/main.ts",
        "tsConfig": "apps/cloud-functions-runner/tsconfig.app.json"
      }
    },
    "serve": {
      "executor": "@nx/node:execute",
      "options": {
        "buildTarget": "cloud-functions-runner:_build"
      }
    }
  },
  "tags": []
}

Is there something I've missed? Thanks!

@TriPSs
Copy link
Owner

TriPSs commented Nov 29, 2023

Sorry for that, just now noticed that when updating the code to the latest runner I did not update the generating of the runner, can you change your json to the following:

{
  "name": "cloud-functions-runner",
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "projectType": "application",
  "sourceRoot": "apps/cloud-functions-runner/src",
  "targets": {
    "_build": {
      "executor": "@nx/webpack:webpack",
      "outputs": ["{options.outputPath}"],
      "options": {
        "outputPath": "dist/apps/cloud-functions-runner",
        "main": "apps/cloud-functions-runner/src/main.ts",
        "tsConfig": "apps/cloud-functions-runner/tsconfig.app.json",
        "compiler": "tsc",
        "target": "node",
        "namedChunks": true
      }
    },
    "serve": {
      "executor": "@nx/js:node",
      "options": {
        "buildTarget": "cloud-functions-runner:_build"
      }
    }
  },
  "tags": []
}

Let me know if it works or if you get other issues.

@abedzantout
Copy link
Author

Amazing, and how does it register the routes and call the functions? Do we need to set up explicitely the endpoints names?

@TriPSs
Copy link
Owner

TriPSs commented Nov 29, 2023

Based on the info inside the projects deploy info it will build an endpoint, the runner should also log all the endpoints it registeres.

So each function needs to be added to the map, with map<nx project name, import to main file>. They can than be called like localhost:9000/

@abedzantout
Copy link
Author

[Nest] 31115  - 29/11/2023, 09:56:28   DEBUG [Runner] Register http -> "/cloud-functions"
[Nest] 31115  - 29/11/2023, 09:56:28   DEBUG [Runner] Register http -> "/_check/health"

/_check/health calls fine and returns empty.
/cloud-functions returns this error:

[Nest] 31115 - 29/11/2023, 10:04:38 ERROR [ExceptionsHandler] endpoint.func is not a function

@TriPSs
Copy link
Owner

TriPSs commented Nov 29, 2023

Could you share the project.json of that cloud function?

@abedzantout
Copy link
Author

abedzantout commented Nov 29, 2023

It's the same one you provided above:

{
  "name": "cloud-functions-runner",
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "projectType": "application",
  "sourceRoot": "apps/cloud-functions-runner/src",
  "targets": {
    "_build": {
      "executor": "@nx/webpack:webpack",
      "outputs": ["{options.outputPath}"],
      "options": {
        "outputPath": "dist/apps/cloud-functions-runner",
        "main": "apps/cloud-functions-runner/src/main.ts",
        "tsConfig": "apps/cloud-functions-runner/tsconfig.app.json",
        "compiler": "tsc",
        "target": "node",
        "namedChunks": true
      }
    },
    "serve": {
      "executor": "@nx/js:node",
      "options": {
        "buildTarget": "cloud-functions-runner:_build"
      }
    }
  },
  "tags": []
}

@TriPSs
Copy link
Owner

TriPSs commented Nov 29, 2023

This is the of the runner, I mean the one of the actual function, since the runner uses the project.json of the imported projects inside the map and than uses the target where the executor is @nx-extend/gcp-functions:deploy, based on that it builds the endpoint.

For example, it uses the required entryPoint option of deploy to determine what code to use from the main.ts

@abedzantout
Copy link
Author

abedzantout commented Nov 29, 2023

{
  "name": "cloud-functions",
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "projectType": "application",
  "sourceRoot": "apps/cloud-functions/src",
  "targets": {
    "lint": {
      "executor": "@nrwl/linter:eslint",
      "options": {}
    },
    "test": {
      "executor": "@nx/jest:jest",
      "options": {
        "jestConfig": "apps/cloud-functions/jest.config.ts",
        "passWithNoTests": true
      }
    },
    "build": {
      "executor": "@nx-extend/gcp-functions:build",
      "options": {
        "generateLockFile": true,
        "outputPath": "dist/apps/cloud-functions",
        "main": "apps/cloud-functions/src/main.ts",
        "tsConfig": "apps/cloud-functions/tsconfig.app.json",
        "assets": []
      },
      "configurations": {
        "production": {
          "optimization": true,
          "extractLicenses": false,
          "inspect": false
        }
      }
    },
    "deploy": {
      "executor": "@nx-extend/gcp-functions:deploy",
      "options": {
        "functionName": "cloud-functions",
        "envVarsFile": "apps/cloud-functions/src/environments/production.yaml"
      }
    }
  },
  "tags": []
}

There's no entryPoint defined here. By the way, this is generated by @nx-extend/gcp-functions:init without any modification.

I've defined the entryPoint and now everything works well.

Thank you!

@TriPSs
Copy link
Owner

TriPSs commented Nov 29, 2023

Sorry for all the issues here, I really need to invest some time and finish + update docs (#152).

The issues we encountered here I updated.

@abedzantout
Copy link
Author

No worries mate, you're doing great work - your library saved me a ton of time.

I'll also find some time to contribute in the upcoming weeks, this is a great project and a great time saver. Thank you

@abedzantout
Copy link
Author

When attempting to deploy, I'm getting the following:

The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable. Logs for this revision might contain more information

Logs state that the healthcheck is failing. Container Healthcheck failed and revision is failing.

This wasn't a problem before, did you face this at any point?

@TriPSs
Copy link
Owner

TriPSs commented Nov 29, 2023

just to make sure, you are deploying the function right? Not the runner?

Double checking: entry point is correct?

@abedzantout
Copy link
Author

Yes the function, and entry point is correct

@TriPSs
Copy link
Owner

TriPSs commented Nov 29, 2023

There is no other error in the logs that could point out why it failed to start?

@TriPSs
Copy link
Owner

TriPSs commented Nov 29, 2023

FYI: I have created an slack for an other opensource project I maintain, if you want you can also join there and maybe share a bit more info on your code.

@abedzantout
Copy link
Author


DEFAULT 2023-11-29T11:52:52.428796Z Function 'CloudFunctions' is not defined in the provided module.
DEFAULT 2023-11-29T11:52:52.428818Z Did you specify the correct target function to execute?
DEFAULT 2023-11-29T11:52:52.429121Z Could not load the function, shutting down.
WARNING 2023-11-29T11:52:53.172518379Z Container called exit(1).

Here are the errors.

And sure, will join!

@abedzantout
Copy link
Author

Downgrading to "@nx/webpack": "17.0.3" temporarely solves the issue.

Reference: nrwl/nx#20349

@TriPSs
Copy link
Owner

TriPSs commented Dec 9, 2023

Nx released the fix (17.2.0)

@TriPSs TriPSs closed this as completed Dec 9, 2023
@TriPSs
Copy link
Owner

TriPSs commented Dec 9, 2023

Good to know: also update to the latest nx-extend version, Nx introduced a couple more issues which are now temporarily solved by the package.

@abedzantout
Copy link
Author

Yea realized that, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants