Entité TypeORM dans NESTJS - Impossible d'utiliser l'instruction d'importation en dehors d'un module

11

Démarrage d'un nouveau projet avec la commande 'nest new'. Fonctionne bien jusqu'à ce que j'y ajoute un fichier d'entité.

Vous avez l'erreur suivante:

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

^^^^^^

SyntaxError: impossible d'utiliser l'instruction d'importation en dehors d'un module

Qu'est-ce que je manque?

Ajout d'une entité au module:

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
la source
importer {Module} depuis '@ nestjs / common';
Preston
@Preston veut développer ce que vous voulez dire? Devez-vous créer un module pour les fichiers partagés en commun?
Joshua de Leon
Obtenez-vous l'erreur de votre linter ou d'une compilation? Où avez-vous ce nouveau fichier? Est-ce dans votre srcannuaire? Si vous utilisez TypeORM, pouvez - vous montrer votre TypeOrmModuleimportation dans le AppModulede importstableau? Il y a peut-être quelque chose qui ne va pas avec la configuration que nous ne pouvons pas voir
Jay McDoniel
article mis à jour avec les informations d'importation d'entité
Anton

Réponses:

20

Mon hypothèse est que vous avez une TypeormModuleconfiguration avec une entitiespropriété qui ressemble à ceci:

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

ou comme

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

L'erreur que vous obtenez est due au fait que vous essayez d'importer un tsfichier dans un jscontexte. Tant que vous n'utilisez pas webpack, vous pouvez l'utiliser à la place pour obtenir les fichiers corrects

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

joinest importé du pathmodule. Maintenant, il __dirnamese résoudra en srcou distpuis trouvera le fichier attendu tsou jsrespectivement. faites-moi savoir si un problème persiste.

EDIT 1/10/2020

Ce qui précède suppose que la configuration est effectuée est un fichier compatible javascript ( .jsou dans les TypeormModule.forRoot()paramètres passés). Si vous utilisez un à la ormconfig.jsonplace, vous devez utiliser

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

afin que vous utilisiez les fichiers js compilés et que vous n'ayez aucune chance d'utiliser les fichiers ts dans votre code.

Jay McDoniel
la source
1
Mais c'est un gâchis total. Un ORM tapuscrit qui n'accepte pas le tapuscrit pour les migrations ...
Madeo
denoest le seul exécuteur de code typographique natif. TypeORM, bien qu'il utilise Typescript, fonctionne toujours avec Nodeet le moteur d'exécution JavaScript. Peut-être que des améliorations peuvent être apportées pour accepter les tsfichiers et les compiler en JavaScript sous le capot, puis les supprimer pour que l'utilisateur final ne les voit pas, mais cela devrait être signalé comme un problème dans le référentiel git de TypeORM
Jay McDoniel
4

Comme Jay McDoniel l'a expliqué dans sa réponse, le problème semble être la correspondance des motifs des fichiers d'entité dans le ormconfig.jsonfichier: probablement un fichier dactylographié (module) est importé à partir d'un fichier javascript (vraisemblablement un fichier dactylographié précédemment transposé).

Il devrait suffire de supprimer un tsmodèle de glob existant dans le ormconfig.json, afin que TypeORM ne charge que les fichiers javascript. Le chemin d'accès aux fichiers d'entité doit être relatif au répertoire de travail où le nœud est exécuté.

   "entities"   : [
      "dist/entity/**/*.js"
   ],
   "migrations" : [
      "dist/migration/**/*.js"
   ],
   "subscribers": [
      "dist/subscriber/**/*.js"
   ],
iY1NQ
la source
Le srcdevrait probablement être changé distcar c'est là que se trouve le code exécutable après avoir été transposé en javascript.
Jay McDoniel
Merci, j'ai mis à jour les chemins.
iY1NQ
2

Dans la documentation TypeORM, j'ai trouvé une section spécifique pour Typescript .

Cette section dit:

Installez ts-node globalement:

npm install -g ts-node

Ajouter la commande typeorm dans la section scripts de package.json

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

Ensuite, vous pouvez exécuter la commande comme ceci:

npm run typeorm migration:run

Si vous devez passer un paramètre avec un tiret au script npm, vous devrez les ajouter après -. Par exemple, si vous devez générer, la commande est la suivante:

npm run typeorm migration:generate -- -n migrationNameHere

Cela fonctionne avec ma configuration de fichier:

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

Ensuite, vous pouvez exécuter la commande generate.

Fabio Cortez
la source
cela devrait être la réponse acceptée
Nico Li
1

Vous devez avoir un quelque chose.module.ts pour chaque section de votre application. Cela fonctionne comme Angular. Ceci est configuré avec les résolveurs et le service GraphQL. REST est un peu différent avec un contrôleur. Chaque module aura probablement une entité et 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
la source
Excellent. Cela signifie-t-il que vous pouvez jamais avoir une entité de base partagée entre plusieurs modules ou cette entité de base devrait-elle faire partie d'un module commun en quelque sorte?
Joshua de Leon
Probablement, comme Angular, mais je ne l'ai jamais essayé.
Preston
Si cela fonctionne, veuillez le marquer comme réponse.
Preston
Je pense que j'ai déjà importé une entité dans le module. S'il vous plaît jeter un oeil à l'article mis à jour
Anton
1
Anton, si vous avez déjà résolu ce problème, veuillez publier votre solution sur SO.
Preston