Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] cannot inject any service when used with nx workspace #2417

Closed
pashaie opened this issue Aug 30, 2023 · 2 comments
Closed

[BUG] cannot inject any service when used with nx workspace #2417

pashaie opened this issue Aug 30, 2023 · 2 comments
Assignees
Labels

Comments

@pashaie
Copy link

pashaie commented Aug 30, 2023

Information

  • Version: 7.34.6
  • Packages:
    "@tsed/ajv": "^7.34.6",
    "@tsed/common": "^7.34.6",
    "@tsed/core": "^7.34.6",
    "@tsed/di": "^7.34.6",
    "@tsed/engines": "^7.34.6",
    "@tsed/exceptions": "^7.34.6",
    "@tsed/json-mapper": "^7.34.6",
    "@tsed/logger": "^7.34.6",
    "@tsed/logger-file": "^7.34.6",
    "@tsed/openspec": "^7.34.6",
    "@tsed/platform-cache": "^7.34.6",
    "@tsed/platform-exceptions": "^7.34.6",
    "@tsed/platform-express": "^7.34.6",
    "@tsed/platform-log-middleware": "^7.34.6",
    "@tsed/platform-middlewares": "^7.34.6",
    "@tsed/platform-params": "^7.34.6",
    "@tsed/platform-response-filter": "^7.34.6",
    "@tsed/platform-views": "^7.34.6",
    "@tsed/schema": "^7.34.6",
    "@tsed/swagger": "^7.34.6",

I'm trying to create a mono repo with nx but after choosing a node express app as my app template and using
Migrate from Express.js to add tsed to my app, any @Inject would not wotk and throws 'UNDEFINED_TOKEN_ERROR: Given token is undefined. Have you enabled emitDecoratorMetadata in your tsconfig.json or decorated your class with @Injectable, @Service, ... decorator
I've also checked tsconfig to be sure that emitDecoratorMetadata is true.
commenting out @Injects will run project successfully, but without @Inject it meaningless

Example

main.ts

import { $log } from "@tsed/common";
import { PlatformExpress } from "@tsed/platform-express";
import { Server } from "./Server";

async function bootstrap() {
  try {
    console.log('bootstrap1');
    const platform = await PlatformExpress.bootstrap(Server);
    console.log('bootstrap2');
    await platform.listen();

    process.on("SIGINT", () => {
      platform.stop();
    });
  } catch (error) {
    $log.error({ event: "SERVER_BOOTSTRAP_ERROR", message: error.message, stack: error.stack });
  }
}

bootstrap();

server.ts

import { join } from "path";
import { Configuration, Inject, InjectorService } from "@tsed/di";
import { PlatformApplication } from "@tsed/common";
import "@tsed/platform-express"; // /!\ keep this import
import "@tsed/ajv";
import "@tsed/swagger";
import { config } from "./config/index";
import * as rest from "./controllers/rest/index";
import * as pages from "./controllers/pages/index";

console.log('server1');
@Configuration({
  ...config,
  acceptMimes: ["application/json"],
  httpPort: process.env.PORT || 8083,
  httpsPort: false, // CHANGE
  disableComponentsScan: true,
  mount: {
    "/rest": [
      ...Object.values(rest)
    ],
    "/": [
      ...Object.values(pages)
    ]
  },
  swagger: [
    {
      path: "/doc",
      specVersion: "3.0.1"
    }
  ],
  middlewares: [
    "cors",
    "cookie-parser",
    "compression",
    "method-override",
    "json-parser",
    { use: "urlencoded-parser", options: { extended: true } }
  ],
  views: {
    root: join(process.cwd(), "../views"),
    extensions: {
      ejs: "ejs"
    }
  },
  exclude: [
    "**/*.spec.ts"
  ]
})
export class Server {
  @Inject()
  protected app: PlatformApplication;

  @Configuration()
  protected settings: Configuration;


  constructor() {
    console.log('server2', this);
  }
}

package.json

{
  "name": "project",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {},
  "private": true,
  "dependencies": {
    "@tsed/ajv": "^7.34.6",
    "@tsed/common": "^7.34.6",
    "@tsed/core": "^7.34.6",
    "@tsed/di": "^7.34.6",
    "@tsed/engines": "^7.34.6",
    "@tsed/exceptions": "^7.34.6",
    "@tsed/json-mapper": "^7.34.6",
    "@tsed/logger": "^7.34.6",
    "@tsed/logger-file": "^7.34.6",
    "@tsed/openspec": "^7.34.6",
    "@tsed/platform-cache": "^7.34.6",
    "@tsed/platform-exceptions": "^7.34.6",
    "@tsed/platform-express": "^7.34.6",
    "@tsed/platform-log-middleware": "^7.34.6",
    "@tsed/platform-middlewares": "^7.34.6",
    "@tsed/platform-params": "^7.34.6",
    "@tsed/platform-response-filter": "^7.34.6",
    "@tsed/platform-views": "^7.34.6",
    "@tsed/schema": "^7.34.6",
    "@tsed/swagger": "^7.34.6",
    "ajv": "^8.12.0",
    "axios": "^1.0.0",
    "body-parser": "^1.20.2",
    "compression": "^1.7.4",
    "cookie-parser": "^1.4.6",
    "cors": "^2.8.5",
    "cross-env": "^7.0.3",
    "dotenv": "^16.3.1",
    "dotenv-expand": "^10.0.0",
    "dotenv-flow": "^3.3.0",
    "express": "4",
    "method-override": "^3.0.0",
    "tslib": "^2.3.0"
  },
  "devDependencies": {
    "@nx/esbuild": "16.7.4",
    "@nx/eslint-plugin": "16.7.4",
    "@nx/jest": "16.7.4",
    "@nx/js": "16.7.4",
    "@nx/linter": "16.7.4",
    "@nx/node": "16.7.4",
    "@nx/workspace": "16.7.4",
    "@types/express": "^4.17.17",
    "@types/jest": "^29.4.0",
    "@types/node": "~18.7.1",
    "@typescript-eslint/eslint-plugin": "^5.60.1",
    "@typescript-eslint/parser": "^5.60.1",
    "esbuild": "^0.17.17",
    "eslint": "~8.46.0",
    "eslint-config-prettier": "8.1.0",
    "jest": "^29.4.1",
    "jest-environment-node": "^29.4.1",
    "nx": "16.7.4",
    "prettier": "^2.6.2",
    "ts-jest": "^29.1.0",
    "ts-node": "10.9.1",
    "typescript": "^5.2.2"
  }
}

tsconfig.base.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "rootDir": ".",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es2015",
    "module": "esnext",
    "lib": ["es2020", "dom", "ESNext.AsyncIterable"],
    "skipLibCheck": true,
    "skipDefaultLibCheck": true,
    "baseUrl": ".",
    "paths": {},
    "typeRoots": ["./node_modules/@types"]
  },
  "exclude": ["node_modules", "tmp"]
}

tsconfig.app.json

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/out-tsc",
    "module": "commonjs",
    "types": ["node"],
    "isolatedModules": false,
    "suppressImplicitAnyIndexErrors": false,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "allowSyntheticDefaultImports": true,
    "newLine": "LF",
    "noEmit": true,
    "esModuleInterop": true,
    "resolveJsonModule": true
  },
  "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"],
  "include": ["src/**/*.ts"]
}

nx project.json

{
  "name": "api",
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "sourceRoot": "apps/api/src",
  "projectType": "application",
  "targets": {
    "build": {
      "executor": "@nx/esbuild:esbuild",
      "outputs": ["{options.outputPath}"],
      "defaultConfiguration": "production",
      "options": {
        "platform": "node",
        "outputPath": "dist/apps/api",
        "format": ["cjs"],
        "bundle": false,
        "main": "apps/api/src/main.ts",
        "tsConfig": "apps/api/tsconfig.app.json",
        "assets": ["apps/api/src/assets"],
        "generatePackageJson": true,
        "esbuildOptions": {
          "sourcemap": true,
          "outExtension": {
            ".js": ".js"
          }
        }
      },
      "configurations": {
        "development": {},
        "production": {
          "esbuildOptions": {
            "sourcemap": false,
            "outExtension": {
              ".js": ".js"
            }
          }
        }
      }
    },
    "serve": {
      "executor": "@nx/js:node",
      "defaultConfiguration": "development",
      "options": {
        "buildTarget": "api:build"
      },
      "configurations": {
        "development": {
          "buildTarget": "api:build:development"
        },
        "production": {
          "buildTarget": "api:build:production"
        }
      }
    },
    "lint": {
      "executor": "@nx/linter:eslint",
      "outputs": ["{options.outputFile}"],
      "options": {
        "lintFilePatterns": ["apps/api/**/*.ts"]
      }
    },
    "test": {
      "executor": "@nx/jest:jest",
      "outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
      "options": {
        "jestConfig": "apps/api/jest.config.ts",
        "passWithNoTests": true
      },
      "configurations": {
        "ci": {
          "ci": true,
          "codeCoverage": true
        }
      }
    }
  },
  "tags": []
}
@Romakita
Copy link
Collaborator

Hello @pashaie

I use nx on many project and it works. My config isn't the same but it works.
You've probably forgot something.

My point is if the process works as expected using the Ts.ED CLI or a node process, it works for anything. I won't give you free support for an integration issue ;).

Especially if you don't create a repository to reproduce the example. I will unfortunately not waste time copying all your codes to set up a project and reproduce your problem.

There is an official project example that use Nx here: https://github.com/tsedio/tsed-vite-plugin-ssr-example

I encourage you to checkout this project and compare the code with your project.

See you
Romain

@github-actions
Copy link

🎉 Are you happy?

If you appreciated the support, know that it is free and is carried out on personal time ;)

A support, even a little bit makes a difference for me and continues to bring you answers!

github opencollective

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants