我正在阅读Sequelize和Node.js的this教程。我在第4行得到以下错误:
TypeError:Path必须是字符串。收到未定义的
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(module.filename);
const env = process.env.NODE_ENV || 'development';
const config = require(`${__dirname}/../config/config.json`)[env];
const db = {};
let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable]);
} else {
sequelize = new Sequelize(
config.database, config.username, config.password, config
);
}
fs
.readdirSync(__dirname)
.filter(file =>
(file.indexOf('.') !== 0) &&
(file !== basename) &&
(file.slice(-3) === '.js'))
.forEach(file => {
const model = sequelize.import(path.join(__dirname, file));
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;
似乎module.filename未定义。我不知道为什么会这样(我是Node的新手),与教程和我的应用程序的唯一区别是我不使用快速api(但GraphQL)和我的sequelize自动生成的文件夹位于。 ./postgres/而不是../
修改
如果我运行教程repo并打印module.filename
,我会得到/Users/Creece/Downloads/postgres-express-node-tutorial-master/server/models/index.js
现在,如果我手动分配module.filename,如下所示:module.filename = '/Users/Creece/Downloads/express_graphql_hmr_article_boilterplate-master/server/postgres/models/index.js';
(在分配基本名称常量之前),我在const model = ...
行上得到一个新的奇怪错误:
Error: Cannot find module '/Users/Creece/Downloads/express_graphql_hmr_article_boilerplate-master/server/dist/postgres/models/todo.js'
请注意文件夹" dist"在上面的路径上是webpack(虽然不确定,但它不是我的)。
编辑2 :(关于我对@ NikMartin的评论&#39>
这是Sequelize ./postgres/models/todo.js自动生成的文件:
module.exports = (sequelize, DataTypes) => {
const Todo = sequelize.define('Todo', {
title: {
type: DataTypes.STRING,
allowNull: false,
},
});
Todo.associate = (models) => {
Todo.hasMany(models.TodoItem, {
foreignKey: 'todoId',
as: 'todoItems',
});
};
return Todo;
};
解决方案(根据接受的答案):
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
//const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(`${__dirname}/../config/config.json`)[env];
const db = {};
let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable]);
} else {
sequelize = new Sequelize(
config.database, config.username, config.password, config
);
}
const models = [
require('./Todo')(sequelize, Sequelize),
require('./TodoItem')(sequelize, Sequelize),
];
models.forEach(model => {
db[model.name] = model;
});
models.forEach(model => {
if (db[model.name].associate) {
console.log("entered");
db[model.name].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
答案 0 :(得分:1)
关于module.filename
问题,您可以阅读此讨论或仅阅读该评论:https://github.com/webpack/webpack/issues/1599#issuecomment-328540024
报价:
aprilmintacpineda评论
对于那些遇到此问题的人,还可以注意到,如果捆绑了文件,module.filename将是未定义的。在我的情况下它是未定义的,我通过简单地用__filename替换它来修复它,产生相同的结果。
因此,您应该能够将path.basename(module.filename);
替换为path.basename(__filename);
。
但它仍然是/ dist文件夹中的捆绑js文件,你的模型在/ postgres / models文件夹中,据我所知。
1)不要自动加载模型,而是直接需要所有必要的模型。
假设此文件的路径为/postgres/models/index.js
且实际模型位于同一文件夹中
未经过测试
const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = require(`${__dirname}/../config/config.json`)[env];
const db = {};
let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable]);
} else {
sequelize = new Sequelize(
config.database, config.username, config.password, config
);
}
// removed autoloading block
// setting the list of used models
const models = [
require('./TodoItem')(sequelize, Sequelize),
require('./Comment')(sequelize, Sequelize)
];
// registering models by their names
models.forEach(model => {
db[model.name] = model;
});
// using registered models to set up relations
models.forEach(model => {
if (model.associate) {
model.associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
这意味着灵活性会降低,但捆绑的代码会开始使用捆绑的模型。我认为对于需要一些"外部"的dist代码来说,这不是最好的选择。 (缺少内部模型)非配置js文件工作。
2)加载不是来自当前文件夹但来自已定义文件的文件。
/postgres/models/index.js
从models文件夹移到/postgres/index.js
(因此模型文件夹只包含实际的模型文件)basename
.readdirSync(__dirname)
使用.readdirSync(__dirname + "/../postgres/models")
(file !== basename) &&
检查(因为没有必要)无论哪种方式,替换模块的属性(module.filename
)都不应该是一个解决方案。
答案 1 :(得分:0)
可以这样简化:
const config = require('../config/config')['development']
const {Sequelize} = require('sequelize');
const sequelize = new Sequelize(config['dbUrl']);
const db = {};
const models = [];
sequelize.authenticate()
.then(() => console.log('Connection has been established successfully.'))
.catch(err => console.error('Unable to connect to the database:', err));
const modules = [
require('./user'),
require('./post'),
require('./comment')
]
modules.forEach(module => {
const model = module(sequelize, Sequelize)
db[model.name] = model
models.push(model)
});
models.forEach(model => {
if (db[model.name].associate) {
db[model.name].associate(db)
}
});
module.exports = {...db, sequelize, Sequelize};