简体   繁体   中英

How to run nestjs-console commands in context of Angular / nx workspace

I have a NestJS application as part of an Angular / Nx workspace.

Within the nest application I'm using nestjs-console to run commands (eg to load fixture data).

Per the nestjs-console docs this involves:

  1. Creating a console.ts file
  2. Adding a script in package.json like "console:dev": "ts-node --project apps/api/tsconfig.console.json apps/api/src/console.ts"
  3. Calling it, eg with npm run console:dev -- --help

Now I have used Nx to create a lib of shared code between applications.

This works well for commands under Angular CLI ( test ; serve etc.), but the nestjs-console task understandably fails with:

Error: Cannot find module '@my-workspace/my-lib'

So the question is how to bring the nestjs-console command under the control of Angular CLI (or run NestJS commands in some other way).

I feel it should be possible to add a custom task to angular.json which uses an existing builder and then somehow points to the console command. (I don't feel like I need a custom builder , but I could be wrong about that).

I'm stuck because I'm not so familiar with this environment, and angular.json workspace config .

Any help is appreciated, be it:

  • Advice on approaches
  • Examples I can copy
  • Specific pointers

EDIT

I tried using the NestJS Application Context directly, (rather than via nestjs-console ) and per this blog post running it with ts-node .

This has the same problems as before. I believe this issue is something to do with how ts-node handles paths in tsconfg.

If I change the way the shared code is imported from:

import { HeadwordDto } from '@my-workspace/my-lib';

To:

import { HeadwordDto } from '../../../../../../libs/my-lib/src';

Then everything works, but tslint complains with "library imports must start with @my-workspace/ (nx-enforce-module-boundaries)." I can see how this defeats the point of Nx.

Alternatively, dealing with what I think is the paths issue looks a bit hairy and involves tools like tspath or module-alias . It also does not benefit from Nx goodness.

I have now added a new Architect target to angular.json which is just like the build target (using the @nrwl/node:build builder), except that is builds the desired application context:

"build-console": {
  "builder": "@nrwl/node:build",
  "options": {
    "main": "apps/api/src/console.ts",      // build console application context
    "outputPath": "different/output/path",  // can run alongside app
    ...
  }
},

After this is built then it can be run via node :

node ./different/output/path/main.js –help

EDIT 2

Building on the approach above, it's also possible to use the execute builder to build the console application context continually in a separate terminal window:

"serve-console": {
  "builder": "@nrwl/node:execute",
  "options": {
    "buildTarget": "api:build-console",
    "port": 7778,
    "args": ["--help"]
  }
},

From here I guess the next step could be to make the console application context into a separate app, with its own project in angular.json, and just pull in the needed code. Starting to feel like the Nx team are about 58 steps ahead of me ;-)

Not sure if this is the best solution, but it works. As before, any advice appreciated!

EDIT 3

To expand on this, in response to @Digitrance's question. The approach I ended up using was:

angular.json

{
    ...
    "api": {
      ...
      "architect": {
        ...
        "build-console": {
          "builder": "@nrwl/node:build",
          "options": {
            "outputPath": "dist/apps/api-console",
            "main": "apps/api/src/console.ts",
            "tsConfig": "apps/api/tsconfig.app.json"
          }
        },
        "serve-console": {
          "builder": "@nrwl/node:execute",
          "options": {
            "buildTarget": "api:build-console",
            "port": 7778,
            "args": ["--help"]
          }
        },

/my-repo/apps/api/src/console.ts

import { BootstrapConsole } from 'nestjs-console';
import { AppModule } from './app/app.module';

const bootstrap = new BootstrapConsole({
  module: AppModule,
  useDecorators: true
});
bootstrap.init().then(async app => {
  try {
    await app.init();
    await bootstrap.boot();
    process.exit(0);
  } catch (e) {
    console.error('Error', e);
    process.exit(1);
  }
});

And then commands to run the console:

ng run api:build-console
ng run api:serve-console

node ./dist/apps/api-console/main.js --help
node ./dist/apps/api-console/main.js myCommand

(Note that api was the name of my app).

Hope this helps!

Like you, I had trouble setting this up. My error boiled down to syntax errors, which according to some issues at ts-node github had to do with node not being able to read the imports properly because it was commonjs syntax. My solution was as followed:

  1. Add the tsconfig.console.json next to the tsconfig.app.json in your nx application.
  2. Make sure the tsconfig.console.json contains "module": "commonjs" inside the "compilerOptions" . Other than that I copied tsconfig.app.json.
  3. In the package.json add the following line: "console:dev": "ts-node --project apps/api/tsconfig.console.json -r tsconfig-paths/register apps/api/src/console.ts" to your scripts.

Hope it helps you or anyone else.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM