如何在 Node 14 / Sequelize 6 中为 Sequelize 动态创建模型
How to dynamically create the models for Sequelize in Node 14 / Sequelize 6
我有一个在后端使用 Node 和 Sequelize 的项目。它工作正常,直到我不得不将 Node 和 Sequelize 升级到最新版本。我知道我可以降级,但是我的其他项目中使用了 Node 14,我不想弄清楚如何同时使用多个 Node 版本。
我的模型文件夹中有我的索引文件,读取所有模型 js 文件并自动生成模型。
这是我的代码:
'use strict';
import fs from 'fs';
import path from 'path';
import Sequelize from 'sequelize';
// import DataTypes from 'sequelize/lib/data-types';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
import { dirname } from 'path';
const __dirname = dirname(__filename);
const basename = path.basename(__filename);
import config from '../config/config.js';
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const db = {};
const sequelize = new Sequelize(config);
fs.readdirSync(__dirname)
.filter((file) => {
return (
file.indexOf('.') !== 0 &&
file !== basename &&
file.slice(-3) === '.js'
);
})
.forEach((file) => {
// const model = sequelize['import'](path.join(__dirname, file));
const model = require(path.join(__dirname, file))(
sequelize,
Sequelize.DataTypes
);
db[model.name] = model;
});
Object.keys(db).forEach((modelName) => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
注释掉的那一行是我之前用的。但现在 Sequelize 6 删除了导入选项。所以我能够想出一个 hack 来让“require”在那个文件中工作。但是现在的问题是,当我尝试 运行 我的应用程序时,出现此错误:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: C:\....\models\Chemicals.js require() of ES modules is not supported. require() of C:\....\models\Chemicals.js from C:\....\models\index.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 Chemicals.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from C:\....\package.json.
如果不需要,我不想将所有模型重命名为“.cjs”。我也不想删除 "type":"module"。
那里的错误就目前而言已经很清楚了,
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: C:\....\models\Chemicals.js
require() of ES modules is not supported.
require() of C:\....\models\Chemicals.js from C:\....\models\index.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 Chemicals.js to end in .cjs, change the requiring
code to use import(), or remove "type": "module" from C:\....\package.json.
最后一行有三个建议:
- 重命名 Chemicals.js 以 .cjs 结尾,
- 更改需要的代码以使用 import(),
- 从 C:....\package.json.
中删除 "type": "module"
这些建议的一些注意事项:
import() 调用是异步的,因此您需要考虑到这一点,而不是真正的替换下降。 (我觉得很奇怪,如果这大概是一些生产级别的后端代码,那么您正在对任何东西使用同步调用!)。这里的快速重构可能看起来像
'use strict';
import fs from 'fs';
import path from 'path';
import Sequelize from 'sequelize';
// import DataTypes from 'sequelize/lib/data-types';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
import { dirname } from 'path';
const __dirname = dirname(__filename);
const basename = path.basename(__filename);
import config from '../config/config.js';
// no need for these bits any more, always nice
// import { createRequire } from 'module';
// const require = createRequire(import.meta.url);
const db = {};
const sequelize = new Sequelize(config);
fs.readdir(__dirname, (err, files) => {
if (err)
console.log(err);
else {
const promise_arr = files
.filter((file) => {
return (
file.indexof('.') !== 0 &&
file !== basename &&
file.slice(-3) === '.js'
);
})
.map((file) => {
// const model = sequelize['import'](path.join(__dirname, file));
return import(path.join(__dirname, file))
});
Promise.all(promise_arr).then((models)=>{
models.forEach((model)=>db[model.name] = model(sequelize,Sequelize.DataTypes))
associateCB()
})
}
})
function associateCB(){
Object.keys(db).forEach((modelName) => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
}
修改你的包 json 如果这是作为 npm 库发布的东西,其他东西需要的东西,可能会产生其他后果。看起来不像,所以这个可能是你最好的选择!
.cjs
好像也不错,就是忍不住觉得怪怪的!
你为什么会这样:
因为更新到节点 14 后,节点中的 es 模块系统作为一个稳定的、可操作的功能开始生效。 package.json type
设置是此处错误的实际原因。参见 here
我有一个在后端使用 Node 和 Sequelize 的项目。它工作正常,直到我不得不将 Node 和 Sequelize 升级到最新版本。我知道我可以降级,但是我的其他项目中使用了 Node 14,我不想弄清楚如何同时使用多个 Node 版本。
我的模型文件夹中有我的索引文件,读取所有模型 js 文件并自动生成模型。
这是我的代码:
'use strict';
import fs from 'fs';
import path from 'path';
import Sequelize from 'sequelize';
// import DataTypes from 'sequelize/lib/data-types';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
import { dirname } from 'path';
const __dirname = dirname(__filename);
const basename = path.basename(__filename);
import config from '../config/config.js';
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const db = {};
const sequelize = new Sequelize(config);
fs.readdirSync(__dirname)
.filter((file) => {
return (
file.indexOf('.') !== 0 &&
file !== basename &&
file.slice(-3) === '.js'
);
})
.forEach((file) => {
// const model = sequelize['import'](path.join(__dirname, file));
const model = require(path.join(__dirname, file))(
sequelize,
Sequelize.DataTypes
);
db[model.name] = model;
});
Object.keys(db).forEach((modelName) => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
注释掉的那一行是我之前用的。但现在 Sequelize 6 删除了导入选项。所以我能够想出一个 hack 来让“require”在那个文件中工作。但是现在的问题是,当我尝试 运行 我的应用程序时,出现此错误:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: C:\....\models\Chemicals.js require() of ES modules is not supported. require() of C:\....\models\Chemicals.js from C:\....\models\index.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 Chemicals.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from C:\....\package.json.
如果不需要,我不想将所有模型重命名为“.cjs”。我也不想删除 "type":"module"。
那里的错误就目前而言已经很清楚了,
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: C:\....\models\Chemicals.js
require() of ES modules is not supported.
require() of C:\....\models\Chemicals.js from C:\....\models\index.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 Chemicals.js to end in .cjs, change the requiring
code to use import(), or remove "type": "module" from C:\....\package.json.
最后一行有三个建议:
- 重命名 Chemicals.js 以 .cjs 结尾,
- 更改需要的代码以使用 import(),
- 从 C:....\package.json. 中删除 "type": "module"
这些建议的一些注意事项:
import() 调用是异步的,因此您需要考虑到这一点,而不是真正的替换下降。 (我觉得很奇怪,如果这大概是一些生产级别的后端代码,那么您正在对任何东西使用同步调用!)。这里的快速重构可能看起来像
'use strict';
import fs from 'fs';
import path from 'path';
import Sequelize from 'sequelize';
// import DataTypes from 'sequelize/lib/data-types';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
import { dirname } from 'path';
const __dirname = dirname(__filename);
const basename = path.basename(__filename);
import config from '../config/config.js';
// no need for these bits any more, always nice
// import { createRequire } from 'module';
// const require = createRequire(import.meta.url);
const db = {};
const sequelize = new Sequelize(config);
fs.readdir(__dirname, (err, files) => {
if (err)
console.log(err);
else {
const promise_arr = files
.filter((file) => {
return (
file.indexof('.') !== 0 &&
file !== basename &&
file.slice(-3) === '.js'
);
})
.map((file) => {
// const model = sequelize['import'](path.join(__dirname, file));
return import(path.join(__dirname, file))
});
Promise.all(promise_arr).then((models)=>{
models.forEach((model)=>db[model.name] = model(sequelize,Sequelize.DataTypes))
associateCB()
})
}
})
function associateCB(){
Object.keys(db).forEach((modelName) => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
}
修改你的包 json 如果这是作为 npm 库发布的东西,其他东西需要的东西,可能会产生其他后果。看起来不像,所以这个可能是你最好的选择!
.cjs
好像也不错,就是忍不住觉得怪怪的!
你为什么会这样:
因为更新到节点 14 后,节点中的 es 模块系统作为一个稳定的、可操作的功能开始生效。 package.json type
设置是此处错误的实际原因。参见 here