错误 TS2307:找不到模块 'path' 或其对应的类型声明。尝试使用 Knex 在 heroku 应用程序中迁移时
error TS2307: Cannot find module 'path' or its corresponding type declarations. when trying to migrate in heroku app with Knex
我想迁移一个 SQlite 数据库:
knex --knexfile knexfile.ts migrate:latest
然而,这给出了以下打字稿错误:
⨯ Unable to compile TypeScript:
knexfile.ts:1:18 - error TS2307: Cannot find module 'path' or its corresponding type declarations.
1 import path from 'path';
~~~~~~
knexfile.ts:4:1 - error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.
4 module.exports = {
~~~~~~
knexfile.ts:7:28 - error TS2304: Cannot find name '__dirname'.
7 filename: path.resolve(__dirname, 'src', 'database', 'database.sqlite'),
~~~~~~~~~
knexfile.ts:10:29 - error TS2304: Cannot find name '__dirname'.
10 directory: path.resolve(__dirname, 'src', 'database', 'migrations'),
~~~~~~~~~
knexfile.ts:13:29 - error TS2304: Cannot find name '__dirname'.
13 directory: path.resolve(__dirname, 'src', 'database', 'seeds'),
~~~~~~~~~
TSError: ⨯ Unable to compile TypeScript:
knexfile.ts:1:18 - error TS2307: Cannot find module 'path' or its corresponding type declarations.
1 import path from 'path';
~~~~~~
knexfile.ts:4:1 - error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.
4 module.exports = {
~~~~~~
knexfile.ts:7:28 - error TS2304: Cannot find name '__dirname'.
7 filename: path.resolve(__dirname, 'src', 'database', 'database.sqlite'),
~~~~~~~~~
knexfile.ts:10:29 - error TS2304: Cannot find name '__dirname'.
10 directory: path.resolve(__dirname, 'src', 'database', 'migrations'),
~~~~~~~~~
knexfile.ts:13:29 - error TS2304: Cannot find name '__dirname'.
13 directory: path.resolve(__dirname, 'src', 'database', 'seeds'),
~~~~~~~~~
下面是我的 knexfile
:
import path from 'path';
import 'dotenv/config';
module.exports = {
client: 'sqlite3',
connection: {
filename: path.resolve(__dirname, 'src', 'database', 'database.sqlite'),
},
migrations: {
directory: path.resolve(__dirname, 'src', 'database', 'migrations'),
},
seeds: {
directory: path.resolve(__dirname, 'src', 'database', 'seeds'),
},
useNullAsDefault: true,
};
如何解决此类问题?
我正在使用以下依赖项:
devDependencies
dependencies
"@types/bcryptjs": "^2.4.2",
"@vscode/sqlite3": "^5.0.8"
"@types/cors": "^2.8.7",
"bcryptjs": "^2.4.3"
"@types/express": "^4.17.7",
"cors": "^2.8.5"
"@types/jsonwebtoken": "^8.5.8"
"dotenv": "^8.2.0"
"@types/node": "^17.0.24"
"express": "^4.17.1"
"knex-types": "^0.3.2"
"jsonwebtoken": "^8.5.1"
"ts-node-dev": "^1.0.0-pre.56"
"knex": "^1.0.7"
"typescript": "^4.6.3"
"ts-node": "^8.10.2"
"sqlite3": "^5.0.3"
编辑package.json
文件
{
"name": "imonitor-server",
"version": "1.0.0",
"description": "",
"main": "src/server.ts",
"scripts": {
"start": "node build/src/server.js",
"postinstall": "tsc",
"dev": "tsnd --transpile-only --ignore-watch node_modules --respawn src/server.ts",
"knex:migrate": "knex --knexfile knexfile.ts migrate:latest",
"knex:seed": "knex --knexfile knexfile.ts seed:run",
"knex:rollback": "knex --knexfile knexfile.ts migrate:rollback",
"build": "tsc"
},
"repository": {
"type": "git",
"url": "git+https://github.com/lucasbbs/imonitor-backend.git"
},
"keywords": [],
"engines": {
"node": "16.14.0",
"npm": "8.3.1"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/lucasbbs/imonitor-backend/issues"
},
"homepage": "https://github.com/lucasbbs/imonitor-backend#readme",
"devDependencies": {
"@types/bcryptjs": "^2.4.2",
"@types/cors": "^2.8.7",
"@types/express": "^4.17.7",
"@types/jsonwebtoken": "^8.5.8",
"@types/node": "^17.0.24",
"knex-types": "^0.3.2",
"ts-node-dev": "^1.0.0-pre.56",
"typescript": "^4.6.3"
},
"dependencies": {
"@vscode/sqlite3": "^5.0.8",
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"knex": "^1.0.7",
"pg": "^8.3.0",
"sqlite3": "^5.0.3",
"ts-node": "^8.10.2"
}
}
TypeScript
这里的直接问题是您在 运行 时尝试使用 TypeScript,但您已将 @types/node
定义为开发依赖项。默认情况下,Heroku strips devDependencies
from your project after building it.
一种选择是 skip the pruning step,这将使您的 devDependencies
保持原样,但这可能不是正确的选择。通常您会希望去除这些依赖项。除其他原因外,这还减小了应用程序 slug 的大小。
另一种选择是将 @types/node
从 devDependencies
移动到 dependencies
。但我也不认为这是正确的举动。我的直觉告诉你根本不应该在生产中使用 TypeScript。
由于您的 build
脚本只是 运行s tsc
,我想知道它是否已经将您的 knexfile.ts
编译为 knexfile.js
。如果是这样,您可以尝试 运行 直接 JavaScript 文件:
knex --knexfile knexfile.js migrate:latest
由于这是 Knex 查找的默认文件,您实际上可以完全跳过该参数:
knex migrate:latest
SQLite
这应该让您的迁移继续进行,但您将 运行 进入另一个问题:Heroku 的 ephemeral filesystem 使 SQLite 成为一个糟糕的数据库选择。
您对数据库所做的任何更改,包括迁移引入的架构更改,都将在您的 dyno 重新启动时丢失。这 happens frequently(每天至少一次)。
要解决该问题,您需要从 SQLite 切换到 client-server 数据库。如果您愿意,可以使用 Heroku 自己的 Postgres service is a reasonable starting point, but there are other database addons。您还可以在云的其他地方托管自己的数据库,例如在 Microsoft Azure 或 AWS 上。
我想迁移一个 SQlite 数据库:
knex --knexfile knexfile.ts migrate:latest
然而,这给出了以下打字稿错误:
⨯ Unable to compile TypeScript:
knexfile.ts:1:18 - error TS2307: Cannot find module 'path' or its corresponding type declarations.
1 import path from 'path';
~~~~~~
knexfile.ts:4:1 - error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.
4 module.exports = {
~~~~~~
knexfile.ts:7:28 - error TS2304: Cannot find name '__dirname'.
7 filename: path.resolve(__dirname, 'src', 'database', 'database.sqlite'),
~~~~~~~~~
knexfile.ts:10:29 - error TS2304: Cannot find name '__dirname'.
10 directory: path.resolve(__dirname, 'src', 'database', 'migrations'),
~~~~~~~~~
knexfile.ts:13:29 - error TS2304: Cannot find name '__dirname'.
13 directory: path.resolve(__dirname, 'src', 'database', 'seeds'),
~~~~~~~~~
TSError: ⨯ Unable to compile TypeScript:
knexfile.ts:1:18 - error TS2307: Cannot find module 'path' or its corresponding type declarations.
1 import path from 'path';
~~~~~~
knexfile.ts:4:1 - error TS2580: Cannot find name 'module'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node`.
4 module.exports = {
~~~~~~
knexfile.ts:7:28 - error TS2304: Cannot find name '__dirname'.
7 filename: path.resolve(__dirname, 'src', 'database', 'database.sqlite'),
~~~~~~~~~
knexfile.ts:10:29 - error TS2304: Cannot find name '__dirname'.
10 directory: path.resolve(__dirname, 'src', 'database', 'migrations'),
~~~~~~~~~
knexfile.ts:13:29 - error TS2304: Cannot find name '__dirname'.
13 directory: path.resolve(__dirname, 'src', 'database', 'seeds'),
~~~~~~~~~
下面是我的 knexfile
:
import path from 'path';
import 'dotenv/config';
module.exports = {
client: 'sqlite3',
connection: {
filename: path.resolve(__dirname, 'src', 'database', 'database.sqlite'),
},
migrations: {
directory: path.resolve(__dirname, 'src', 'database', 'migrations'),
},
seeds: {
directory: path.resolve(__dirname, 'src', 'database', 'seeds'),
},
useNullAsDefault: true,
};
如何解决此类问题? 我正在使用以下依赖项:
devDependencies | dependencies |
---|---|
"@types/bcryptjs": "^2.4.2", | "@vscode/sqlite3": "^5.0.8" |
"@types/cors": "^2.8.7", | "bcryptjs": "^2.4.3" |
"@types/express": "^4.17.7", | "cors": "^2.8.5" |
"@types/jsonwebtoken": "^8.5.8" | "dotenv": "^8.2.0" |
"@types/node": "^17.0.24" | "express": "^4.17.1" |
"knex-types": "^0.3.2" | "jsonwebtoken": "^8.5.1" |
"ts-node-dev": "^1.0.0-pre.56" | "knex": "^1.0.7" |
"typescript": "^4.6.3" | "ts-node": "^8.10.2" |
"sqlite3": "^5.0.3" |
编辑package.json
文件
{
"name": "imonitor-server",
"version": "1.0.0",
"description": "",
"main": "src/server.ts",
"scripts": {
"start": "node build/src/server.js",
"postinstall": "tsc",
"dev": "tsnd --transpile-only --ignore-watch node_modules --respawn src/server.ts",
"knex:migrate": "knex --knexfile knexfile.ts migrate:latest",
"knex:seed": "knex --knexfile knexfile.ts seed:run",
"knex:rollback": "knex --knexfile knexfile.ts migrate:rollback",
"build": "tsc"
},
"repository": {
"type": "git",
"url": "git+https://github.com/lucasbbs/imonitor-backend.git"
},
"keywords": [],
"engines": {
"node": "16.14.0",
"npm": "8.3.1"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/lucasbbs/imonitor-backend/issues"
},
"homepage": "https://github.com/lucasbbs/imonitor-backend#readme",
"devDependencies": {
"@types/bcryptjs": "^2.4.2",
"@types/cors": "^2.8.7",
"@types/express": "^4.17.7",
"@types/jsonwebtoken": "^8.5.8",
"@types/node": "^17.0.24",
"knex-types": "^0.3.2",
"ts-node-dev": "^1.0.0-pre.56",
"typescript": "^4.6.3"
},
"dependencies": {
"@vscode/sqlite3": "^5.0.8",
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"knex": "^1.0.7",
"pg": "^8.3.0",
"sqlite3": "^5.0.3",
"ts-node": "^8.10.2"
}
}
TypeScript
这里的直接问题是您在 运行 时尝试使用 TypeScript,但您已将 @types/node
定义为开发依赖项。默认情况下,Heroku strips devDependencies
from your project after building it.
一种选择是 skip the pruning step,这将使您的 devDependencies
保持原样,但这可能不是正确的选择。通常您会希望去除这些依赖项。除其他原因外,这还减小了应用程序 slug 的大小。
另一种选择是将 @types/node
从 devDependencies
移动到 dependencies
。但我也不认为这是正确的举动。我的直觉告诉你根本不应该在生产中使用 TypeScript。
由于您的 build
脚本只是 运行s tsc
,我想知道它是否已经将您的 knexfile.ts
编译为 knexfile.js
。如果是这样,您可以尝试 运行 直接 JavaScript 文件:
knex --knexfile knexfile.js migrate:latest
由于这是 Knex 查找的默认文件,您实际上可以完全跳过该参数:
knex migrate:latest
SQLite
这应该让您的迁移继续进行,但您将 运行 进入另一个问题:Heroku 的 ephemeral filesystem 使 SQLite 成为一个糟糕的数据库选择。
您对数据库所做的任何更改,包括迁移引入的架构更改,都将在您的 dyno 重新启动时丢失。这 happens frequently(每天至少一次)。
要解决该问题,您需要从 SQLite 切换到 client-server 数据库。如果您愿意,可以使用 Heroku 自己的 Postgres service is a reasonable starting point, but there are other database addons。您还可以在云的其他地方托管自己的数据库,例如在 Microsoft Azure 或 AWS 上。