在 Node 14 中使用 sequelize-cli,类型为:module

Posted

技术标签:

【中文标题】在 Node 14 中使用 sequelize-cli,类型为:module【英文标题】:Using sequelize-cli in Node 14 with type: module 【发布时间】:2020-09-19 02:35:21 【问题描述】:

我正在尝试使用Node v14.3sequelize 设置项目。

我不想使用babel-register。而不是这个,我在我的package.json 中设置了"type": "module" 并使用所有开箱即用的 ES6 - ES11 功能。

我还想使用sequelize-cli 来设置和应用迁移。除以下命令外,一切正常:

& sequelize db:migrate

Sequelize CLI [Node: 14.3.0, CLI: 5.5.1, ORM: 5.21.11]

Loaded configuration file "config/config.json".
Using environment "development".
== 20200530214311-create-user: migrating =======

ERROR: Must use import to load ES Module: /home/kasheftin/work/tests/chai-http-publication/migrations/20200530214311-create-user.js
require() of ES modules is not supported.
require() of /home/kasheftin/work/tests/chai-http-publication/migrations/20200530214311-create-user.js from /home/kasheftin/.nvm/versions/node/v14.3.0/lib/node_modules/sequelize-cli/node_modules/umzug/lib/migration.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename 20200530214311-create-user.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /home/kasheftin/work/tests/chai-http-publication/package.json.

我们看到 sequelize-cli 在后台使用 require()。 ES 模块不允许这样做。它提出了 3 种方法来解决这个问题:

将 20200530214311-create-user.js 重命名为以 .cjs 结尾 - 无法完成,sequelize-cli 找不到以 .cjs 结尾的迁移。

将需要的代码更改为使用 import() - 我不想接触 sequelize-cli 代码。

删除 "type": "module" - 我不能,因为一切都停止了。

还有其他方法可以使sequelize-cli 工作吗?我正在大量使用测试,我希望在运行测试之前自动准备测试数据库。

【问题讨论】:

github.com/sequelize/cli/issues/861 仍处于打开状态。也许您只能使用解决方法? 谢谢,@Anatoly。安装 babel-core 包并添加 require("babel-core/register");我的 config.cjs 文件对我有用,就像链接中提到的那样。除此之外,我还需要安装 babel-preset-env 以使其正常工作。 您不是原始问题的作者。我可以复制我的评论作为答案吗? 是的。所以答案是目前不可能。 官方文档中提到了babel-register:sequelize.org/master/manual/migrations.html。看来这是官方使用 es6 的方式 【参考方案1】:

一种解决方案是在您的迁移文件夹中添加一个 package.json 以覆盖您的主 package.json 中的 type: "module"

这个 package.json 看起来像这样:


  "type": "commonjs"

您的迁移文件必须如下所示:

module.exports = 
  up: async (queryInterface, Sequelize) => 

  ,

  down: async (queryInterface, Sequelize) => 

  
;

它适用于 nodeJS 14.16.1 & Sequelize 6.6.2 & sequelize-cli 6.2.0

【讨论】:

【参考方案2】:

几个月来我一直遇到同样的问题。在使用 ES 模块导入和 Sequelize cli 时,Babel 寄存器将无法正常工作。

这就是我最终让一切正常工作的方法。 我不得不将 src 复制到 dist 目录。然后覆盖json包中的type。希望这会有所帮助?

.sequelizerc

require('@babel/register')(
  presets: [
    ['@babel/preset-env',  targets:  node: 'current'  ]
  ]
);
const path = require('path');

const DB_PATH = 'dist/db'; // use dist instead of src directory

module.exports = 
  'config': path.resolve(DB_PATH, 'config.json'),
  'models-path': path.resolve(DB_PATH, 'models'),
  'seeders-path': path.resolve(DB_PATH, 'seeders'),
  'migrations-path': path.resolve(DB_PATH, 'migrations')
;

package.json


  "type": "module",
  "engines": 
    "node": ">=14.18",
    "yarn": ">=1.22"
  ,
  "scripts": 
    "start": "node --experimental-specifier-resolution=node src",
    "db": "sequelize db:migrate && sequelize db:seed:all",
    "predb": "yarn dist",
    "dist": "cp -r src dist",
    "predist": "rm -rf dist",
    "postdist": "node setup-dist.js"
  ,
  "dependencies": 
    "@babel/core": "^7.16.0",
    "@babel/preset-env": "^7.16.0",
    "@babel/register": "^7.16.0",
    "sequelize": "^6.8.0",
    "sequelize-cli": "^6.2.0"
  

setup-dist.js

import  writeFileSync  from 'fs';

const file = './dist/package.json';
const data = ' "type": "" '; // to override ESM in main package.json

writeFileSync(file, data);

参考:https://gist.github.com/elawad/c0af86ea37629ad0538c2b974b4ea0c1

【讨论】:

【参考方案3】:

我通过创建一个.sequelizerc 文件让 sequelize 知道我正在覆盖默认路径,从而实现了这一点:

// .sequelizerc
const path = require('path');

const db_path = './';

module.exports = 
  'config': path.resolve(db_path, 'config/config.cjs'),
  'models-path': path.resolve(db_path, 'models'),
  'seeders-path': path.resolve(db_path, 'seeders'),
  'migrations-path': path.resolve(db_path, 'migrations')
;

请注意,我正在使用 config.cjs 文件。然后只需创建一个迁移,但也将扩展名更改为 .cjs:

// 20211206164144-create_subjects_table.cjs
const tableName = 'subjects';

module.exports = 
  up: async (queryInterface, Sequelize) => 
    await queryInterface.createTable(tableName, 
      id: 
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        allowNull: false,
        primaryKey: true,
      ,
      title: 
        type: Sequelize.STRING,
        required: true,
      ,
      created_at: 
        type: Sequelize.DATE,
      ,
      updated_at: 
        type: Sequelize.DATE,
      ,
      deleted_at: 
        type: Sequelize.DATE,
      ,
    );
  ,

  down: async (queryInterface) => 
    await queryInterface.dropTable('subjects');
  ,
;

这适用于 Node.js 版本 v16.13.1 和以下package.json


  "type": "module",
  "dependencies": 
    "pg": "^8.7.1",
    "pg-hstore": "^2.3.4",
    "sequelize": "^6.12.0-beta.1"
  ,
  "devDependencies": 
    "sequelize-cli": "^6.3.0"
  

【讨论】:

以上是关于在 Node 14 中使用 sequelize-cli,类型为:module的主要内容,如果未能解决你的问题,请参考以下文章

nodejs: express sequelize-cli

nodejs: express sequelize-cli

sequelize(和 sequelize-cli)queryInterface.createTable 在 PostgreSQL 上,PK id 类型为 UUID 和 defaultValue:Se

Node、Sequelize、Mysql - 如何为模型定义排序规则和字符集?

Sequelize Migration:关系 <table> 不存在

Ubantu 14服务器 node.js环境 运行线上项目