msgraph-sdk-javascript icon indicating copy to clipboard operation
msgraph-sdk-javascript copied to clipboard

Invalid ECMAScript modules

Open simonyarde opened this issue 2 years ago • 4 comments

Bug Report

Issue

I'd like to write valid isomorphic ECMAScript but the following import fails

import { Client } from "./node_modules/@microsoft/microsoft-graph-client/lib/es/src/index.js"

Discussion

Package @microsoft/microsoft-graph-client has invalid ECMAScript modules due to missing file extensions, e.g.

// node_modules\@microsoft\microsoft-graph-client\lib\es\src\index.js
export * from "./content/BatchRequestContent";

Node gives the following error, which is counter-intuitive since the package documentation appears to say it contains ECMAScript modules but node defaults to common-js

import { Client } from "./node_modules/@microsoft/microsoft-graph-client/lib/es/src/index.js"
         ^^^^^^
SyntaxError: Named export 'Client' not found. The requested module './node_modules/@microsoft/microsoft-graph-client/lib/es/src/index.js' is a CommonJS module, which may not support all module.exports as named exports.

If we hack package.json with "type": "module" we'll obviously get

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '...node_modules\@microsoft\microsoft-graph-client\lib\es\src\content\BatchRequestContent'

Almost workaround for Node (but not browser)

In node, we can work around with flag --experimental-specifier-resolution=node and by hacking the @microsoft/microsoft-graph-client/package.json (making deployment difficult)

// index.mjs
import { Client } from "./node_modules/@microsoft/microsoft-graph-client/lib/es/src/index.js"
console.log("OK")
// node_modules\@microsoft\microsoft-graph-client\package.json
// ..
  "type": "module",
// ...
node --experimental-specifier-resolution=node index.mjs
OK

In Azure Web Apps we can get this behaviour via package.json

// package.json
{
  "scripts": {
    "start": "node --experimental-specifier-resolution=node index.mjs",
  },
}

I've spent a little time googling, but can't see if Azure Functions should support package.json scripts.

Related discussion

https://github.com/microsoft/TypeScript/issues/42151

simonyarde avatar Oct 15 '21 10:10 simonyarde

@simonyarde Thank you for reaching out!

The following worked for me with type : module in the package.json of the project importing @microsoft/microsoft-graph-client.

import {Client} from "@microsoft/microsoft-graph-client"

Is the type config set to module in your package.json?

I have the following questions for you:

  1. What is the version of node that you are using?
  2. What is the reason to use the entire path to the ESM entry point instead of simply importing from @microsoft/microsoft-graph-client?
import { Client } from "./node_modules/@microsoft/microsoft-graph-client/lib/es/src/index.js

The @microsoft/microsoft-graph-client export commonjs and es modules. In the package, main config is set to the the commonjs entry point and the module config is set to the esm entry point.

When I set type : module in the package.json of the test project and import @microsoft/microsoft-graph-client, it automatically looks for the ES modules in the dependent library, that is, in @microsoft/microsoft-graph-client .

  1. Can you give me some details of your script/application? Is this code working fine in browser for you?

nikithauc avatar Oct 20 '21 21:10 nikithauc

@nikithauc Thanks for coming back to me.

I think we may be at cross-purposes? My question is about uncompiled ECMAScript, rather than TypeScript or common-js module patttern.

Asked another way, why doesn't the graph module use valid ECMAScript module syntax, i.e. including the file extension?

The following import is valid ECMAScript because it uses the full path and extension, but it will fail in both browsers and node, regardless of the module setting, because the @microsoft/microsoft-graph-client does not contain valid ECMAScript.

import { Client } from "./node_modules/@microsoft/microsoft-graph-client/lib/es/src/index.js`

Here is an example from the graph module containing invalid ECMAScript import (because it does have a file extension) that causes the error on import (browsers and node)

// node_modules\@microsoft\microsoft-graph-client\lib\es\src\index.js
export * from "./content/BatchRequestContent";

If file extensions were added, then we could import the graph module in uncompiled ECMAScript that would run in both browsers and node.

simonyarde avatar Oct 21 '21 09:10 simonyarde

@simonyarde

why doesn't the graph module use valid ECMAScript module syntax, i.e. including the file extension?

Using .mjs file extension is one of the ways to use ES modules in node. The current ES modules are valid.

Here is an example, of using Graph SDK with a .mjs extension script and this works for me. https://github.com/nikithauc/GraphESUsageDemo/blob/main/index.mjs.

Can you please tell me why you using the full path, that is, import { Client } from "./node_modules/@microsoft/microsoft-graph-client/lib/es/src/index.js instead of just referring to the the library entry point?

nikithauc avatar Oct 25 '21 17:10 nikithauc

@nikithauc Now please show me how to write your example isomorphically so that it will run in a browser.

simonyarde avatar Nov 02 '21 23:11 simonyarde

closing out some older issues.

ddyett avatar Jul 25 '23 05:07 ddyett

@ddyett this should be re-opened since it was not actually resolved - Graph API has trouble supporting mjs bundling

onionhammer avatar Jul 28 '23 13:07 onionhammer

I lost hope this would ever get sorted and moved to different tools.

My understanding is that the graph client remains unusable without typescript because the .mjs files contain non-valid javascript import statements.

simonyarde avatar Jul 28 '23 14:07 simonyarde

@simonyarde it's unusable for compiled typescript as well. Opened a new issue #1377

onionhammer avatar Jul 28 '23 14:07 onionhammer

Thanks @onionhammer that's good to know.

simonyarde avatar Jul 28 '23 14:07 simonyarde