在 NestJS 应用程序中添加 @keycloak\keycloak-admin-client 包时出错

问题描述 投票:0回答:3

我是 Typescript 和 Nest JS 的新手,正在努力将 Keycloak 集成到我的 Nest JS 应用程序中,以将用户添加到 Keycloak。我添加了 @keycloak\keycloak-admin-client 19.x 包以在 Keycloak 管理 API 上工作。我在执行 Nest JS 应用程序时收到以下错误:

    C:\Program Files\nodejs\node.exe .\dist\main.js
    Uncaught NodeError Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: F:\MyProj\node_modules\@keycloak\keycloak-admin-client\lib\index.js
    require() of ES modules is not supported.
    require() of F:\MyProj\node_modules\@keycloak\keycloak-admin-client\lib\index.js from F:\MyProj\dist\user\user.service.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
    Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from F:\MyProj\node_modules\@keycloak\keycloak-admin-client\package.json.
        at NodeError (<node_internals>/internal/errors.js:279:9)
        at Module._extensions..js (<node_internals>/internal/modules/cjs/loader.js:1102:13)
        at Module.load (<node_internals>/internal/modules/cjs/loader.js:950:32)
        at Module._load (<node_internals>/internal/modules/cjs/loader.js:790:14)
        at Module.require (<node_internals>/internal/modules/cjs/loader.js:974:19)
        at require (<node_internals>/internal/modules/cjs/helpers.js:92:18)
        at <anonymous> (F:\MyProj\src\user\user.service.ts:5:1)
        at Module._compile (<node_internals>/internal/modules/cjs/loader.js:1085:14)
        at Module._extensions..js (<node_internals>/internal/modules/cjs/loader.js:1114:10)
        at Module.load (<node_internals>/internal/modules/cjs/loader.js:950:32)
        at Module._load (<node_internals>/internal/modules/cjs/loader.js:790:14)
        at Module.require (<node_internals>/internal/modules/cjs/loader.js:974:19)
        at require (<node_internals>/internal/modules/cjs/helpers.js:92:18)
        at <anonymous> (F:\MyProj\src\user\user.controller.ts:4:1)
        at Module._compile (<node_internals>/internal/modules/cjs/loader.js:1085:14)
        at Module._extensions..js (<node_internals>/internal/modules/cjs/loader.js:1114:10)
        at Module.load (<node_internals>/internal/modules/cjs/loader.js:950:32)
        at Module._load (<node_internals>/internal/modules/cjs/loader.js:790:14)
        at Module.require (<node_internals>/internal/modules/cjs/loader.js:974:19)
        at require (<node_internals>/internal/modules/cjs/helpers.js:92:18)
        at <anonymous> (F:\MyProj\src\user\user.module.ts:3:1)
        at Module._compile (<node_internals>/internal/modules/cjs/loader.js:1085:14)
        at Module._extensions..js (<node_internals>/internal/modules/cjs/loader.js:1114:10)
        at Module.load (<node_internals>/internal/modules/cjs/loader.js:950:32)
        at Module._load (<node_internals>/internal/modules/cjs/loader.js:790:14)
        at Module.require (<node_internals>/internal/modules/cjs/loader.js:974:19)
        at require (<node_internals>/internal/modules/cjs/helpers.js:92:18)
        at <anonymous> (F:\MyProj\src\app.module.ts:7:1)
        at Module._compile (<node_internals>/internal/modules/cjs/loader.js:1085:14)
        at Module._extensions..js (<node_internals>/internal/modules/cjs/loader.js:1114:10)
        at Module.load (<node_internals>/internal/modules/cjs/loader.js:950:32)
        at Module._load (<node_internals>/internal/modules/cjs/loader.js:790:14)
        at Module.require (<node_internals>/internal/modules/cjs/loader.js:974:19)
        at require (<node_internals>/internal/modules/cjs/helpers.js:92:18)
        at <anonymous> (F:\MyProj\src\main.ts:2:1)
        at Module._compile (<node_internals>/internal/modules/cjs/loader.js:1085:14)
        at Module._extensions..js (<node_internals>/internal/modules/cjs/loader.js:1114:10)
        at Module.load (<node_internals>/internal/modules/cjs/loader.js:950:32)
        at Module._load (<node_internals>/internal/modules/cjs/loader.js:790:14)
        at executeUserEntryPoint (<node_internals>/internal/modules/run_main.js:76:12)
        at <anonymous> (<node_internals>/internal/main/run_main_module.js:17:47)
    Process exited with code 1
