wessberg / DI-compiler

A Custom Transformer for Typescript that enables compile-time Dependency Injection
MIT License
80 stars 7 forks source link

Does not work with webpack ts-loader #12

Closed unlight closed 2 years ago

unlight commented 3 years ago

No errors while compiling.

But when run:

ReferenceError: DIContainer could not get service: No arguments were given!
wessberg commented 3 years ago

Hi there,

Did you follow these instructions? Also, have you checked the compiled code to see if your calls to .registerSingleton and/or .registerTransient has been updated?

The compiler is highly dependent on the type hierarchy of your application, and it will only be able to function properly if it can trace back the instance of your service container to an instance of DIContainer, so make sure it can.

A minimal repro will help me a lot with the debugging.

NikitaIT commented 3 years ago

same error, it really doesn't seem to work

export interface IMyService {
  //
}
export class MyService implements IMyService {
  s = 3;
}
import { DIContainer } from "@wessberg/di";
import { IMyService, MyService } from "./MyService";

// Instantiate a new container for services
const container = new DIContainer();
new MyService();
container.registerSingleton<IMyService, MyService>();
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _wessberg_di__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @wessberg/di */ "./node_modules/@wessberg/di/dist/esm/index.js");
/* harmony import */ var _MyService__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./MyService */ "./src/MyService.ts");

 // Instantiate a new container for services

var container = new _wessberg_di__WEBPACK_IMPORTED_MODULE_0__.DIContainer();
new _MyService__WEBPACK_IMPORTED_MODULE_1__.MyService();
container.registerSingleton();//# sourceURL=[module]
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvcmVnaXN0ZXJESS50cy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL3N0ZXAucnUvLi9zcmMvcmVnaXN0ZXJESS50cz9kYTVjIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERJQ29udGFpbmVyIH0gZnJvbSBcIkB3ZXNzYmVyZy9kaVwiO1xyXG5pbXBvcnQgeyBJTXlTZXJ2aWNlLCBNeVNlcnZpY2UgfSBmcm9tIFwiLi9NeVNlcnZpY2VcIjtcclxuXHJcbi8vIEluc3RhbnRpYXRlIGEgbmV3IGNvbnRhaW5lciBmb3Igc2VydmljZXNcclxuY29uc3QgY29udGFpbmVyID0gbmV3IERJQ29udGFpbmVyKCk7XHJcbm5ldyBNeVNlcnZpY2UoKTtcclxuY29udGFpbmVyLnJlZ2lzdGVyU2luZ2xldG9uPElNeVNlcnZpY2UsIE15U2VydmljZT4oKTtcclxuIl0sIm1hcHBpbmdzIjoiOzs7QUFBQTtBQUNBO0FBQ0E7QUFFQTtBQUNBO0FBQ0EiLCJzb3VyY2VSb290IjoiIn0=
// vue.config.js
const { di } = require("@wessberg/di-compiler");

console.log("di", di); // ok
module.exports = {
  chainWebpack: (config) => {
    config.module
      .rule("ts")
      .use("ts-loader")
      .tap((options) => {
        return {
          ...options,
          getCustomTransformers: (program) => {
            const res = di({ program });
            console.log(res); // {  before: [ [Function (anonymous)] ], after: [ [Function (anonymous)] ] }
            return res;
          },
        };
      });
  },
};
NikitaIT commented 3 years ago

Default ts-loader vue-cli config:

{
            transpileOnly: true,
            appendTsSuffixTo: ["\\.vue$"],
            happyPackMode: false, // true in prod mode
},

Changes:

-            transpileOnly: true,
+            transpileOnly: false,
+           happyPackMode: false

And

config.module.rule('ts').uses.delete('thread-loader')

And it works.

Are there any ways not to do this? My project took a few minutes to compile instead of a few seconds.

unlight commented 2 years ago

Solved. registerSingleton do the trick