zazoomauro / node-dependency-injection

The NodeDependencyInjection component allows you to standarize and centralize the way objects are constructed in your application.
https://github.com/zazoomauro/node-dependency-injection/wiki
MIT License
281 stars 34 forks source link

Error loading Services #82

Closed alberto-leon-crespo closed 6 years ago

alberto-leon-crespo commented 6 years ago

Hi i became a implementation in my own framework based on express. This is the folder structure:

|-- app
|   |-- app.ts
|   |-- config
|   |   |-- parameters.yaml
|   |   |-- routes.yaml
|   |   `-- services.yaml
|   |-- controllers
|   |   `-- users.controller.ts
|   |-- core
|   |   `-- controller.ts
|   |-- server.ts
|   `-- services
|       `-- dummy.service.ts

I load config file in my app.ts file with this function:

// app/app.ts
private loadDependencyInjection(){
   let container = new ContainerBuilder();
   let loader = new YamlFileLoader(container);
   loader.load('app/config/services.yaml');
   console.log(loader);
   container.compile();
   this.container = container;
}

This is my services.yaml file:

# app/config/services.yaml
services:
    dummy.service:
        class: './../services/dummy.service'

This is my dummy.service file:

class DummyService{
    public getName(){
        return 'DummyService';
    }
}

export default DummyService;

But when i try to load application i get this error:

Error: Cannot find module 'app/services/dummy.service'
    at Function.Module._resolveFilename (module.js:547:15)
    at Function.Module._load (module.js:474:25)
    at Module.require (module.js:596:17)
    at require (internal/module.js:11:18)
    at YamlFileLoader._requireClassNameFromPath (/home/mastercss/node/node_modules/node-dependency-injection/dist/lib/Loader/FileLoader.js:345:14)
    at YamlFileLoader._getDefinition (/home/mastercss/node/node_modules/node-dependency-injection/dist/lib/Loader/FileLoader.js:131:27)
    at YamlFileLoader._parseDefinition (/home/mastercss/node/node_modules/node-dependency-injection/dist/lib/Loader/FileLoader.js:90:47)
    at YamlFileLoader._parseDefinitions (/home/mastercss/node/node_modules/node-dependency-injection/dist/lib/Loader/FileLoader.js:69:16)
    at YamlFileLoader.load (/home/mastercss/node/node_modules/node-dependency-injection/dist/lib/Loader/YamlFileLoader.js:65:12)
    at App.loadDependencyInjection (/home/mastercss/node/app/app.ts:119:16)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! nodejs@1.0.0 dev: `ts-node ./app/server.ts`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the nodejs@1.0.0 dev script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2018-08-18T00_41_54_260Z-debug.log

Do u have any idea of what is wrong?

zazoomauro commented 6 years ago

hi @alberto-leon-crespo ! I think typescript is not supported at the moment! DI tries to load javascripts files and not ts. Can you try to rename your filename to .js instead of .ts

alberto-leon-crespo commented 6 years ago

Hi @zazoomauro ! I rename filename to '.js' but i get the same error. I try to debug program but i cant dump the informatión of path in load process. I tried with console.log, utils.debug and something similar but i cant.

¿how i can debug module to add this funcionality?

zazoomauro commented 6 years ago

@alberto-leon-crespo may be can be a filename error issues. Can you try to remove the dots in the filename? like: instead of dummy.service.js to dummyService.js if success there is bug with dots in the filename

alberto-leon-crespo commented 6 years ago

@zazoomauro removing dot in the filename i get the same error. I try to debug module

zazoomauro commented 6 years ago

@alberto-leon-crespo let me know

alberto-leon-crespo commented 6 years ago

@zazoomauro I debug source to know the problem. When use require in Loader class, path is relative to loader directory in node_modules. I resolve problem with class path with a path like this ../../../../../dist/services/dummyservice. But i think this is not a real solution for this problem. I try to change "node_path" with a package directive moduleSearchPaths but i cant resolve the problem with this. I dont know how to fix that problem.

alberto-leon-crespo commented 6 years ago

@zazoomauro I solve the problem with the next fix in the file Loader.js in method _requireClassNameFromPath.

return require(process.cwd() + "/" + path.join(fromDirectory, classObject)).default;

Can u fix that?

zazoomauro commented 6 years ago

@alberto-leon-crespo I stil not convinced. process.cwd() contains exactly the same value of fromDirectory Can you please show me the output of your fromDirectory parameter? Can you please show me the output of your this.filePath parameter?

alberto-leon-crespo commented 6 years ago

@zazoomauro I think load of classes has been relative to project directory, but is only a opinion. Here values of fromDirectory and this.filePath:

fromDirectory: app/config this.filePath: app/config/services.yaml

zazoomauro commented 6 years ago

@alberto-leon-crespo I know what is going on. Can u please send the ABSOLUTE path during your configuration file loader? So instead of this

loader.load('app/config/services.yaml');

use something like this:

loader.load(path.join(__dirname, 'app/config/services.yaml'));
zazoomauro commented 6 years ago

Then we can discuss if only enabling absolute path during loading is good or bad. We can enable a flag to enable relative file path loading... etc.. An easy fix could be check if the file path is absolute or relative and do the magic depending on this. What do you think @alberto-leon-crespo ?

alberto-leon-crespo commented 6 years ago

I think is good idea. I try to load config file with loader.load(path.join(__dirname, 'app/config/services.yaml'));. BTW i can fix the problem until you publish enchancement.

zazoomauro commented 6 years ago

@alberto-leon-crespo should be ready for the 2.1 version.

zazoomauro commented 6 years ago

I don´t think this can be done... after further investigation, we are just sending a string value as a function parameter. No way to join the whole path to make it absolute. No way to ask the user to provide __dirname value

alberto-leon-crespo commented 6 years ago

I can fix the problem using absolute path to load config file.

loader.load(process.cwd() + '/' + this.fixRoute + '/config/services.yaml');