Complex cyclic reset of dependencies of Node module "TypeError: super constructor for" inherit "must have a prototype"

I have a complex Node SDK project that uses some class inheritance for try and javascript static-ify. I use the caching behavior of the Node module to create single-user behavior for the SDK (class Project, shared instance ProjectClient)). For initialization, it looks like this:

var Project = require('./project'),
Project.init(params)
// Project is now an instance of ProjectClient

I have classes of classes of objects for data: Entity(the standard parsed object is a JSON payload) and User(a special type of Entity that contains user properties).

The class ProjectClienthas several methods that allow you to run RESTful API calls, for example. Project.GET(), Project.PUT(). They work great when creating a Project"singleton".

Now I'm trying to create convenience-related methods Entitythat will use ProjectClientRESTful operations , for example. Entity.save(), Entity.refresh().

When I try to import Projectinto Entity:

var Project = require('../project')

I get:

TypeError: The super constructor to `inherits` must have a prototype.
    at Object.exports.inherits (util.js:756:11)

Troubleshooting leads me to what this is related to util.inherits(ProjectUser, ProjectEntity)in User, because if I comment on it, I get this instead:

Uncaught TypeError: ProjectEntity is not a function

inherits? , Entity ? , , (, ), - , :

module.exports = _.assign(module.exports, **ClassNameHere**)

:

Entity

var Project = require('../Project'),
    _ = require('lodash')

var ProjectEntity = function(obj) {
    var self = this

    _.assign(self, obj)

    Object.defineProperty(self, 'isUser', {
        get: function() {
            return (self.type.toLowerCase() === 'user')
        }
    })

    return self
}

module.exports = ProjectEntity

( Entity)

var ProjectEntity = require('./entity'),
    util = require('util'),
    _ = require('lodash')

var ProjectUser = function(obj) {

    if (!ok(obj).has('email') && !ok(obj).has('username')) {
        // This is not a user entity
        throw new Error('"email" or "username" property is required when initializing a ProjectUser object')
    }

    var self = this

    _.assign(self, ProjectEntity.call(self, obj))

    return self
}

util.inherits(ProjectUser, ProjectEntity)

module.exports = ProjectUser

( "singleton", )

'use strict'

var ProjectClient = require('./lib/client')
var Project = {
    init: function(options) {
        var self = this
        if (self.isInitialized) {
            return self
        }
        Object.setPrototypeOf(Project, new ProjectClient(options))
        ProjectClient.call(self)
        self.isInitialized = true
    }
}

module.exports = Project

Client

var ProjectUser = require('./user'),
    _ = require('lodash')

var ProjectClient = function(options) {
    var self = this

    // some stuff happens here to check options and init with default values

    return self
}

ProjectClient.prototype = {
    GET: function() {
        return function() {
            // async GET request with callback
        }
    },
    PUT: function() {
        return function() {
            // async PUT request with callback
        }
    }
}

module.exports = ProjectClient
+4
1

, . Entity Project, Client, User, Entity.

-, . Project, , Entity Project. , . , , . , init Entity, .

/ , . NodeJS docs:

a.js

console.log('a starting');
exports.done = false;
var b = require('./b.js');
console.log('in a, b.done = %j', b.done);
exports.done = true;
console.log('a done');

b.js

console.log('b starting');
exports.done = false;
var a = require('./a.js');
console.log('in b, a.done = %j', a.done);
exports.done = true;
console.log('b done');

main.js

console.log('main starting');
var a = require('./a.js');
var b = require('./b.js');
console.log('in main, a.done=%j, b.done=%j', a.done, b.done);

, main.js . a.js, done, b.js. b.js done. a.js, a.js , ( done). a , b , . ( b.js) (a.done, false), reset done true. a.js require('b.js'). b.js , .

:

main starting
a starting
b starting
in b, a.done = false
b done
in a, b.done = true
a done
in main, a.done=true, b.done=true

, , .

, ... ?

, . , :

a.js

exports.func = function(){ console.log('Hello world'); }
var b = require('./b.js');
console.log('a done');

b.js

var a = require('./a.js');
a.func(); //i'm still incomplete but i got func!
console.log('b done');

:

a.js

b.func(); //b isn't even an object yet.
var b = require('./b.js');
console.log('a done');

b.js

exports.func = function(){ console.log('hello world'); }
var a = require('./a.js');
a.func();
console.log('b done');

, a.js , , - :

a.js

exports.func = function(){ b.func(); }
var b = require('./b.js');
console.log('a done');

b.js

exports.func = function(){ console.log('hello world'); }
var a = require('./a.js');
console.log('b done');

, b, b , . . , .

, a.js , func , b b.js. , , .

+5

Source: https://habr.com/ru/post/1622794/


All Articles