typescript - fel TS2307: Kan inte hitta modulen 'path' eller dess motsvarande typdeklarationer. när man försöker migrera i Heroku-app med Knex


Jag vill migrera en SQlite-databas:

knex --knexfile knexfile.ts migrate:latest

Men detta ger följande TypeScript-fel:

⨯ 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'),
                               ~~~~~~~~~

Nedan är min 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,
};

Hur kan jag ta itu med ett sådant problem? Jag använder följande beroenden:

devDependenciesberoenden
"@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"

Redigera package.json-filen

{
  "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"
  }
}

Svar #1

TypeScript

Det omedelbara problemet här är att du försöker använda TypeScript vid körning, men du har definierat @types/node som ett utvecklingsberoende. Som standard tar Heroku bort devDependencies från ditt projekt efter att det har byggts.

Ett alternativ är att hoppa över beskärningssteget, vilket kommer att lämna dina devDependencies på plats, men det är troligen inte det rätta valet. Normalt vill du att dessa beroenden ska tas bort. Bland annat minskar detta storleken på din applikationsslug.

Ett annat alternativ är att flytta @types/node från devDependencies till dependencies. Men jag tror inte att det är rätt drag här heller. Min magkänsla säger att du inte borde använda TypeScript alls i produktion.

Eftersom ditt build-skript helt enkelt kör tsc, undrar jag om det redan har kompilerat din knexfile.ts till knexfile.js. Om det har gjort det kan du försöka köra JavaScript-filen direkt:

knex --knexfile knexfile.js migrate:latest

Eftersom det är den standardfil som Knex letar efter, kan du faktiskt helt hoppa över argumentet:

knex migrate:latest

SQLite

Detta borde få dina migreringar att börja, men du kommer att stöta på ett annat problem: Herokus kortlivade filsystem gör SQLite till ett dåligt databasval.

Alla ändringar du gör i databasen, inklusive schemaändringar som införts av dina migrationer, kommer att gå förlorade varje gång din dyno startar om. Detta händer ofta (minst en gång per dag).

För att lösa det problemet vill du byta från SQLite till en klient-serverdatabas. Herokus egen Postgres-tjänst är en rimlig startpunkt, men det finns andra databastillägg om du föredrar det. Du kan också vara värd för din egen databas någon annanstans i molnet, t.ex. på Microsoft Azure eller AWS.

Svar #2

Jag hade samma problem med en annan modul, jag försökte importera @mui/x-data-grid i en fil, men fick samma fel. Jag upptäckte, som nämnts av @Chris ovan, att biblioteket fanns i dependencies-objektet och inte i devDependencies, så jag behövde bara ta bort det och installera det igen i devDependencies, nu är felmeddelandet borta. Det verkar som att @types/node måste finnas i samma dependencies-objekt (dev eller inte) som modulen du försöker använda.

Relaterade artiklar