This is my package.json
    {
      "name": "MyProj",
      "version": "0.0.1",
      "description": "",
      "author": "",
      "private": true,
      "license": "UNLICENSED",
      "scripts": {
        "prebuild": "rimraf dist",
        "build": "nest build",
        "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
        "start": "nest start",
        "start:dev": "nest start --watch",
        "start:debug": "nest start --debug --watch",
        "start:prod": "node dist/main",
        "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
        "test": "jest",
        "test:watch": "jest --watch",
        "test:cov": "jest --coverage",
        "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
        "test:e2e": "jest --config ./test/jest-e2e.json"
      },
      "dependencies": {
        "@keycloak/keycloak-admin-client": "^19.0.1",
        "@nestjs/axios": "^0.1.0",
        "@nestjs/common": "^9.0.0",
        "@nestjs/config": "^2.2.0",
        "@nestjs/core": "^9.0.11",
        "@nestjs/platform-express": "^9.0.0",
        "reflect-metadata": "^0.1.13",
        "rimraf": "^3.0.2",
        "rxjs": "^7.2.0"
      },
      "devDependencies": {
        "@nestjs/cli": "^9.0.0",
        "@nestjs/schematics": "^9.0.0",
        "@nestjs/testing": "^9.0.0",
        "@types/chai": "^4.3.3",
        "@types/express": "^4.17.13",
        "@types/jest": "28.1.4",
        "@types/mocha": "^9.1.1",
        "@types/node": "^16.0.0",
        "@types/supertest": "^2.0.11",
        "@typescript-eslint/eslint-plugin": "^5.0.0",
        "@typescript-eslint/parser": "^5.0.0",
        "eslint": "^8.0.1",
        "eslint-config-prettier": "^8.3.0",
        "eslint-plugin-prettier": "^4.0.0",
        "jest": "28.1.2",
        "prettier": "^2.3.2",
        "source-map-support": "^0.5.20",
        "supertest": "^6.1.3",
        "ts-jest": "28.0.5",
        "ts-loader": "^9.2.3",
        "ts-node": "^10.0.0",
        "tsconfig-paths": "4.0.0",
        "typescript": "^4.3.5"
      },
      "jest": {
        "moduleFileExtensions": [
          "js",
          "json",
          "ts"
        ],
        "rootDir": "src",
        "testRegex": ".*\\.spec\\.ts$",
        "transform": {
          "^.+\\.(t|j)s$": "ts-jest"
        },
        "collectCoverageFrom": [
          "**/*.(t|j)s"
        ],
        "coverageDirectory": "../coverage",
        "testEnvironment": "node"
      }
    }

更新 - 1

  • 我添加了一个没有Nest JS的单独的typescript项目,安装了@keycloak\keycloak-admin-client包并执行了代码。仍然存在同样的错误。

  • 我已经降级到@keycloak\keycloak-admin-client 18.x版本并且错误消失了!!!

这是否意味着 @keycloak\keycloak-admin-client 19.x 版本存在一些问题?是否有任何解决方案可以处理当前版本的 keycloak-admin-client 软件包?

更新 - 2

  • 我已经克隆了@keycloak\keycloak-admin-client 19.x**版本的代码 并更改了“module”:“CommonJS”,“target”:“ES6” tsconfig.json 文件(与我的 typescript 项目中的相同)。
  • 我已经进行了必要的代码更改以修复由于以下原因引起的错误 已弃用的包(如查询字符串)和方法(如) querystring.stringify 方法以及与 axios 相关的其他一些问题。 最后,我收到以下错误消息:
 Uncaught NodeError Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: d:\keycloak-nodejs-admin-client\node_modules\url-join\lib\url-join.js
