jaydenseric / graphql-upload

Middleware and an Upload scalar to add support for GraphQL multipart requests (file uploads via queries and mutations) to various Node.js GraphQL servers.
https://npm.im/graphql-upload
MIT License
1.42k stars 131 forks source link

const GraphQLUpload = require("graphql-upload/GraphQLUpload.mjs") error but i dont use require #346

Closed Choco-milk-for-u closed 1 year ago

Choco-milk-for-u commented 1 year ago

import * as GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs'; import type { FileUpload } from 'graphql-upload/processRequest.mjs';

Error

const GraphQLUploadError [ERR_REQUIRE_ESM]: require() of ES Module CarRent\server\node_modules\graphql-upload\GraphQLUpload.mjs not supported.
Instead change the require of CarRent\server\node_modules\graphql-upload\GraphQLUpload.mjs to a dynamic import() which is available in all CommonJS modules. = require("graphql-upload/GraphQLUpload.mjs") 

Pleace help

jaydenseric commented 1 year ago

See the required TypeScript compiler options:

https://github.com/jaydenseric/graphql-upload#requirements

Most likely you have configured your TypeScript project to transpile the modules to CJS modules, which results in that error.

Choco-milk-for-u commented 1 year ago

See the required TypeScript compiler options:

https://github.com/jaydenseric/graphql-upload#requirements

Most likely you have configured your TypeScript project to transpile the modules to CJS modules, which results in that error.

Hi! Have i done this right in this time?

//@ts-ignore
const GraphQLUpload = import('graphql-upload/GraphQLUpload.mjs');
//@ts-ignore
const FileUpload = import('graphql-upload/processRequest.mjs');

tsconfig:

{
  "compilerOptions": {
    "allowJs": true,
    "maxNodeModuleJsDepth": 10,
    "module": "Node16",
}
}
jaydenseric commented 1 year ago

Have i done this right in this time?

I don't think so. The TS config looks better, but I'm not sure what you're doing with the code.

If you want to dynamic import an ES module, perhaps because the surrounding module is CJS, you need to do this:

const { default: GraphQLUpload } = await import("graphql-upload/GraphQLUpload.mjs");

Note that you will run into problems with top level await in a CJS module so you will need to put that in an async function or use .then() syntax.

But you can use a regular import if you have TS configured to emit ES modules:

import GraphQLUpload from "graphql-upload/GraphQLUpload.mjs";

This stuff is just general advice around how native JavaScript works, which is beyond the scope of graphql-upload maintenance. I'm happy to help a little bit with general JavaScript advice, but keep in mind I don't always have the time.

Here is the MDN article on dynamic import:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import

Here is a TypeScript article on ESM in Node.js:

https://www.typescriptlang.org/docs/handbook/esm-node.html

Here is the Node.js docs on ESM:

https://nodejs.org/dist/latest-v19.x/docs/api/esm.html

Choco-milk-for-u commented 1 year ago

As i understood after deeply consuming these link with documintation i was not very well knowed about webpack and node eco-system as i should (In fact when i was learning about js i didnt even mention about it). The differens between commonjs and ESM is huge and some of modern package decide to use esm now. Thanks for the links i appreciate it.

jamiesunderland commented 1 year ago

@jaydenseric thank you for this! I would recommend adding this to docs. It's a simple fix for a lot of folks (I'd imagine) and it's a rough developer experience whenever you end up searching closed issues to find accurate/useful documentation. With that said I realize esm migrations is not your responsibility nor the focus of this module and it's everyone's responsibility to educate themselves on evolutions in js ecosystem. You may save yourself a few headaches by appending this to docs though as a pure mjs npm module is still a little cutting edge for most of us.