Skip to content

Non-Default Server Core + Driver Exports Unavailable via ESM #8755

@joealden

Description

@joealden

Describe the bug

Due to how exports are handled in https://github.com/cube-js/cube/blob/master/packages/cubejs-server-core/index.js, Node's CJS -> ESM conversion doesn't match what the TS types say are exposed.

Note that this problem does not happen for @cubejs-backend/server, as exports are actually defined on module.exports (module.exports.x = y) rather than module.exports being set to an object value module.exports = { x: y }.

So with this in mind, I believe Node treats module.exports = ... as only the default export in ESM, whereas named exports need to be defined directly on module.exports.

Maybe the for of logic will still work if done directly on the export (module.exports[key] = module)?

ESM import examples for @cubejs-backend/server-core

import { CubejsServerCore } from "@cubejs-backend/server-core"
console.log(CubejsServerCore); // undefined, but TS doesn't complain

import * as Cube from "@cubejs-backend/server-core"
console.log(Cube.CubejsServerCore); // undefined, but TS doesn't complain

import CubejsServerCore from "@cubejs-backend/server-core"
console.log(CubejsServerCore); // defined as expected 

ESM import examples for @cubejs-backend/server

import { CubejsServer } from "@cubejs-backend/server";
console.log(CubejsServer); // defined as expected 

import * as Cube from "@cubejs-backend/server"
console.log(Cube.CubejsServer); // defined as expected 

import CubejsServer from "@cubejs-backend/server";
console.log(CubejsServer); // defined as expected

Comparison of what Node sees the modules to contain (note everything getting added to default):

{
  "@cubejs-backend/server-core": [Module: null prototype] {
    default: <ref *1> [class CubejsServerCore] {
      driverDependencies: [Function: driverDependencies],
      lookupDriverClass: [Function: lookupDriverClass],
      createDriver: [Function: createDriver],
      getDriverMaxPool: [AsyncFunction: getDriverMaxPool],
      FileRepository: [class FileRepository],
      devLogger: [Function: devLogger],
      prodLogger: [Function: prodLogger],
      CubejsServerCore: [Circular *1],
      RefreshScheduler: [class RefreshScheduler],
      OrchestratorApi: [class OrchestratorApi],
      CompilerApi: [class CompilerApi],
      default: [Circular *1]
    }
  },
  "@cubejs-backend/server": [Module: null prototype] {
    CubejsServer: <ref *2> [class CubejsServer] {
      CubejsServer: [Circular *2],
      ServerContainer: [class ServerContainer],
      run: [Function: run]
    },
    ServerContainer: [class ServerContainer],
    default: <ref *2> [class CubejsServer] {
      CubejsServer: [Circular *2],
      ServerContainer: [class ServerContainer],
      run: [Function: run]
    },
    run: [Function: run]
  }
}

To Reproduce
I'm not sure I can get a good repro for this via StackBlitz - but I think the problem is self evident.

Expected behavior
All ways of importing CubejsServerCore should work the same as CubejsServer (and as the type suggest).

Version:
0.36.4

Metadata

Metadata

Assignees

Labels

questionThe issue is a question. Please use Stack Overflow for questions.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions