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

Add support ES modules for Firebase Functions #3485

Merged
merged 12 commits into from Jun 28, 2021
Merged

Add support ES modules for Firebase Functions #3485

merged 12 commits into from Jun 28, 2021

Conversation

taeold
Copy link
Contributor

@taeold taeold commented Jun 11, 2021

To import modules packaged as ES module, we have to use import instead of require. Both the emulator and function deploy code hardcodes require to load user's function code and ends up throwing ERR_REQUIRE_ESM when given ES modules.

We will now try using import when require fails with an ERR_REQUIRE_ESM error. This is a bit lazy - we could've detected whether given module is ES module vs CommonJS and dispatch require vs import appropriately - but I think it simplifies the script while still being correct.

Note that this PR doesn't itself provide ES module support for Firebase Functions (#2994); we need Google Cloud Function to provide ES module support first (GoogleCloudPlatform/functions-framework-nodejs#233).

Functions Framework now supports ES modules in 1.9.0! GoogleCloudPlatform/functions-framework-nodejs#301

NOTE ES Module support is available only for Node.js v13 and beyond. This leads to tricky situations where node version on dev's machine might support ES modules while the selected GCF runtime doesn't, and vice versa. Maybe a follow up item for early detection to reduce number of support tickets we might get because of this confusion?

Will fix once released: #2994

@google-cla google-cla bot added the cla: yes Manual indication that this has passed CLA. label Jun 11, 2021
@taeold taeold requested review from inlined and joehan June 11, 2021 19:47
Copy link
Contributor

@joehan joehan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits, but this LGTM

@inlined
Copy link
Member

inlined commented Jun 21, 2021

LGTM to me too. This will go into the firebase runtime code before it hits production, but the discovery is still quite useful.

@taeold taeold changed the title Add support for parsing function triggers from ES modules. Add support for function code packaged as ES modules. Jun 27, 2021
@taeold taeold requested a review from samtstern June 27, 2021 14:48
@@ -567,6 +576,7 @@ async function initializeFirebaseAdminStubs(frb: FunctionsRuntimeBundle): Promis
// Stub the admin module in the require cache
require.cache[adminResolution.resolution] = {
exports: proxiedAdminModule,
path: path.dirname(adminResolution.resolution),
Copy link
Contributor Author

@taeold taeold Jun 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needed to be done - otherwise, the dynamic import called failed with errors like this:

TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
    at new NodeError (node:internal/errors:363:5)
    at validateString (node:internal/validators:119:11)
    at Object.resolve (node:path:1098:7)
    at Function.Module._nodeModulePaths (node:internal/modules/cjs/loader:625:17)
    at cjsPreparseModuleExports (node:internal/modules/esm/translators:258:30)
    at Loader.commonjsStrategy (node:internal/modules/esm/translators:188:35)

@samtstern Think this is safe modification, but I'm 100% unfamiliar with this code path. Let me know if this isn't going to work (I tested things out, and emulator continues to work normally).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems safe to me.

@taeold taeold changed the title Add support for function code packaged as ES modules. Add support ES modules for Firebase Functions Jun 27, 2021
@taeold taeold merged commit 7f99ac5 into master Jun 28, 2021
@taeold taeold deleted the dl-cf3-esm branch June 28, 2021 11:16
devpeerapong pushed a commit to devpeerapong/firebase-tools that referenced this pull request Dec 14, 2021
\To import modules packaged as ES module, we have to use import instead of require. Both the emulator and function deploy code hardcodes require to load user's function code and ends up throwing ERR_REQUIRE_ESM when given ES modules.

We will now try using import when require fails with an ERR_REQUIRE_ESM error. This is a bit lazy - we could've detected whether given module is ES module vs CommonJS and dispatch require vs import appropriately - but I think it simplifies the script while still being correct.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Manual indication that this has passed CLA.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants