Open ColbyTresness opened 6 years ago
@ColbyTresness - you brought this up, but putting here for posterity: We'll wait until node.js has ES6 style export capabilities, and not worry about trying to enable an experimental node feature or transpiling user code (status of feature here).
Assigning myself so I don't forget about this
I expect this is what this is tracking but any thoughts on why when I use things like:
import foo from './foo.js'
export default function() { }
I get errors in functions, where as for other node projects where I use node 10 it seems to work? VS Code is telling me something about CommonJS and I frankly don't know where CommonJS, ES6, and Node overlap and if this is related 😕 . Seems from link above seems like we are waiting for something with node?
EDIT: I think I may understand this now. Have only used this in projects with Babel before so I think it was converting to a node compatible format as node doesn't fully adhere to ES6 it appears? Who knows.. and I thought .NET Core / .NET Standard was strange. Is weird that VS Code prompts me to change this though.
@jeffhollan You're correct - Node currently just supports CJS style exports (that's require
and module.exports = { stuff }
. But with a flag, you can switch on ESM, which is in the experimental phase: https://nodejs.org/docs/latest-v10.x/api/esm.html
@jeffhollan Yes, the fact that VS Code prompts for this is a bug that I brought up with @fiveisprime. We left this issue open though since we'd like to support this once Node does.
Nice thanks. @fiveisprime would be nice if any related code issue we could link
You might try using esm
, which allows seamless interop between cjs and esm in older node versions:
npm i -S esm
// index.js
// ESM polyfill lets us write source code with Modules, while running CJS
// App code is in main.js.
// Set options as a parameter, environment variable, or rc file.
require = require('esm')(module/* , options*/);
module.exports = require('./main.js');
// main.js
export default async function(context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
if (req.query.name || (req.body && req.body.name)) {
context.res = {
// status: 200, /* Defaults to 200 */
body: `Hello ${req.query.name || req.body.name}`,
};
} else {
context.res = {
status: 400,
body: 'ESM: Please pass a name on the query string or in the request body',
};
}
}
Is it okay to write
require = require('esm')(module/* , options*/); module.exports = require('./main.js');
as
module.exports = require('esm')('./main.js');
Flagging this as blocked for now. @mhoeger will provide an update and assign it to the correct milestone once we have more information.
Hi,
Quick check if there are any updates. Thank you!
This is on the way. We’re adding support for ES modules. If you use the .mjs
extension in your function file, you can use ESM syntax. This will be available as a preview feature when running on Node 14.
Any updates on this?
Yes please see our docs for more details. It’s unclear if ES modules will become stable in Node.js 14 so this feature may keep its “preview” label in Azure Functions until Node.js 16 LTS is available on the platform. https://docs.microsoft.com/en-us/azure/azure-functions/functions-reference-node?tabs=v2#ecmascript-modules
Awesome thank you :)
@anthonychu should this be out of Preview now? ES Modules are stable in Node.js 16 now: https://nodejs.org/docs/latest-v16.x/api/esm.html#modules-ecmascript-modules
Yes this should probably be out of preview by now - we will look into it
Hey, since not just Node 16 LTS is stable now but also 18 LTS, how is this ESM support coming? ESM is becoming the new standard.
MAJOR EDIT: I've cleaned up my comment heavily as it showed TWO wrong ways of doing this.
Wow. I'm running an ESM stack with TypeScript. Got this error when trying to start my func:
Worker was unable to load entry point "./dist/index.mjs": Named export 'HttpResponse' not found. The requested module '@azure/functions' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from '@azure/functions';
const { HttpResponse, app } = pkg;
My index.mts
looked like:
import { HttpResponse, app } from '@azure/functions';
app.http('home', {
methods: ['GET'],
authLevel: 'anonymous',
handler: (): HttpResponse => {
return new HttpResponse({
status: 200,
jsonBody: { msg: 'Test succeeded' },
});
},
route: '',
});
And my package.json
contained both "type": "module"
and a "main": "./dist/index.mjs"
. The last one irks me a mite since pure ESM projects should be using "module": "./dist/index.mjs"
not main
- or even exports.*.import
. But that's not part of this ticket.
EDIT: bad code and conclusions removed, replaced by correct code that actually works:
import { HttpResponseInit, app } from '@azure/functions';
app.http('home', {
methods: ['GET'],
authLevel: 'anonymous',
handler: (): HttpResponseInit => {
return {
status: 200,
jsonBody: { msg: 'Test succeeded' },
};
},
route: '',
});
Will update issue with more information later on.