Node.js中require语句作立即执行函数报错的原因及解决咨询
问题:Express.js持久化会话中sqlite3引入错误
我在大学课程开发Node.js服务器,参照讲义代码实现Express.js持久化会话时碰了壁。讲义里的引入代码是:
var session = require('express-session'); var SQLiteStore = require('sqlite3')(session);
运行后直接报错:
var SQLiteStore = require("sqlite3")(session); ^ TypeError: require(...) is not a function at Object.<anonymous> (C:\Users\jordv\OneDrive\Documenten\UU\2022 -2023\Blok 3\Web Technology\test\server.js:12:37) at Module._compile (node:internal/modules/cjs/loader:1254:14) at Module._extensions..js (node:internal/modules/cjs/loader:1308:10) at Module.load (node:internal/modules/cjs/loader:1117:32) at Module._load (node:internal/modules/cjs/loader:958:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) at node:internal/main/run_main_module:23:47
我找了相关帖子但看不懂置顶答案,有两个问题:
- 帖子里提到了立即执行函数,为啥我的代码算立即执行函数?而且错误提示它不是函数,这不是矛盾吗?
- 帖子里的解决方案怎么用到我的场景里?
补充信息:按建议执行console.log(sqlite3),输出如下:
{ Database: [Function: Database], Statement: [Function: Statement], Backup: [Function: Backup], OPEN_READONLY: 1, OPEN_READWRITE: 2, OPEN_CREATE: 4, OPEN_FULLMUTEX: 65536, OPEN_URI: 64, OPEN_SHAREDCACHE: 131072, OPEN_PRIVATECACHE: 262144, VERSION: '3.41.1', SOURCE_ID: '2023-03-10 12:13:52 20399f3eda5ec249d147ba9e48da6e87f969d7966a9a896764ca437ff7e737ff', VERSION_NUMBER: 3041001, OK: 0, ERROR: 1, INTERNAL: 2, PERM: 3, ABORT: 4, BUSY: 5, LOCKED: 6, NOMEM: 7, READONLY: 8, INTERRUPT: 9, IOERR: 10, CORRUPT: 11, NOTFOUND: 12, FULL: 13, CANTOPEN: 14, PROTOCOL: 15, EMPTY: 16, SCHEMA: 17, TOOBIG: 18, CONSTRAINT: 19, MISMATCH: 20, MISUSE: 21, NOLFS: 22, AUTH: 23, FORMAT: 24, RANGE: 25, NOTADB: 26, LIMIT_LENGTH: 0, LIMIT_SQL_LENGTH: 1, LIMIT_COLUMN: 2, LIMIT_EXPR_DEPTH: 3, LIMIT_COMPOUND_SELECT: 4, LIMIT_VDBE_OP: 5, LIMIT_FUNCTION_ARG: 6, LIMIT_ATTACHED: 7, LIMIT_LIKE_PATTERN_LENGTH: 8, LIMIT_VARIABLE_NUMBER: 9, LIMIT_TRIGGER_DEPTH: 10, LIMIT_WORKER_THREADS: 11, cached: { Database: [Function: Database], objects: {} }, verbose: [Function (anonymous)] }
解答
先解决你的两个疑问
- 你的代码不属于立即执行函数,那个帖子的场景和你的完全不同,别被误导。错误提示的核心是:你把
require('sqlite3')的返回值当成函数调用了,但它实际返回的是一个包含Database、常量等属性的普通对象,根本不是函数,所以才会报错,和立即执行函数没有任何关系。 - 那个帖子的解决方案对你不适用,因为问题根源完全不同,你得换思路解决。
问题根源与正确解决方案
讲义里的代码写错了——sqlite3本身是纯SQLite操作库,不是专门为express-session做的存储引擎适配。你需要用connect-sqlite3这类专门的会话存储包。
具体步骤:
- 调整依赖包:
npm uninstall sqlite3 npm install express-session connect-sqlite3
- 修改代码:
var session = require('express-session'); var SQLiteStore = require('connect-sqlite3')(session);
- 配置session中间件示例:
app.use(session({ store: new SQLiteStore({ db: 'sessions.db', // 会话存储的数据库文件名 dir: './db' // 数据库文件存放目录,不存在会自动创建 }), secret: 'your-custom-secret-key', // 替换成你的密钥 resave: false, saveUninitialized: false, cookie: { maxAge: 7 * 24 * 60 * 60 * 1000 } // 会话有效期7天 }));
为什么之前的代码会错?
从你打印的sqlite3输出能看到,这个模块导出的是一个对象,里面只有数据库操作类和常量,没有可以接收session参数的函数。而connect-sqlite3才是专门为express-session做的适配,它导出的是一个函数,接收session对象后会返回可用的SQLiteStore类——大概率是讲义里把包名写错了。
内容的提问来源于stack exchange,提问作者Jord van Eldik
相关产品推荐
相关产品推荐

