I am creating a vscode extension in typescript, webpack and better-sqlite3. I try to create a database in the C:\Users\userName\AppData\Roaming\Code\User\globalStorage\ folder.
But i get the error:
TypeError: o.default is not a constructor
This is my code:
import Database from 'better-sqlite3';
import * as fs from "fs";
import { DatabaseNames } from "./database-names.enum";
import { PersistenceRepository } from './persistence.repository';
export class BetterSqliteAdapter implements PersistenceRepository {
private static instance: BetterSqliteAdapter | null = null;
db: Database.Database | null = null;
private constructor() { };
;
public static getInstance() {
if (!this.instance) {
this.instance = new BetterSqliteAdapter();
}
return this.instance;
}
createDatabase(name: DatabaseNames, globalStoragePath: string): void {
const dbPath = globalStoragePath + "\\" + name + ".db";
console.log('dbPath :>> ', dbPath);
if (!fs.existsSync(globalStoragePath)) {
throw new Error('Extension folder don\'t exist');
}
if (!fs.existsSync(dbPath)) {
try {
this.db = new Database(dbPath);
} catch (error) {
console.log(`Error creating database: ${name}.db ... error: ${error}`);
}
}
}
this is my tsconfig.json:
{
"compilerOptions": {
"module": "CommonJS",
"target": "ES2020",
"lib": ["ES2020", "DOM"],
"sourceMap": true,
"rootDir": "src",
"strict": true ,
"jsx": "react",
"esModuleInterop": true
}
}
i also tried this (How to correctly and fully import BetterSqlite3's Database class in typescript?) but it doesn't work. Still get the same error.
Update:
The persistence.repository.ts:
import { DatabaseNames } from './database-names.enum';
export interface PersistenceRepository {
/**
* This method will check if a database with a specific name existe, if not, it will be created.
* @param name name of the database to check if exist or create.
*/
createDatabase(name: DatabaseNames, globalStoragePath: string): void;
}
Since it's a vscode extension development, i launch it pressing F5. This is the launch.json (it is the default launch.json from yo-code extension creator):
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
],
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
],
"preLaunchTask": "${defaultBuildTask}"
},
{
"name": "Extension Tests",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test/suite/index"
],
"outFiles": [
"${workspaceFolder}/out/**/*.js",
"${workspaceFolder}/dist/**/*.js"
],
"preLaunchTask": "tasks: watch-tests"
}
]
}
this is the tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "watch",
"problemMatcher": "$ts-webpack-watch",
"isBackground": true,
"presentation": {
"reveal": "never",
"group": "watchers"
},
"group": {
"kind": "build",
"isDefault": true
}
},
{
"type": "npm",
"script": "watch-tests",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never",
"group": "watchers"
},
"group": "build"
},
{
"label": "tasks: watch-tests",
"dependsOn": [
"npm: watch",
"npm: watch-tests"
],
"problemMatcher": []
}
]
}
this is the package.json scripts and dependencies:
"scripts": {
"vscode:prepublish": "npm run package",
"compile": "webpack --mode development --progress",
"watch": "webpack --mode development --progress --watch",
"package": "webpack --mode production ",
"compile-tests": "tsc -p . --outDir out",
"watch-tests": "tsc -p . -w --outDir out",
"pretest": "npm run compile-tests && npm run compile && npm run lint",
"lint": "eslint src --ext ts",
"test": "node ./out/test/runTest.js"
},
"devDependencies": {
"@types/better-sqlite3": "^7.6.5",
"@types/glob": "^8.1.0",
"@types/mocha": "^10.0.1",
"@types/node": "20.2.5",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7",
"@types/vscode": "^1.81.0",
"@typescript-eslint/eslint-plugin": "^5.59.8",
"@typescript-eslint/parser": "^5.59.8",
"@vscode/test-electron": "^2.3.2",
"drizzle-kit": "^0.19.13",
"eslint": "^8.41.0",
"glob": "^8.1.0",
"mini-css-extract-plugin": "^2.7.6",
"mocha": "^10.2.0",
"terser-webpack-plugin": "^5.3.9",
"ts-loader": "^9.4.3",
"typescript": "^5.1.3",
"webpack": "^5.85.0",
"webpack-cli": "^5.1.1"
},
"dependencies": {
"@vscode/webview-ui-toolkit": "^1.2.2",
"better-sqlite3": "^8.6.0",
"drizzle-orm": "^0.28.6",
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
Update 2:
i deleted the node modules, uninstalled better-sqlite3 and re-installed it. Now i have the following error:
TypeError: Cannot read properties of undefined (reading 'indexOf').
If i remove the try / catch clause, no error are thrown.
Update 3:
i deleted the node modules, uninstalled better-sqlite3 and re-installed it AGAIN. Now I have the first error message again
Update 4:
I just tried to create a file directly with 'fs' to check that I have permissions and that my project is not misconfigured. It has worked perfectly. The code i changedis:
createDatabase(name: DatabaseNames, globalStoragePath: string): void {
...
fs.writeFileSync(dbPath, '');
...
}
After many hours of research, at the moment it is not possible to directly use any library for SQLite when developing a vscode extension. At least if you want to work with local files instead of an in-memory database. This is because to use SQLite, each operating system must have different binaries. One of the possible solutions is to use this configuration in the
webpack.config.js:But you will have to find a way for the user to have the necessary binaries installed on their computer.
sources of that information: