在命令行中运行的NestJS脚本内部使用服务

15
我知道如何在命令行中运行脚本,使用npmnpx ts-node [script.ts],就像这里所述一样。
我的问题与此不同,现在我可以运行脚本,那么我可以在项目中使用模块内部的服务吗?假设我有这个结构,通常由其他模块在项目中调用:

foo/foo.module.ts

import { HttpModule, Module } from '@nestjs/common';

@Module({
  providers: [FooService],
  imports: [HttpModule],
  exports: [FooService]
})
export class FooModule { }

foo/foo.service.ts

import { HttpService, Injectable } from '@nestjs/common';

@Injectable()
export class FooService {
    constructor(
        private readonly httpService: HttpService,
    ) {}

    bar() {
        console.log('do stuff');
    }
}

我怎样才能在文件 /src/script.ts 中调用 bar(),并且在保留所有导入的情况下运行 npx ts-node script.ts?谢谢。


1
你有检查过这个包吗?nestjs-command - antoineso
@antoineso 不,我会尝试的。谢谢。 - Ripper346
4个回答

35

假设你有这样一个应用程序模块:

import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';

@Module({
  imports: [
    UsersModule,
  ],
})
export class ApplicationModule {}

用户模块通过以下方式使用UserService:

import { Module } from '@nestjs/common';

@Module({
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}

而且您希望创建一个指令,可以直接从命令行创建新用户。

您可以创建一个名为console.ts的文件,并放入以下内容:

import { NestFactory } from '@nestjs/core';
import { ApplicationModule } from './application.module';
import { UsersService } from './users/users.service';

async function bootstrap() {
  const application = await NestFactory.createApplicationContext(
    ApplicationModule,
  );

  const command = process.argv[2];

  switch (command) {
    case 'create-administrator-user':
      const usersService = application.get(UsersService);
      await usersService.create({
        username: 'administrator',
        password: 'password',
      });
      break;
    default:
      console.log('Command not found');
      process.exit(1);
  }

  await application.close();
  process.exit(0);
}

bootstrap();

现在您可以在package.json中创建以下脚本:

And now in your package.json you can create the following script:

->

现在,您可以在package.json中创建以下脚本:

"execute": "ts-node ./src/console.ts"

现在,您可以像以下示例一样在NestJS上下文中调用自定义命令:

// Using Yarn
yarn execute create-administrator-user

// Using NPM
npm run execute create-administrator-user

1
所以,唯一的问题是我被迫将项目中所有的导入从src/[...]转换为相对路径,因为它无法解析它们。除此之外,它完美地工作。谢谢。 - Ripper346
1
我脑海中浮现出一个问题,如果我的项目中有一些嵌套的定时任务,并且在我运行脚本的同时正好是其中一个定时任务执行的时间,那么它会被执行吗? - Ripper346

5

补充 @Emanuele 的回答。如果您遇到了 src/[...] 相对路径的问题,那么可以尝试用以下命令运行脚本,而不是使用 ts-node: "node -r ts-node/register -r tsconfig-paths/register path_to_script"


目前你的回答不够清晰,请编辑并添加更多细节,以帮助其他人理解它如何回答问题。你可以在帮助中心找到有关如何撰写好答案的更多信息。 - Community

2
一般来说,要使用一个服务,你需要实例化该服务类。Nest通常会在NestFactory.create的过程中完成这个步骤。你可以这样做:
async function bootstrap() {
  const app = await NestFactory.createApplicationContext(FooModule);
  const service = app.get<FooService>(FooService); // this sets the type of service and gets the instance
  service.bar();
  await app.close();
}

现在你只需要编译文件并像通常一样使用node运行它们作为服务器即可。

1

解决相对路径问题,请将此添加到 ts-config 文件中

{
  "ts-node": {
    // Do not forget to `npm i -D tsconfig-paths`
    "require": ["tsconfig-paths/register"]
  }
}

来源: https://typestrong.org/ts-node/docs/paths/

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接