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

Bug: Import error when using tsconfig module: Node16 or newer #4060

Closed
zirkelc opened this issue Jan 17, 2024 · 13 comments · Fixed by #4238 or #4259
Closed

Bug: Import error when using tsconfig module: Node16 or newer #4060

zirkelc opened this issue Jan 17, 2024 · 13 comments · Fixed by #4238 or #4259
Assignees
Labels
auto:bug Related to a bug, vulnerability, unexpected error with an existing feature

Comments

@zirkelc
Copy link
Contributor

zirkelc commented Jan 17, 2024

I have a Node.js project with module format commonjs, I noticed the following errors when import LangChain packages:

import { ChatOpenAI } from "@langchain/openai";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { StringOutputParser } from "@langchain/core/output_parsers";

/* 
The current file is a CommonJS module whose imports will produce 'require' calls; 
however, the referenced file is an ECMAScript module and cannot be imported with 'require'. 
Consider writing a dynamic 'import("@langchain/openai")' call instead.
To convert this file to an ECMAScript module, change its file extension to '.mts', 
or add the field `"type": "module"` to package.json
*/

This issue seems to be related to TypeScripts module resolution. If I use "module": "Node16" or "module": "NodeNext", the issue appears. If I switch to the very old "module": "CommonJS", the issue disappears.

I have seen similar issues here with the recommendation to use require("@langchain/openai") instead of import.
However, I really don't think that is the real issue because LangChain includes both ESM and CJS packages and it should not be any problem to import CJS in TypeScript via import.

Here is a minimal reproducible example:
https://github.com/zirkelc/langchain-node16-issue

Changing the "module" in the tsconfig.json will toggle the import error:

{
  "compilerOptions": {
    // "module": "CommonJS", // => works
    // "module": "NodeNext", // => doesn't work
    // "module": "Node16", // => doesn't work
    "target": "es2022",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
  },
  "include": [
    "index.ts",
  ],
  "exclude": [
    "node_modules/**/*",
  ],
}
Copy link

dosubot bot commented Jan 17, 2024

🤖

Hey there @zirkelc! 👋

I'm Dosu, your friendly neighborhood bot, here to lend a helping hand with all things related to the LangChain repository while you wait for a human maintainer. Whether it's squashing bugs, answering questions, or even helping you become a contributor, I've got your back. Don't hesitate to reach out - that's what I'm here for! 😊

Let's dive into the issue at hand.

Thank you for providing a detailed description of the issue you're facing. This seems to be a common issue when trying to import ECMAScript modules (ESM) in a CommonJS (CJS) module.

Based on the error message you provided, it seems you're trying to import an ECMAScript module in a CommonJS module. This is not allowed because ECMAScript modules use import and export syntax, while CommonJS modules use require and module.exports.

To resolve this issue, you can use dynamic imports which are supported in both CommonJS and ECMAScript modules. Here's an example of how you can modify your code:

export const getExamples = async (query: string, apiKey: string) => {
  const { MemoryVectorStore } = await import("langchain/vectorstores/memory");
  const { OpenAIEmbeddings } = await import("langchain/embeddings/openai");

  // Rest of your code...
};

This approach uses the import() function which returns a promise. This function can be used in an async function to import the module and use it in your code. Please note that this method is asynchronous and the imported modules will not be available immediately. If you need to use the imported modules in a synchronous way, you might need to refactor your code to use promises or async/await.

Also, please ensure that you're using a version of Node.js that supports ECMAScript modules. The current version of Node.js that langchainjs supports is 20 and above. You can find more details about this solution in this issue.

If you still want to use CommonJS, you can change the module system from "commonjs" to "esnext" or "es6" in your TypeScript configuration file (tsconfig.cjs.json). This will allow TypeScript to compile your code to use ECMAScript modules instead of CommonJS. Here's how you can modify your tsconfig.cjs.json:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "module": "esnext",
    "declaration": false
  },
  "exclude": [
    "node_modules",
    "dist",
    "docs",
    "**/tests"
  ]
}

Please note that this change might affect the compatibility of your code with older environments that do not support ECMAScript modules. If you need to support such environments, you might need to use a tool like Babel to transpile your code to a compatible format. You can find more details about this solution in the langchain/tsconfig.cjs.json file.

I hope this helps! If you have any other questions, feel free to ask.

Best,
Dosu

Sources


This response is meant to be useful and save you time. It is not meant to be a precise solution, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.

@dosubot dosubot bot added the auto:bug Related to a bug, vulnerability, unexpected error with an existing feature label Jan 17, 2024
@jacoblee93 jacoblee93 self-assigned this Jan 17, 2024
@jacoblee93
Copy link
Collaborator

Thank you for the report. Will dig in as soon as I can.

@zirkelc
Copy link
Contributor Author

zirkelc commented Jan 18, 2024

Hi @jacoblee93,
I encountered the same issue for NanoID awhile ago: ai/nanoid#422

Gladly, they were able to fix it by: ai/nanoid#422 (comment)

TLDR: the package.json exports need to reference .js and .d.ts files for both ESM and CJ. That means, exporting .js and .d.ts for ESM, and .cjs and .d.cts for CJS. See TS reference

I was able to verify locally by changing the package.json of @langchain/openai and adding a index.d.cts type file:

Before:

  "exports": {
    ".": {
      "types": "./index.d.ts",
      "import": "./index.js",
      "require": "./index.cjs"
    },
    "./package.json": "./package.json"
  },

After:

  "exports": {
    ".": {
      "require": {
        "types": "./index.d.cts",
        "default": "./index.cjs"
      },
      "import": {
        "types": "./index.d.ts",
        "default": "./index.js"
      }
    },
    "./package.json": "./package.json"
  },

The new index.d.cts is a copy of the existing index.d.ts:

export * from './dist/index.js'

I hope this helps you. Let me know if I can do anything else!

@jacoblee93
Copy link
Collaborator

That's extremely helpful! Thanks so much.

I think with all of the integration packages we're splitting out we should get some kind of scaffolding lib in place along with this to avoid excessive copy paste...

@thibautvdu
Copy link

I'm facing the same issue, and unfortunately I have to stick to NodeNext for module resolution. Any work around ?

@zirkelc
Copy link
Contributor Author

zirkelc commented Feb 1, 2024

@thibautvdu it's a TS-only error, so you can @ts-ignore these errors as a workaround.

@jacoblee93
Copy link
Collaborator

This should be fixed in the latest versions of langchain, @langchain/core, @langchain/community, and @langchain/openai! Please reopen if it persists.

@thibautvdu
Copy link

Hi @jacoblee93 thanks a lot for the update ;

The issue is solved for the aforementioned packages, but is still present with @langchain/misralai

@jacoblee93
Copy link
Collaborator

Will push a new version of all integration packages today and update you 👍

@zirkelc
Copy link
Contributor Author

zirkelc commented Mar 8, 2024

Hi @jacoblee93

this issue is mainly fixed, but I noticed the @langchain/openai still has an incomplete exports declaration:

"exports": {
".": {
"types": {
"import": "./index.d.ts",
"require": "./index.d.cts",
"default": "./index.d.ts"
},
"import": "./index.js",
"require": "./index.cjs"
},

Will you going to change this package too?

@jacoblee93
Copy link
Collaborator

Oh crap thanks. Will patch today.

@jacoblee93 jacoblee93 reopened this Mar 8, 2024
@jacoblee93
Copy link
Collaborator

Hey, this slipped my mind. Fixing now.

@jacoblee93
Copy link
Collaborator

Wait no @zirkelc I think that is the correct and expected output at this point? We didn't go with exactly what was suggested above.

If it's still causing problems, let me know and we can reopen.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto:bug Related to a bug, vulnerability, unexpected error with an existing feature
Projects
None yet
3 participants