NESTJS 中的 TypeORM 实体 - 不能在模块外使用导入语句

Ant*_*ton 52 typeorm nestjs

使用 'nest new' 命令开始新项目。工作正常,直到我向其中添加实体文件。

得到以下错误:

从'typeorm'导入{实体,列,PrimaryGeneratedColumn};

^^^^^^

语法错误:不能在模块外使用导入语句

我想念什么?

将实体添加到模块:

import { Module } from '@nestjs/common';
import { BooksController } from './books.controller';
import { BooksService } from './books.service';
import { BookEntity } from './book.entity';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [TypeOrmModule.forFeature([BookEntity])],
  controllers: [BooksController],
  providers: [BooksService],
})
export class BooksModule {}
Run Code Online (Sandbox Code Playgroud)

app.module.ts:

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Connection } from 'typeorm';
import { BooksModule } from './books/books.module';

@Module({
  imports: [TypeOrmModule.forRoot()],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
Run Code Online (Sandbox Code Playgroud)

Jay*_*iel 108

我的假设是您的TypeormModule配置具有如下所示的entities属性:

entities: ['src/**/*.entity.{ts,js}']
Run Code Online (Sandbox Code Playgroud)

或喜欢

entities: ['../**/*.entity.{ts,js}']
Run Code Online (Sandbox Code Playgroud)

您收到的错误是因为您试图ts在js上下文中导入文件。只要您不使用 webpack,您就可以使用它来代替,以便获得正确的文件

entities: [join(__dirname, '**', '*.entity.{ts,js}')]
Run Code Online (Sandbox Code Playgroud)

wherejoin是从path模块导入的。现在__dirname将解析为srcor dist,然后分别找到预期的ts或js文件。如果还有问题,请告诉我。

编辑 1/10/2020

以上假设配置完成的是一个 javascript 兼容文件(.js或在TypeormModule.forRoot()传递的参数中)。如果您使用的是ormconfig.json代替,则应使用

entities: ['src/**/*.entity.{ts,js}']
Run Code Online (Sandbox Code Playgroud)

这样您就可以使用编译后的 js 文件,而没有机会在您的代码中使用 ts 文件。

  • 但这完全是一团糟。不接受 typescript 进行迁移的 typescript ORM... (42认同)
  • 我绝对同意,必须接触到转译的 JS 才能让所有这些混乱工作是一个笑话。 (5认同)
  • Github 上的问题 [#4283](https://github.com/nestjs/nest/issues/4283#issuecomment-597987321) 详细解释了为什么应该使用 JavaScript 从 Dist 文件夹中读取实体。这是我在根文件夹中的`ormconfig.js`中更改的神奇行,您也可以尝试看看。`entities: ['dist/**/*.entity.js']` 是解决方案。 (3认同)
  • `deno` 是唯一的原生打字稿代码运行器。“TypeORM”虽然使用 Typescript,但仍然适用于“Node”和 JavaScript 运行时。也许可以进行改进以接受“ts”文件并在后台将它们编译成 JavaScript,然后删除它们,这样最终用户就看不到它们,但这需要在 TypeORM git 存储库上作为问题提出 (2认同)
  • 实际上,由于 json 语法的原因,整行必须是 "entities": ["dist/**/*.entity.js"]。 (2认同)

小智 27

在 TypeORM 文档中,我找到了Typescript的特定部分。

本节说:

全局安装 ts-node:

npm install -g ts-node
Run Code Online (Sandbox Code Playgroud)

在 package.json 中的 scripts 部分下添加 typeorm 命令

"scripts" {
    ...
    "typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js"    
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样运行命令:

npm run typeorm migration:run
Run Code Online (Sandbox Code Playgroud)

如果需要将带破折号的参数传递给 npm 脚本,则需要在 -- 之后添加它们。比如需要生成,命令是这样的:

npm run typeorm migration:generate -- -n migrationNameHere
Run Code Online (Sandbox Code Playgroud)

这适用于我的文件配置:

{
    "type": "postgres",
    "host": "yourhost",
    "port": 5423,
    "username": "username",
    "password": "password",
    "database": "your_db",
    "synchronize": true,
    "entities": [
        "src/modules/**/*.entity.{ts,js}"
    ],
    "migrations": [
        "src/migrations/**/*.{ts,js}"
    ],
    "cli": {
        "entitiesDir": "src/modules",
        "migrationsDir": "src/migrations"
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以运行 generate 命令。


iY1*_*1NQ 15

正如 Jay McDoniel 在他的回答中所解释的那样,问题似乎是文件中实体文件的模式匹配ormconfig.json:可能是从 javascript 文件(大概是先前转译的打字稿文件)导入的打字稿文件(模块)。

删除 中现有的tsglob 模式应该就足够了ormconfig.json,这样 TypeORM 将只加载 javascript 文件。实体文件的路径应该相对于执行节点的工作目录。

   "entities"   : [
      "dist/entity/**/*.js"
   ],
   "migrations" : [
      "dist/migration/**/*.js"
   ],
   "subscribers": [
      "dist/subscriber/**/*.js"
   ],
Run Code Online (Sandbox Code Playgroud)


ama*_*hit 10

ormconfig.json如官方文档中所述定义实体属性为我解决了这个问题。

// This is your ormconfig.json file

...
"entities": ["dist/**/*.entity{.ts,.js}"]
...
Run Code Online (Sandbox Code Playgroud)


Max*_*Max 7

接下来我在tsconfig.json文件中进行了更改:

"module": "es6"
Run Code Online (Sandbox Code Playgroud)

到:

"module": "commonjs",
Run Code Online (Sandbox Code Playgroud)

它帮助到我


Tom*_*ger 7

还要检查您在实体中的导入。不要这样做import { SomeClassFromTypeorm } from 'typeorm/browser';,因为这可能会导致同样的错误。

我的 IDE 自动导入了错误的包后就发生了这种情况。'/browser'从导入中删除。


lzk*_*ill 5

这就是我设法解决它的方法。使用单个配置文件,我可以在应用程序 boostrap 上或使用 TypeOrm 的 CLI 运行迁移。

\n

src/config/ormconfig.ts

\n
import parseBoolean from \'@eturino/ts-parse-boolean\';\nimport { TypeOrmModuleOptions } from \'@nestjs/typeorm\';\nimport * as dotenv from \'dotenv\';\nimport { join } from \'path\';\n\ndotenv.config();\n\nexport = [\n  {\n    //name: \'default\',\n    type: \'mssql\',\n    host: process.env.DEFAULT_DB_HOST,\n    username: process.env.DEFAULT_DB_USERNAME,\n    password: process.env.DEFAULT_DB_PASSWORD,\n    database: process.env.DEFAULT_DB_NAME,\n    options: {\n      instanceName: process.env.DEFAULT_DB_INSTANCE,\n      enableArithAbort: false,\n    },\n    logging: parseBoolean(process.env.DEFAULT_DB_LOGGING),\n    dropSchema: false,\n    synchronize: false,\n    migrationsRun: parseBoolean(process.env.DEFAULT_DB_RUN_MIGRATIONS),\n    migrations: [join(__dirname, \'..\', \'model/migration/*.{ts,js}\')],\n    cli: {\n      migrationsDir: \'src/model/migration\',\n    },\n    entities: [\n      join(__dirname, \'..\', \'model/entity/default/**/*.entity.{ts,js}\'),\n    ],\n  } as TypeOrmModuleOptions,\n  {\n    name: \'other\',\n    type: \'mssql\',\n    host: process.env.OTHER_DB_HOST,\n    username: process.env.OTHER_DB_USERNAME,\n    password: process.env.OTHER_DB_PASSWORD,\n    database: process.env.OTHER_DB_NAME,\n    options: {\n      instanceName: process.env.OTHER_DB_INSTANCE,\n      enableArithAbort: false,\n    },\n    logging: parseBoolean(process.env.OTHER_DB_LOGGING),\n    dropSchema: false,\n    synchronize: false,\n    migrationsRun: false,\n    entities: [],\n  } as TypeOrmModuleOptions,\n];\n
Run Code Online (Sandbox Code Playgroud)\n

src/app.module.ts

\n
import configuration from \'@config/configuration\';\nimport validationSchema from \'@config/validation\';\nimport { Module } from \'@nestjs/common\';\nimport { ConfigModule } from \'@nestjs/config\';\nimport { TypeOrmModule } from \'@nestjs/typeorm\';\nimport { LoggerService } from \'@shared/logger/logger.service\';\nimport { UsersModule } from \'@user/user.module\';\nimport { AppController } from \'./app.controller\';\nimport ormconfig = require(\'./config/ormconfig\'); //path mapping doesn\'t work here\n\n@Module({\n  imports: [\n    ConfigModule.forRoot({\n      cache: true,\n      isGlobal: true,\n      validationSchema: validationSchema,\n      load: [configuration],\n    }),\n    TypeOrmModule.forRoot(ormconfig[0]), //default\n    TypeOrmModule.forRoot(ormconfig[1]), //other db\n    LoggerService,\n    UsersModule,\n  ],\n  controllers: [AppController],\n})\nexport class AppModule {}\n
Run Code Online (Sandbox Code Playgroud)\n

包.json

\n
  "scripts": {\n    ...\n    "typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js --config ./src/config/ormconfig.ts",\n    "typeorm:migration:generate": "npm run typeorm -- migration:generate -n",\n    "typeorm:migration:run": "npm run typeorm -- migration:run"\n  },\n\n
Run Code Online (Sandbox Code Playgroud)\n

项目结构

\n
src/\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app.controller.ts\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 app.module.ts\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 config\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 configuration.ts\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ormconfig.ts\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 validation.ts\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.ts\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 model\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 entity\n\xe2\x94\x82   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 migration\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 repository\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 route\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 user\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 shared\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 logger\n
Run Code Online (Sandbox Code Playgroud)\n