【问题标题】:Typescript & TypeORM: Cannot use import statement outside a moduleTypescript & TypeORM:不能在模块外使用 import 语句
【发布时间】:2021-08-05 07:41:23
【问题描述】:

我已经使用 TypeORM 建立了一个 Typescript 项目,但我在编译时遇到了一些问题。

我的包结构是这样的:

root
├── db
│   ├── migrations
│   │   ├── a_migration.ts
│   ├── connection
│   │   ├── config.ts <- ormconfig
│   │   ├── encrypt.ts
│   │   ├── index.ts <- creates the connection
├── src
│   ├── card
│   │   ├── entity.ts
├── package.json
├── tsconfig.json

我的 config.ts 是:


export = {
  type: 'postgres',
  host: POSTGRES_HOST,
  port: POSTGRES_PORT,
  username: POSTGRES_USER,
  password: POSTGRES_PASS,
  database: POSTGRES_DB,
  synchronize: true,
  logging: false,
  entities: ['**src/**/*entity.{ts,js}'],
  migrations: ['**/migrations/*.{ts,js}'],
  cli: {
    entitiesDir: 'src/entity',
    migrationsDir: 'db/migrations',
  },
  namingStrategy: new SnakeNamingStrategy(),
};

tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "target": "es6",
    "module": "CommonJS",
    "allowJs": false,
    "esModuleInterop": true,
    "noImplicitAny": true,
    "resolveJsonModule": true,
    "outDir": "./build",
    "strict": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  },
  "include": ["./src/*", "./db/*"],
  "exclude": ["./**/__tests__/*", "./**/__functionaltests__/*"]
}

我尝试用 path.join + __dirname 替换实体和迁移中的 ** 前缀,但 typeorm 无法检测到迁移文件和实体。我知道这与解析代码在build 文件夹下的路径有关,但我不确定如何解决这个问题。

如果我这样生活,CLI 适用于执行应用程序的未编译代码 (ts),例如 nodemon,但不适用于已编译 (js) 代码。

我从编译的 js 中得到的错误是: SyntaxError: Cannot use import statement outside a module

感谢任何帮助,非常感谢!

【问题讨论】:

    标签: javascript node.js typescript postgresql typeorm


    【解决方案1】:

    应为您的实体和迁移提供 build 目录而不是 src 目录。

    并且synchronize应该设置为false。

    尝试更新您的config.ts,如下所示:

    export = {
      type: 'postgres',
      host: POSTGRES_HOST,
      port: POSTGRES_PORT,
      username: POSTGRES_USER,
      password: POSTGRES_PASS,
      database: POSTGRES_DB,
      synchronize: false,
      logging: false,
      entities: ['build/src/**/*entity.{ts,js}'],
      migrations: ['build/db/migrations/*.{ts,js}'],
      cli: {
        entitiesDir: 'src/entity',
        migrationsDir: 'db/migrations',
      },
      namingStrategy: new SnakeNamingStrategy(),
    };
    

    注意entitiesmigrations 属性的变化。如果这不起作用,很可能是因为我指定的路径不在build 目录中。在这种情况下,请根据需要进行更改。

    希望对您有所帮助!干杯? !!!

    【讨论】:

    • 您好,感谢您的帮助,很抱歉回复晚了。这将在 docker 容器内工作,但如果没有 docker (nodemon 和 ts-node),它将无法在本地环境上运行。如果您有任何其他建议,我们非常欢迎?
    • 在本地环境中,您需要在运行迁移之前构建应用程序。你在运行迁移之前尝试过“npm run build”吗?您在本地环境中遇到的错误是什么?哦,顺便说一句,您需要将同步设置为 false,否则将不会有任何更改来创建迁移。
    • 问题不在于迁移执行,而在于通过打字稿运行的应用程序。我的意思是,如果我在开发模式下运行它以进行热重载等,该应用程序将无法找到迁移和实体文件。不知道我是否有意义?
    • 你在开发模式下使用的 npm 命令是什么?
    • 我为此使用nodemon,而nodemon exects-node ./src/app.ts
    【解决方案2】:

    为您的部署创建环境变量。在 config.ts 检查环境,然后相应地设置实体和迁移。

    【讨论】:

      【解决方案3】:

      我遇到了类似的问题,也许这对你有帮助。

      我正在使用(未编译的)ormconfig.js(注意,.js)进行这样的迁移(NestJS 应用程序使用另一种方式通过 TypeORM 建立其数据库连接):

      const { SnakeNamingStrategy } = require('typeorm-naming-strategies');
      
      module.exports = {
          type: 'mysql',
          host: 'localhost',
          username: 'some user',
          database: 'some db',
          password: 'some pw',
          entities: ['./src/**/model/*.entity.ts'],
          migrations: ['migrations/*{.ts,.js}'],
          cli: {
              migrationsDir: 'src/migrations',
          },
          namingStrategy: new SnakeNamingStrategy(),
      };
      

      我的 IDE 建议将其转换为 ES6 模块,这会将 require('typeorm-naming-strategies') 更改为 import 语句。如果我这样做,我会得到:

      SyntaxError: 不能在模块外使用 import 语句

      错误的附加输出是:

      import { SnakeNamingStrategy } from 'typeorm-naming-strategies';
      ^^^^^^
      

      所以也许您可以将您的(未显示?)importSnakeNamingStrategy 替换为 require

      只是一个猜测,不确定它是否真的对你有帮助。

      【讨论】:

        猜你喜欢
        • 2021-03-10
        • 1970-01-01
        • 2021-04-22
        • 2021-08-24
        • 2021-05-18
        • 2020-02-09
        • 2020-06-29
        • 2020-01-27
        相关资源
        最近更新 更多