Entidad TypeORM en NESTJS: no se puede usar la declaración de importación fuera de un módulo

11

Comenzó un nuevo proyecto con el comando 'anidar nuevo'. Funciona bien hasta que le agregue un archivo de entidad.

Tengo el siguiente error:

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

^^^^^^

SyntaxError: no se puede usar la declaración de importación fuera de un módulo

¿Qué extraño?

Agregar entidad al 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
fuente
importar {Módulo} desde '@ nestjs / common';
Preston
@Preston, ¿quieres explicar a qué te refieres? ¿Tiene que crear un módulo para archivos compartidos comúnmente?
Joshua de Leon
¿Recibes el error de tu linter o de una compilación? ¿Dónde tienes este nuevo archivo? ¿Está en tu srcdirectorio? Si está utilizando TypeORM, ¿puede mostrar su TypeOrmModuleimportación en la matriz de AppModule's imports? Puede haber algo mal con la configuración que no podemos ver
Jay McDoniel
publicación actualizada con información de importación de la entidad
Anton

Respuestas:

20

Supongo que tiene una TypeormModuleconfiguración con una entitiespropiedad que se ve así:

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

o como

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

El error que está recibiendo es porque está intentando importar un tsarchivo en un jscontexto. Mientras no esté usando el paquete web, puede usar esto en su lugar para obtener los archivos correctos

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

donde joinse importa desde el pathmódulo. Ahora __dirnamese resolverá en srco disty luego encontrará el archivo esperado tso el jsarchivo respectivamente. avíseme si todavía hay un problema.

EDITAR 1/10/2020

Lo anterior asume que la configuración se realiza es un archivo compatible con JavaScript ( .jso en los TypeormModule.forRoot()parámetros pasados). Si está usando un ormconfig.jsonen su lugar, debe usar

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

para que esté utilizando los archivos js compilados y no tenga la posibilidad de utilizar los archivos ts en su código.

Jay McDoniel
fuente
1
Pero esto es un desastre total. Un ORM mecanografiado que no acepta mecanografiado para las migraciones ...
Madeo
denoes el único corredor de código mecanografiado nativo. TypeORM, aunque utiliza el Script mecanografiado, aún funciona con Nodeel tiempo de ejecución de JavaScript. Tal vez se pueden hacer mejoras para aceptar tsarchivos y compilarlos en JavaScript debajo del capó, luego eliminarlos para que el usuario final no los vea, pero eso debería mencionarse como un problema en el repositorio git de TypeORM
Jay McDoniel
4

Como explicó Jay McDoniel en su respuesta, el problema parece ser la coincidencia de patrones de los archivos de entidad en el ormconfig.jsonarchivo: probablemente se importa un archivo (módulo) mecanografiado desde un archivo javascript (presumiblemente un archivo mecanografiado previamente transpilado).

Debería ser suficiente eliminar un tspatrón de globo existente en el ormconfig.json, para que TypeORM solo cargue archivos javascript. La ruta a los archivos de entidad debe ser relativa al directorio de trabajo donde se ejecuta el nodo.

   "entities"   : [
      "dist/entity/**/*.js"
   ],
   "migrations" : [
      "dist/migration/**/*.js"
   ],
   "subscribers": [
      "dist/subscriber/**/*.js"
   ],
iY1NQ
fuente
El srcprobablemente se debe cambiar a distya que es donde el código ejecutable es después de haber sido transpiled a javascript.
Jay McDoniel
Gracias, actualicé los caminos.
iY1NQ
2

En la documentación de TypeORM, encontré una sección específica para Typecript .

Esta sección dice:

Instale ts-node globalmente:

npm install -g ts-node

Agregue el comando typeorm en la sección de scripts en package.json

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

Entonces puedes ejecutar el comando así:

npm run typeorm migration:run

Si necesita pasar el parámetro con guión al script npm, deberá agregarlos después de -. Por ejemplo, si necesita generar, el comando es así:

npm run typeorm migration:generate -- -n migrationNameHere

Esto funciona con mi archivo de configuración:

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

Luego puede ejecutar el comando generar.

Fabio Cortez
fuente
esta debería ser la respuesta aceptada
Nico Li
1

Necesitas tener algo.module.ts para cada sección de tu aplicación. Funciona como angular. Esto se configura con los solucionadores GraphQL y el servicio. REST es un poco diferente con un controlador. Cada módulo probablemente tendrá una entidad y si 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
fuente
Excelente. Entonces, ¿eso significa que alguna vez puede tener una entidad base compartida entre múltiples módulos o esa entidad base debería ser parte de un tipo de módulo de bienes comunes?
Joshua de Leon
Probablemente, como Angular, pero nunca lo probé.
Preston
Si esto funciona, márquelo como la respuesta.
Preston
Creo que ya importé la entidad al módulo. Por favor, eche un vistazo a la publicación actualizada
Anton
1
Anton, si ya has resuelto esto, publica tu solución en SO.
Preston