Error adding @keycloak\keycloak-admin-client package in NestJS application

3.3k Views Asked by At

I am new to Typescript and Nest JS, working to integrate Keycloak in my Nest JS application to add users to Keycloak. I have added @keycloak\keycloak-admin-client 19.x package to work on Keycloak admin API's. I am getting the below error while executing the Nest JS application :

    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"
      }
    }

UPDATE - 1:

  • I have added a separate typescript project without Nest JS, installed @keycloak\keycloak-admin-client package and executed the code. Still the same error persists.

  • I have downgraded to @keycloak\keycloak-admin-client 18.x version and the error disappeared !!!

Does this mean there is some issue in @keycloak\keycloak-admin-client 19.x version? Is there any solutions for working on current version of keycloak-admin-client package?

UPDATE - 2:

  • I have cloned code of @keycloak\keycloak-admin-client 19.x** version and changed "module": "CommonJS","target": "ES6" in it's tsconfig.json file (same as that in my typescript project).
  • I have made necessary code changes to fix errors caused due to deprecated packages like query-string and methods like querystring.stringify methods and few other issues related to axios. Finally, I got the following error message :
 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)

It would be helpful if somebody could throw some light on this !!!

2

There are 2 best solutions below

4
On

unfortunately Nest JS still doesn't support import ES module so we are forced to keep using the previous version (18.0.2)

1
On

I faced similar problem when I switched @keycloak\keycloak-admin-client library from 18.x to 19.x. I observed your post with the hope that someone will solve that for me :) But finally I did research myself.

The guys who develop this library changed module system from Common JS to ES modules when upgrading version 18 -> 19. What are consequences? The most important is that you cannot import ES modules from project which is based on CommonJS modules. More you can read here: https://reflectoring.io/nodejs-modules-imports/

So in my case I 'upgraded' my project from CommonJS modules to ES modules and finally it works. But... changing module system it is not so easy as changing only TSconfig (change "module" from "CommonJS" to "ESNext" is the first step). You can face some more issues. My project was quite small so I managed that in finite time. I don't know if it is option for you. How to overcome issues when switching from CommonJS to ES modules you can read e.g. here:

One more thing regarding your UPDATE - 2.

Your idea to set back @keycloak\keycloak-admin-client library to CommonJS modules was good - then you can import CommonJS modules from your project. But as I understand from the code you attached :

     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.

some @keycloak\keycloak-admin-client dependency (url-join) is using ES modules and therefore @keycloak\keycloak-admin-client needs to use ES module system too. So if you cannot switch module system in your project and want to switch module system back to CommonJS in @keycloak\keycloak-admin-client, you need to take care also about it dependency...

The more the ES modules will be popular, the more npm libraries will be use it, the more it will enforce us, developers, to switch module system in our projects to ES modules :)