Сущность TypeORM в NESTJS - Невозможно использовать оператор импорта вне модуля

11

Начал новый проект с помощью команды 'nest new'. Работает нормально, пока я не добавлю к нему файл сущности.

Получил следующую ошибку:

import {Entity, Column, PrimaryGeneratedColumn} из 'typeorm';

^^^^^^

SyntaxError: Невозможно использовать оператор импорта вне модуля

Что мне не хватает?

Добавление объекта в модуль:

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 {}

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 {}
Антон
источник
import {Module} из '@ nestjs / common';
Престон
@Preston хотите уточнить, что вы имеете в виду? Нужно ли создавать модуль для общих файлов?
Джошуа де Леон
Вы получаете ошибку от своего линтера или от компиляции? Где у вас этот новый файл? Это в вашемsrc каталоге? Если вы используете TypeORM, вы можете показать свой TypeOrmModuleимпорт в AppModule«s importsмассив? Может быть что-то не так с конфигурацией, которую мы не можем видеть
Джей МакДонил
обновленный пост с информацией об импорте
Антон

Ответы:

20

Я предполагаю, что у вас есть TypeormModuleконфигурация со entitiesсвойством, которое выглядит следующим образом:

entities: ['src/**/*.entity.{ts,js}']

или как

entities: ['../**/*.entity.{ts,js}']

Вы получаете ошибку, потому что вы пытаетесь импортировать tsфайл в jsконтексте. Пока вы не используете веб-пакет, вы можете использовать его, чтобы получить правильные файлы

entities: [join(__dirname, '**', '*.entity.{ts,js}`)]

где joinимпортируется из pathмодуля. Теперь __dirnameразрешите srcили distзатем найдите ожидаемый файл tsили jsсоответственно. дайте мне знать, если проблема не устранена.

РЕДАКТИРОВАТЬ 1/10/2020

Выше предполагается, что конфигурация выполнена в формате javascript-совместимого файла ( .jsили в TypeormModule.forRoot()переданных параметрах). Если вы используете ormconfig.jsonвместо этого, вы должны использовать

entities: ['dist/**/*.entity.js']

так что вы используете скомпилированные файлы js и не имеете возможности использовать файлы ts в своем коде.

Джей МакДонил
источник
1
Но это полный беспорядок. Машинопись ORM, которая не принимает машинопись для миграций ...
Мадео,
denoединственный бегун с машинным кодом TypeORM, хотя он использует Typescript, все еще работает Nodeи время выполнения JavaScript. Возможно, могут быть сделаны улучшения, чтобы принимать tsфайлы и компилировать их в JavaScript под капотом, а затем удалять их, чтобы конечный пользователь их не видел, но это должно быть поднято как проблема в git-репозитории
TypeORM
4

Как объяснил Джей МакДонил в своем ответе, проблема заключается в сопоставлении шаблонов файлов сущностей в ormconfig.jsonфайле: возможно, файл (модуль) машинописи импортирован из файла JavaScript (предположительно, ранее перенесенного файла машинописи).

Должно быть достаточно удалить существующий tsшаблон glob в ormconfig.json, чтобы TypeORM загружал только файлы javascript. Путь к файлам сущностей должен быть относительно рабочего каталога, в котором выполняется узел.

   "entities"   : [
      "dist/entity/**/*.js"
   ],
   "migrations" : [
      "dist/migration/**/*.js"
   ],
   "subscribers": [
      "dist/subscriber/**/*.js"
   ],
iY1NQ
источник
src, Вероятно , следует изменить , чтобы , distкак это где работоспособный код после того , как transpiled в JavaScript.
Джей МакДонил
Спасибо, я обновил пути.
iY1NQ
2

В документации TypeORM я нашел специальный раздел для Typescript .

В этом разделе говорится:

Установите ts-node глобально:

npm install -g ts-node

Добавьте команду typeorm в разделе скриптов в package.json

"scripts" {
    ...
    "typeorm": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js"    
}

Затем вы можете запустить команду следующим образом:

npm run typeorm migration:run

Если вам нужно передать параметр с дефисом в скрипт npm, вам нужно будет добавить их после -. Например, если вам нужно сгенерировать, команда выглядит так:

npm run typeorm migration:generate -- -n migrationNameHere

Это работает с моим файлом конфигурации:

{
    "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"
    }
}

Затем вы можете запустить команду создания.

Фабио Кортес
источник
это должен быть принятый ответ
Нико Ли
1

Вам нужно иметь что-то для каждого раздела вашего приложения. Это работает как Angular. Это настройка с помощью распознавателей и сервиса GraphQL. REST немного отличается от контроллера. Каждый модуль, вероятно, будет иметь сущность, а если GraphQL, projects.schema.graphql.

projects.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ProjectsService } from './projects.service';
import { Projects } from './projects.entity';

import { ProjectsResolvers } from './projects.resolvers';

@Module({
  imports: [
    TypeOrmModule.forFeature([Projects])],
  providers: [
    ProjectsService,
    ProjectsResolvers
  ],

})

export class ProjectsModule {}
Престон
источник
Отлично. Значит ли это, что вы когда-либо можете иметь базовую сущность, совместно используемую несколькими модулями, или эта базовая сущность должна быть частью своего рода общего модуля?
Джошуа де Леон
Возможно, как Angular, но никогда не пробовал.
Престон
Если это работает, отметьте это как ответ.
Престон
Я думаю, что я уже импортировал объект в модуль. Пожалуйста, взгляните на обновленный пост
Антон
1
Антон, если вы уже решили это, пожалуйста, опубликуйте свое решение в SO.
Престон