k8s-operator-node icon indicating copy to clipboard operation
k8s-operator-node copied to clipboard

Import Error

Open MarkCupitt opened this issue 2 years ago • 4 comments

This used to work a couple of months ago ..

I have a file index.mjs contains

import TenantOperator from './modules/operator/tenantoperator.mjs';
var tenantOperator = new TenantOperator();

./modules/operator/tenantoperator.mjs contains this

import Operator from '@dot-i/k8s-operator';
export default class TenantOperator extends Operator {

    constructor() {}
    
    async init() { ... code ... }
}

Node.js V16.18.0 (Same as I had earlier) is now giving this error @dot-i/k8s-operator": "^1.3.5 installed

Uncaught TypeError TypeError: Class extends value #<Object> is not a constructor or null

At first I thought I had a circular reference, but dpdm says I am good

AL that is changed is that I want form a index.js to index.mjs, Im happily importing other commonJS packages

I'm actually stumped at the moment .. Amny suggestions?

MarkCupitt avatar Nov 17 '22 06:11 MarkCupitt

I have been able to get this to work, this guy has the same issue, he describes it probably a little better:

also, this statement from another read may help

set the esModuleInterOp flag for the Typescript compiler. Without this flag module.exports is not set as the default export and the type error was produced.

My Solution (so far) is to install the package, then

Class File: tenantoperator.mjs

import Operator from './node_modules/@dot-i/k8s-operator/dist/operator.js'
export class TenantOperator extends Operator.default {
constructor() {}
}

Then in my main Script:

import { TenantOperator } from './tenantoperator.mjs';
var tenantOperator = new TenantOperator()

Hoping @dot-i could help with this

Deploying to a container in a K8's Prod wil be a little complex .. but probably just a manner of figuring out pathing

MarkCupitt avatar Nov 23 '22 05:11 MarkCupitt

I have the same problem. Import with dist/operator.js does not work for me.

tuler avatar Aug 10 '23 22:08 tuler

The problem is that this package is being built as a CommonJS module, and when running typescript in esmodule mode it is just simply incompatible. There's a decent discussion of the issue here: https://github.com/microsoft/TypeScript/issues/2719

What happens when you import the package is that the default export is exposed as the default property, and the named exports are in their proper positions in the exported object. Doing util.inspect on the import results in:

{                                                                                                                                                  
  ResourceEventType: { Added: 'ADDED', Modified: 'MODIFIED', Deleted: 'DELETED' },                                                                 
  ResourceMetaImpl: [class ResourceMetaImpl],                                                                                                      
  default: [class Operator]                                                                                                                        
}

So, what I ended up doing to import this package is:

import opmod from '@dot-i/k8s-operator'
const { default: Operator, ResourceEventType } = opmod

My tsconfig.json looks like this (and my package.json has type: module):

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ES2022",
    "moduleResolution": "nodenext",
    "esModuleInterop": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "incremental": true,
    "outDir": "dist"
  },
  "include": [
    "src/**/*"
  ]
}

I'm not sure if there's anything the packager can do about this, but one thing I noticed is that import { default as Operator } from '@dot-i/k8s-operator' gave me the exact same result, not sure why it didn't rename the default import, probably something to do with the transpilation process.

joshperry avatar Aug 16 '23 01:08 joshperry

Maybe I should consider not exporting the class as default but named:

export abstract class Operator {
   // ...
}

I plan to switch to and support the new 1.0 of @kubernetes/client-node soon anyway (it's now in rc3) and that may be a good time to apply this breaking change.

dot-i avatar Sep 03 '23 19:09 dot-i