require() of ES modules is not supported.
require() of e:\NewArchitecture\keycloak-nodejs-admin-client\node_modules\url-join\lib\url-join.js from d:\keycloak-nodejs-admin-client\lib\resources\agent.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename url-join.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from d:\keycloak-nodejs-admin-client\node_modules\url-join\package.json.
    at NodeError (<node_internals>/internal/errors.js:279:9)
    at Module._extensions..js (<node_internals>/internal/modules/cjs/loader.js:1102:13)
    at Module.load (<node_internals>/internal/modules/cjs/loader.js:950:32)
    at Module._load (<node_internals>/internal/modules/cjs/loader.js:790:14)
    at Module.require (<node_internals>/internal/modules/cjs/loader.js:974:19)
    at require (<node_internals>/internal/modules/cjs/helpers.js:92:18)
    at <anonymous> (d:\keycloak-nodejs-admin-client\src\resources\agent.ts:1:1)
    at Module._compile (<node_internals>/internal/modules/cjs/loader.js:1085:14)
    at Module._extensions..js (<node_internals>/internal/modules/cjs/loader.js:1114:10)
    at Module.load (<node_internals>/internal/modules/cjs/loader.js:950:32)
    at Module._load (<node_internals>/internal/modules/cjs/loader.js:790:14)
    at Module.require (<node_internals>/internal/modules/cjs/loader.js:974:19)
    at require (<node_internals>/internal/modules/cjs/helpers.js:92:18)
    at <anonymous> (d:\keycloak-nodejs-admin-client\src\resources\resource.ts:2:1)
    at Module._compile (<node_internals>/internal/modules/cjs/loader.js:1085:14)
    at Module._extensions..js (<node_internals>/internal/modules/cjs/loader.js:1114:10)
    at Module.load (<node_internals>/internal/modules/cjs/loader.js:950:32)
    at Module._load (<node_internals>/internal/modules/cjs/loader.js:790:14)
    at Module.require (<node_internals>/internal/modules/cjs/loader.js:974:19)
    at require (<node_internals>/internal/modules/cjs/helpers.js:92:18)
    at <anonymous> (d:\keycloak-nodejs-admin-client\src\resources\attackDetection.ts:1:1)
    at Module._compile (<node_internals>/internal/modules/cjs/loader.js:1085:14)
    at Module._extensions..js (<node_internals>/internal/modules/cjs/loader.js:1114:10)
    at Module.load (<node_internals>/internal/modules/cjs/loader.js:950:32)
    at Module._load (<node_internals>/internal/modules/cjs/loader.js:790:14)
    at Module.require (<node_internals>/internal/modules/cjs/loader.js:974:19)
    at require (<node_internals>/internal/modules/cjs/helpers.js:92:18)
    at <anonymous> (d:\keycloak-nodejs-admin-client\src\client.ts:3:1)
    at Module._compile (<node_internals>/internal/modules/cjs/loader.js:1085:14)
    at Module._extensions..js (<node_internals>/internal/modules/cjs/loader.js:1114:10)
    at Module.load (<node_internals>/internal/modules/cjs/loader.js:950:32)
    at Module._load (<node_internals>/internal/modules/cjs/loader.js:790:14)
    at Module.require (<node_internals>/internal/modules/cjs/loader.js:974:19)
    at require (<node_internals>/internal/modules/cjs/helpers.js:92:18)
    at <anonymous> (d:\keycloak-nodejs-admin-client\src\index.ts:2:1)
    at Module._compile (<node_internals>/internal/modules/cjs/loader.js:1085:14)
    at Module._extensions..js (<node_internals>/internal/modules/cjs/loader.js:1114:10)
    at Module.load (<node_internals>/internal/modules/cjs/loader.js:950:32)
    at Module._load (<node_internals>/internal/modules/cjs/loader.js:790:14)
    at executeUserEntryPoint (<node_internals>/internal/modules/run_main.js:76:12)
    at <anonymous> (<node_internals>/internal/main/run_main_module.js:17:47)

如果有人能对此有所帮助的话将会很有帮助!!!

typescript nestjs keycloak keycloak-admin-client
3个回答
2
投票

当我将 @keycloak\keycloak-admin-client 库从 18.x 切换到 19.x 时,我遇到了类似的问题。我观察了你的帖子,希望有人能为我解决这个问题:)但最后我自己做了研究。

开发这个库的人在升级版本 18 -> 19 时将模块系统从 Common JS 更改为 ES 模块。 会有什么后果? 最重要的是,你不能从基于 CommonJS 模块的项目中导入 ES 模块。 您可以在这里阅读更多内容:https://reflectoring.io/nodejs-modules-imports/

所以就我而言,我将我的项目从 CommonJS 模块“升级”到 ES 模块,最后它起作用了。但是......更改模块系统并不像仅更改 TSconfig 那么容易(将“模块”从“CommonJS”更改为“ESNext”是第一步)。您可能会面临更多问题。我的项目很小,所以我在有限的时间内完成了它。我不知道这是否适合你。 如何克服从 CommonJS 切换到 ES 模块时出现的问题,您可以阅读例如这里:

关于您的更新 - 2还有一件事。

您将 @keycloak\keycloak-admin-client 库设置回 CommonJS 模块的想法很好 - 然后您可以从项目中导入 CommonJS 模块。但据我从您附加的代码中了解到:

     Uncaught NodeError Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: d:\keycloak-nodejs-admin-client\node_modules\url-join\lib\url-join.js
require() of ES modules is not supported.
require() of e:\NewArchitecture\keycloak-nodejs-admin-client\node_modules\url-join\lib\url-join.js from d:\keycloak-nodejs-admin-client\lib\resources\agent.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename url-join.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from d:\keycloak-nodejs-admin-client\node_modules\url-join\package.json.

一些 @keycloak\keycloak-admin-client 依赖项(url-join)正在使用 ES 模块,因此 @keycloak\keycloak-admin-client 也需要使用 ES 模块系统。因此,如果您无法在项目中切换模块系统,并且想要将模块系统切换回 @keycloak\keycloak-admin-client 中的 CommonJS,则还需要注意它的依赖关系...

ES 模块越流行,使用它的 npm 库就越多,它就越会强制我们开发者将项目中的模块系统切换到 ES 模块:)


0
投票

不幸的是,Nest JS 仍然不支持导入 ES 模块,所以我们被迫继续使用以前的版本(18.0.2)


0
投票

我能够让它与动态导入一起工作

在解决这些问题时找到了解决方案

https://github.com/nestjs/nest/issues/7021

https://github.com/keycloak/keycloak-nodejs-admin-client/issues/523

import KcAdminClient from '@keycloak/keycloak-admin-client';


@Injectable()
export class KcAdminClientService {
  kcAdminClient: KcAdminClient;

  constructor(private configService: ConfigService) {
    this.initAdmin();
  }

  /**
   * NOTE: @keycloak/keycloak-admin-client in nestjs
   * https://github.com/nestjs/nest/issues/7021
   * https://github.com/keycloak/keycloak-nodejs-admin-client/issues/523
   */
  private dynamicKeycloakImport = async () =>
    new Function("return import('@keycloak/keycloak-admin-client')")();

  private async initAdmin() {
    const KCadmCli = (await this.dynamicKeycloakImport()).default;
    this.kcAdminClient = new KCadmCli({
      baseUrl: this.configService.get('KEYCLOAK_BASE_URL'),
      realmName: this.configService.get('KEYCLOAK_REALM'),
    });
    await this.kcAdminClient.auth({
      username: this.configService.get('KEYCLOAK_REALM_ADMIN_NAME'),
      password: this.configService.get('KEYCLOAK_REALM_ADMIN_PASSWORD'),
      grantType: 'password',
      clientId: 'admin-cli',
    });
  }


  // refresh token logic and other code logic
.
.
.
}

在需要的地方导入服务

© www.soinside.com 2019 - 2024. All rights reserved.