Entidade TypeORM no NESTJS - Não é possível usar a instrução de importação fora de um módulo

11

Iniciou um novo projeto com o comando 'nest new'. Funciona bem até eu adicionar o arquivo de entidade a ele.

Obteve o seguinte erro:

import {Entity, Column, PrimaryGeneratedColumn} de 'typeorm';

^^^^^^

SyntaxError: Não é possível usar a instrução de importação fora de um módulo

Do que sinto falta?

Adicionando Entidade ao Módulo:

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 {}
Anton
fonte
import {Module} de '@ nestjs / common';
Preston
@ Preston se preocupa em elaborar o que você quer dizer? Você precisa criar um módulo para arquivos comumente compartilhados?
Joshua de Leon
Você está recebendo o erro do seu linter ou de uma compilação? Onde você tem esse novo arquivo? Está no seu srcdiretório? Se você estiver usando TypeORM, você pode mostrar sua TypeOrmModuleimportação na AppModule's importsarray? Pode haver algo de errado com a configuração que não podemos ver
Jay McDoniel
publicação atualizada com informações de importação de entidade
Anton

Respostas:

20

Minha suposição é que você tenha uma TypeormModuleconfiguração com uma entitiespropriedade que se parece com isso:

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

ou como

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

O erro que você está recebendo é porque você está tentando importar um tsarquivo em um jscontexto. Desde que você não esteja usando o webpack, use-o para obter os arquivos corretos

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

onde joiné importado do pathmódulo. Agora __dirnameserá resolvido para srcou diste, em seguida, localize o arquivo tsou o esperado, jsrespectivamente. informe-me se ainda houver um problema em andamento.

EDIT 1/10/2020

O exemplo acima pressupõe que a configuração foi feita como um arquivo compatível com javascript ( .jsou nos TypeormModule.forRoot()parâmetros passados). Se você estiver usando um ormconfig.json, deve usar

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

para que você esteja usando os arquivos js compilados e não tenha chance de usar os arquivos ts no seu código.

Jay McDoniel
fonte
11
Mas isso é uma bagunça total. Um ORM datilografado que não aceita datilografado para as migrações ...
Madeo 03/02
denoé o único corredor de código datilografado nativo. TypeORM, enquanto usa o Typecript, ainda funciona com Nodeo tempo de execução do JavaScript. Talvez possam ser feitas melhorias para aceitar tsarquivos e compilá-los em JavaScript, excluindo-os para que o usuário final não os veja, mas isso precisaria ser apresentado como um problema no repositório git TypeORM
Jay McDoniel
4

Como Jay McDoniel explicou em sua resposta, o problema parece ser a correspondência de padrões dos arquivos de entidade no ormconfig.jsonarquivo: Provavelmente, um arquivo de texto (módulo) datilografado é importado de um arquivo javascript (presumivelmente um arquivo datilografado anteriormente transpilado).

Deve ser suficiente remover um tspadrão glob existente no ormconfig.json, para que TypeORM carregue apenas arquivos javascript. O caminho para os arquivos de entidade deve ser relativo ao diretório de trabalho em que o nó é executado.

   "entities"   : [
      "dist/entity/**/*.js"
   ],
   "migrations" : [
      "dist/migration/**/*.js"
   ],
   "subscribers": [
      "dist/subscriber/**/*.js"
   ],
iY1NQ
fonte
O srcprovavelmente deve ser alterado para distjá que é onde o código executável é depois de ser transpiled para javascript.
Jay McDoniel
Obrigado, atualizei os caminhos.
iY1NQ 10/01
2

Na documentação do TypeORM, encontrei uma seção específica para o Typecript .

Esta seção diz:

Instale o nó ts globalmente:

npm install -g ts-node

Adicione o comando typeorm na seção scripts em package.json

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

Então você pode executar o comando assim:

npm run typeorm migration:run

Se você precisar passar o parâmetro com o script dash para o npm, precisará adicioná-los após -. Por exemplo, se você precisa gerar, o comando é assim:

npm run typeorm migration:generate -- -n migrationNameHere

Isso funciona com a minha configuração de arquivo:

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

Então você pode executar o comando generate.

Fabio Cortez
fonte
esta deve ser a resposta aceita
Nico Li
1

Você precisa ter algo.module.ts para cada seção do seu aplicativo. Funciona como Angular. Isso é configurado com os resolvedores e serviços GraphQL. REST é um pouco diferente com um controlador. Cada módulo provavelmente terá uma entidade e, se 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 {}
Preston
fonte
Excelente. Então, isso significa que você pode ter uma entidade base compartilhada entre vários módulos ou essa entidade base teria que fazer parte de um tipo de módulo comum?
Joshua de Leon
Provavelmente, como Angular, mas nunca tentei.
Preston
Se isso funcionar, marque-o como a resposta.
Preston
Eu acho que já importei entidade para o módulo. Dê uma olhada na publicação atualizada
Anton
11
Anton, se você já resolveu isso, poste sua solução no SO.
Preston