langchain-ai / langchainjs

šŸ¦œšŸ”— Build context-aware reasoning applications šŸ¦œšŸ”—
https://js.langchain.com/docs/
MIT License
12.32k stars 2.08k forks source link

langchain.js module issue #2092

Closed Pavel-Piha closed 4 months ago

Pavel-Piha commented 1 year ago

Could someone suggest me how to to make it work?

[1] const langchain_js_1 = require("llama-node/dist/extensions/langchain.js");
[1]                        ^
[1]
[1] Error [ERR_REQUIRE_ESM]: require() of ES Module D:\test-server\node_modules\llama-node\dist\extensions\langchain.js from D:\test-server\dist\src\chat-service.js not supported.
[1] Instead change the require of langchain.js in D:\test-server\dist\src\chat-service.js to a dynamic import() which is available in all CommonJS modules.
[1]     at Object.<anonymous> (D:\test-server\dist\src\chat-service.js:8:24)
[1]     at Object.<anonymous> (D:\test-server\dist\index.js:5:24) {
[1]   code: 'ERR_REQUIRE_ESM'

I want to use Typescript and ES6 modules in my project

here is my tsconfig.json

{
  "compilerOptions": {
    "outDir": "./dist",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": false,
    "skipLibCheck": true,
    "target": "esNext",
    "module": "commonjs",
    "lib": ["ESNext"]
  },
  "exclude": ["node_modules"]
}
dosubot[bot] commented 1 year ago

Answer generated by a šŸ¤–

Answer

I understand that you're encountering an issue with the langchain.js module in your project. The error message you're seeing is due to an attempt to use require() to import an ES module, which is not supported. ES modules are the official standard format to package JavaScript code for reuse, and they use import and export statements instead of require().

To resolve this issue, you can replace the require() statement with a dynamic import() statement, like so:

import("llama-node/dist/extensions/langchain.js").then(langchain_js_1 => {
  // You can use langchain_js_1 here
});

However, since you're using TypeScript, you might prefer to use import directly:

import * as langchain_js_1 from "llama-node/dist/extensions/langchain.js";

Please note that this solution might require you to adjust your tsconfig.json to allow such imports. Specifically, you might need to change the module option to ESNext or ES2020:

{
  "compilerOptions": {
    "outDir": "./dist",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": false,
    "skipLibCheck": true,
    "target": "esNext",
    "module": "ESNext",
    "lib": ["ESNext"]
  },
  "exclude": ["node_modules"]
}

This is one potential solution to your problem. If you find that this solution works and you believe it's a bug that could impact other users, I encourage you to make a pull request to help others who might encounter the same issue. If this solution doesn't align with your experience, I recommend checking if you're using the latest version of the software, as the issue might have been resolved in a more recent update.

Sources


This response is meant to be useful, save you time, and share context. 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.

jacoblee93 commented 1 year ago

Hey @Pavel-Piha - apologies for the delay!

I have this set as my tsconfig.json for my test project:

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "ES2019",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true
  }
}

Could you try this to get yourself unblocked? I'll try to repro with your config.

jacoblee93 commented 1 year ago

Wasn't able to repro with your setup - can you show how you're trying to import things?

7emretelli commented 1 year ago

Could someone suggest me how to to make it work?

[1] const langchain_js_1 = require("llama-node/dist/extensions/langchain.js");
[1]                        ^
[1]
[1] Error [ERR_REQUIRE_ESM]: require() of ES Module D:\test-server\node_modules\llama-node\dist\extensions\langchain.js from D:\test-server\dist\src\chat-service.js not supported.
[1] Instead change the require of langchain.js in D:\test-server\dist\src\chat-service.js to a dynamic import() which is available in all CommonJS modules.
[1]     at Object.<anonymous> (D:\test-server\dist\src\chat-service.js:8:24)
[1]     at Object.<anonymous> (D:\test-server\dist\index.js:5:24) {
[1]   code: 'ERR_REQUIRE_ESM'

I want to use Typescript and ES6 modules in my project

here is my tsconfig.json

{
  "compilerOptions": {
    "outDir": "./dist",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": false,
    "skipLibCheck": true,
    "target": "esNext",
    "module": "commonjs",
    "lib": ["ESNext"]
  },
  "exclude": ["node_modules"]
}

Try importing dynamically like the example below:

const LLamaCpp = await import("langchain/llms/llama_cpp")
const model = new LLamaCpp.LlamaCpp({ modelPath: "llamaPath" });
anamariadem commented 11 months ago

Has anyone found a fix for this using es2021? I keep experiencing this issue. @jacoblee93 The dynamic import did not work for me.

jacoblee93 commented 11 months ago

So I've just set up a brand new project and it looks like specifically node-llama-cpp doesn't work with CommonJS due to a top level await (other LangChain modules should).

Can you try with a fresh project and the following config (note "type": "module" in package.json:

tsconfig.json

{
  "compilerOptions": {
    "outDir": "./dist",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": false,
    "skipLibCheck": true,
    "target": "esNext",
    "module": "commonjs",
    "lib": ["ESNext"]
  },
  "exclude": ["node_modules"]
}

package.json

{
  "name": "tsproject",
  "packageManager": "yarn@3.5.1",
  "type": "module",
  "devDependencies": {
    "ts-node": "^10.9.1",
    "tsx": "^3.14.0",
    "typescript": "^5.2.2"
  },
  "dependencies": {
    "langchain": "^0.0.168",
    "node-llama-cpp": "^2.7.3"
  }
}
anamariadem commented 11 months ago

@jacoblee93 We have NestJS on backend, that comes with a specific tsconfig, if we switch it to type:"module" in package.json it won't work. There's a thread about this here https://github.com/nestjs/nest/issues/10267

mhuckstepp commented 10 months ago

I was able to work around this import issue in a ts project by using the following import style

const getLlama = async () => {
  const { LLamaCpp } = await import('llama-node/dist/llm/llama-cpp.js');
  const { LLM } = await import('llama-node');
  const llama = new LLM(LLamaCpp);
  return llama;
};
deeeed commented 9 months ago

@mhuckstepp would you have a repo to see? I did try a similar setup but still get the Error [ERR_REQUIRE_ESM]: require() of ES Module / error

mhuckstepp commented 9 months ago

@deeeed Here is my setup

package.json

{
  "name": "strava-image",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "tsc && node dist/index.js",
    "build": "react-scripts build && tsc",
    "test": "jest",
    "build:server": "tsc",
    "dev:server": "ts-node-dev --respawn --transpile-only server/index.ts",
    "start:client": "react-scripts start",
    "test:client": "react-scripts test",
    "dev:client": "react-scripts start",
    "build:client": "react-scripts build"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@emotion/react": "^11.7.1",
    "@emotion/styled": "^11.6.0",
    "@googlemaps/polyline-codec": "^1.0.28",
    "@llama-node/llama-cpp": "^0.1.6",
    "@mui/material": "^5.3.1",
    "@testing-library/jest-dom": "^5.16.1",
    "@testing-library/react": "^12.1.2",
    "@testing-library/user-event": "^13.5.0",
    "axios": "^1.5.1",
    "canvas": "^2.11.2",
    "dayjs": "^1.11.10",
    "dotenv": "^16.3.1",
    "express": "^4.18.2",
    "jimp": "^0.22.10",
    "llama-node": "^0.1.6",
    "mongodb": "4.1",
    "promise-queue": "^2.2.5",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^6.2.1",
    "react-scripts": "^5.0.1",
    "styled-components": "^5.3.3",
    "ts-jest": "^29.1.1",
    "ts-node": "^10.9.1",
    "ts-node-dev": "^2.0.0",
    "web-vitals": "^2.1.4"
  },
  "devDependencies": {
    "@babel/plugin-proposal-private-property-in-object": "^7.16.7",
    "@types/express": "^4.17.19",
    "@types/jest": "^29.5.5",
    "@types/node": "^20.8.6",
    "@types/supertest": "^2.0.14",
    "eslint": "8.51.0",
    "eslint-config-airbnb": "^19.0.4",
    "eslint-config-prettier": "^8.5.0",
    "eslint-plugin-import": "^2.25.4",
    "eslint-plugin-node": "^11.1.0",
    "eslint-plugin-prettier": "^4.0.0",
    "eslint-plugin-react": "^7.28.0",
    "husky": "^7.0.4",
    "jest": "^29.7.0",
    "lint-staged": "^12.3.2",
    "nodemon": "^3.0.1",
    "prettier": "^2.6.0",
    "supertest": "^6.3.3",
    "typescript": "^4"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
--------
tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "target": "es6",
    "noImplicitAny": false,
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "dist",
    "baseUrl": "."
  },
  "include": ["server/**/*"],
  "exclude": ["./dist", "__tests__", "jest.config.js"]
}
--------------------
llama.js
const getLlama = async () => {
  const { LLamaCpp } = await import('llama-node/dist/llm/llama-cpp.js');
  const { LLM } = await import('llama-node');
  const llama = new LLM(LLamaCpp);
  return llama;
};

const config = {
  modelPath: './models/airoboros-13b-gpt4.ggmlv3.q4_0.bin',
  enableLogging: true,
  nCtx: 1024,
  seed: 0,
  f16Kv: false,
  logitsAll: false,
  vocabOnly: false,
  useMlock: false,
  embedding: false,
  useMmap: true,
  nGpuLayers: 0,
};

const getAiText = async (prompt) => {
  try {
    console.log('Loading model, prompt:', prompt);
    const llama = await getLlama();
    await llama.load(config);
    console.log('Loaded model ');
    let responseText = '';
    await llama.createCompletion(
      {
        nThreads: 4,
        nTokPredict: 2048,
        topK: 40,
        topP: 0.1,
        temp: 0.2,
        repeatPenalty: 1,
        prompt,
      },
      (response) => {
        console.log({ response });
        if (response.token && response.completed === false) {
          responseText += response.token;
        }
      },
    );
    return responseText;
  } catch (e) {
    console.log(e);
  }
};

module.exports = { getAiText };
mikjee commented 7 months ago

I faced the same issue, while using import in my TS project. I tried using tsc, ts-node and nodemon, but none of those worked, however I was able to make it work with tsx.

dosubot[bot] commented 7 months ago

šŸ¤–

The error you're encountering, ERR_REQUIRE_ESM, occurs when you're trying to use require() to import an ES module. In Node.js, require() is used for CommonJS modules, not ES modules. ES modules should be imported using the import statement.

In your package.json file, you have specified the "type" as "module", which means that Node.js treats .js files as ES modules. However, you're also providing a CommonJS entry point in your "exports" field with "require": "./index.cjs".

To resolve this issue, you can try one of the following solutions:

  1. Convert your code to use ES modules and use import instead of require(). This might involve changing your TypeScript configuration to output ES modules.

  2. If you want to keep using require(), you can change the "type" field in your package.json to "commonjs". This will make Node.js treat .js files as CommonJS modules.

  3. If you want to use both ES modules and CommonJS, you can use the .mjs extension for ES modules and .cjs for CommonJS modules. Node.js uses the file extension to determine the module system in this case. You would also need to adjust your "exports" field to point to the correct files.

Please note that if you're using TypeScript, you'll need to adjust your tsconfig.json file to match your chosen module system. For example, if you're using ES modules, you should set "module": "ESNext" in your tsconfig.json.

This issue has been encountered before in the langchainjs repository. You can refer to the issue #3662 and the corresponding pull request #3670 for more details.

As for the purpose of the langchain.js module, I wasn't able to find specific information within the repository. However, given the name and the overall purpose of the langchainjs repository, it's likely that langchain.js is a core module for developing applications powered by language models using the LangChain framework.

I hope this helps! If you have any more questions or need further clarification, feel free to ask.

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.