You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js+TypeScript项目Sequelize迁移时出现import语句模块错误

问题:TypeScript Node.js项目执行Sequelize迁移时出现Syntax Error: Cannot use import statement outside a module

目录结构

├── dist
├── src
│   ├── config
│   │   └── database.ts
│   ├── connection
│   │   └── connection.ts
│   ├── controllers
│   │   └── user.controller.ts
│   ├── migrations
│   │   └── 20231015073945-create-role.ts
│   ├── models
│   │   ├── index.ts
│   │   └── role.ts
│   ├── routes
│   │   └── role.router.ts
│   ├── seeders
│   │   └── 20231015075720-role-data.ts
│   └── server.ts
├── .sequelizerc
└── package.json

错误原因

Sequelize-CLI默认以CommonJS模块规范执行脚本,但你的代码混用了ES模块(import)和CommonJS(module.exports)语法,同时TypeScript编译配置与运行环境不匹配,导致迁移脚本无法被正确解析。

解决方案

1. 统一配置文件模块语法

修改src/config/database.ts,改用ES模块导出:

import dotenv from 'dotenv';
dotenv.config();

export default {
  "development": {
    "username": process.env.DEV_DB_USERNAME,
    "password": process.env.DEV_DB_PASSWORD,
    "database": process.env.DEV_DB_NAME,
    "host": process.env.DEV_DB_HOST,
    "dialect": process.env.DEV_DB_DATABASE_TYPE,
  },
  "test": {
    "username": process.env.TEST_DB_USERNAME,
    "password": process.env.TEST_DB_PASSWORD,
    "database": process.env.TEST_DB_NAME,
    "host": process.env.TEST_DB_HOST,
    "dialect": "mysql"
  },
  "production": {
    "username": process.env.PROD_DB_USERNAME,
    "password": process.env.PROD_DB_PASSWORD,
    "database": process.env.PROD_DB_NAME,
    "host": process.env.PROD_DB_HOST,
    "dialect": "mysql"
  }
};

2. 调整迁移文件适配CommonJS

Sequelize-CLI默认不编译TypeScript,迁移文件需改用CommonJS语法:
修改20231015073945-create-role.ts:

'use strict';
const { QueryInterface, DataTypes } = require('sequelize');

module.exports = {
  async up(queryInterface) {
    await queryInterface.createTable('roles', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: DataTypes.INTEGER
      },
      role: {
        allowNull: false,
        type: DataTypes.STRING
      },
      isActive: {
        type: DataTypes.BOOLEAN,
        defaultValue: true
      },
      createdAt: {
        allowNull: true,
        type: DataTypes.DATE
      },
      updatedAt: {
        allowNull: true,
        type: DataTypes.DATE
      }
    });
  },
  async down(queryInterface) {
    await queryInterface.dropTable('roles');
  }
};

3. 修改tsconfig编译配置

将module设为CommonJS,确保编译产物符合Sequelize-CLI预期:

{
  "compilerOptions": {
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "target": "es2017",
    "module": "CommonJS",
    "lib": [
      "dom",
      "es6",
      "es2017",
      "esnext.asynciterable"
    ],
    "skipLibCheck": true,
    "sourceMap": true,
    "outDir": "./dist",
    "moduleResolution": "node",
    "removeComments": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "resolveJsonModule": true,
    "baseUrl": "./src",
    "paths": {
      "@/*": ["*"]
    }
  },
  "exclude": ["node_modules"],
  "include": ["src/**/*.ts", "server.ts"]
}

4. 配置Sequelize-CLI通过ts-node运行

在package.json中添加迁移脚本,让CLI通过ts-node编译TypeScript:

{
  "scripts": {
    "start": "nodemon server.ts",
    "dev": "nodemon server.ts",
    "test": "",
    "build": "tsc",
    "prestart": "yarn run build",
    "migrate": "ts-node ./node_modules/sequelize-cli/lib/sequelize db:migrate",
    "migrate:undo": "ts-node ./node_modules/sequelize-cli/lib/sequelize db:migrate:undo"
  }
}

5. 统一模型文件模块语法

修改src/models/index.ts:

const fs = require('fs');
const path = require('path');
const { Sequelize, DataTypes } = require('sequelize');
const process = require('process');

const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/database.ts')[env];
const db = {};

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

fs
  .readdirSync(__dirname)
  .filter(file => {
    return (
      file.indexOf('.') !== 0 &&
      file !== basename &&
      file.slice(-3) === '.ts' &&
      file.indexOf('.test.ts') === -1
    );
  })
  .forEach(file => {
    const model = require(path.join(__dirname, file))(sequelize, DataTypes);
    db[model.name] = model;
  });

Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

修改src/models/role.ts:

'use strict';
const { Model, DataTypes, Sequelize } = require('sequelize');

interface RoleAttributes {
  id: number;
  role: string;
  isActive: boolean;
}

module.exports = (sequelize) => {
  class Role extends Model {
    static associate() {
      // 定义关联逻辑
    }
  }

  Role.init({
    id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true,
    },
    role: DataTypes.STRING,
    isActive: DataTypes.BOOLEAN,
  }, {
    sequelize,
    modelName: 'role',
  });

  return Role;
};

6. 调整数据库连接文件语法

修改src/connection/connection.ts:

const { Sequelize } = require('sequelize');
const dotenv = require('dotenv');
dotenv.config();

let env;
if (process.env.NODE_ENV === 'test') {
    env = 'test';
} else if (process.env.NODE_ENV === 'production') {
    env = 'production';
} else {
    env = 'development';
}
const config = require('../config/database.ts')[env];

const sequelize = new Sequelize(config.database, config.username, config.password, config);

(async () => {
    try {
        await sequelize.authenticate();
        console.log('Database connection has been established successfully.');
    } catch (err) {
        console.error('Unable to connect to the database:', err.message);
    }
})();

module.exports = sequelize;

执行迁移

完成以上修改后,运行以下命令执行迁移:

npm run migrate
# 或
yarn migrate

内容的提问来源于stack exchange,提问作者Ramcharan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 10:06:05