-
Notifications
You must be signed in to change notification settings - Fork 163
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
Support ES Modules #292
Support ES Modules #292
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Looks good, I'll test when I get back in office. I added a few comments and suggestions.
src/loader.ts
Outdated
* | ||
* @returns {string} Module format ('commonjs' or 'module') | ||
*/ | ||
function moduleFormat(modulePath: string): 'commonjs' | 'module' { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a library that already implements this logic? It might not be unique to this module.
Maybe we can use this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newbie question: Do we prefer to use an external package when possible or is there any reason to limit external deps in this repo?
The list of deps for this repo was pretty slim, and I had small amount of hesitation adding new ones. The package you linked seems to be well tested, but I can imagine going the other route and beefing up the unit tests for this function rather than adding a dep.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If an external package seems useful, not abandoned, and genetic for the problem, then use it. I like to remove code that isn't unique to this library / i.e. could be used in other packages as package dependencies. We do keep dependencies small in general.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I took a closer look at https://www.npmjs.com/package/is-file-esm 's source code. I'm being very nitpicky, but it seems to me that it has bit more complex implementation than what I have here. To be fair, it does more, but we don't need those extra functiond ality.
I lean towards keeping couple of lines and keep this logic to ourselves, but that's just me coming from go-world where I'm used to doing things like this. If you think we should opt-in to use that package, I'll be happy to revise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops. Discovered that is-file-esm
makes use of queueMicroStack
in https://github.com/davidmarkclements/is-file-esm/blob/master/index.js#L9 which is only available on NodeJS 11 and up.
I think functions framework needs to work for nodejs10 for the foreseeable future. Does this make using the library a deal breaker?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, hmmm.
Let's keep the lines here then.
Aside, Node 12 should be latest LTS but we need to update min engine to that. But I'm not sure if that will take a bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a bunch!
Main test
export const helloWorld = (req, res) => {
res.send('Hello, World!');
};
Works as expected. Other testing
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, this looks good. Thanks for doing this!
@taeold It seems like this PR needs some logic for windows for ESM support. Maybe we need to add something like a Error I see:
We could also consider not supporting ESM for Windows for now. |
Related nodejs/node#31710 |
@grant The fix to support Windows seems pretty straightforward. |
@matthewrobertson I re-approved running the last checks. Over to you. |
@taeold awesome work, I'm very excited for this contribution, from the perspective of someone who helps maintain our client libraries. |
LGTM, thank you! |
@taeold I don't understand how this is supposed to work for There's The only way I could figure out to make import { promises: fs } from 'fs';
// -----------------
// In getUserFunction()
const _path = path.resolve(codeLocation, './index.mjs')
await fs.stat(_path);
functionModulePath = _path; |
@aryehb Can you clarify? Are saying that the functions-framework does not currently work with As for
I |
I see what you mean. I was able to get it to work using My issue was that I was using the I'm not sure why there is a |
Updates
loader.js
'sgetUserFunction
to detect and load user code packaged as an ES module.To determine whether user code is ES Module or CommonJS, we use the following "algorithm" as described in NodeJS package documentation:
Note that dynamic import function used to load ES modules is only available on NodeJS v13.2.0 and up (proof). The code throws an error if the version of NodeJS on the running process is less than v13.2.0. (In practice, this means that GCF users must use nodejs14 if they want to deploy a function packaged as an ES module).
Fixes #233