sindresorhus / electron-store

Simple data persistence for your Electron app or module - Save and load user preferences, app state, cache, etc
MIT License
4.64k stars 154 forks source link

Module does not provide an export #282

Open jjfufu opened 2 months ago

jjfufu commented 2 months ago

I don't know why, but when i run my project i have this error.

Versions :

$ tsx src/scripts/modules/backend.ts
file:///home/xxxxx/work/xxxxx/xxxxx/node_modules/electron-store/index.js:4
        app,
        ^^^
SyntaxError: The requested module 'electron' does not provide an export named 'app'
    at ModuleJob._instantiate (node:internal/modules/esm/module_job:134:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:217:5)
    at async ModuleLoader.import (node:internal/modules/esm/loader:316:24)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:123:5)
timeowilliams commented 2 months ago

@jjfufu , could you share more code (imports and exports)? Also what repo are you currently running?

jjfufu commented 2 months ago

The program is just a part of an application. I try to run only one module. (it work's under v8.1)

Also what repo are you currently running?

I can't provide the repository.

The executed file

tsx src/scripts/modules/backend.ts

import {ConfigStore, setStoreObject} from '../../shared/utils/store.js'
import {stringToBoolean, stringToNumber} from '../../shared/utils/functions.js'
import {SupportedCollector} from '../../backend/modules/collector/collector.js'
import {BackendModule} from '../../backend/index.js'
import {isDev} from '../../shared/utils/env.js'

function getConfig(): ConfigStore {
    return {...someData}
}

const config = getConfig()
const collectorOptions = config.collector
const database = config.database

setStoreObject(config)

const backend = new BackendModule({
    collectorOptions: {...collectorOptions},
    driverOptions: {
        password: database.password,
        user: database.user,
        database: database.name,
        host: database.host,
        port: database.port
    }
})

const collector = backend.getCollector()

if(!collector) {
    throw new Error(`Collector is not defined. Unsupported collector name ${collectorOptions.name}`)
}

collector.setup()

Store file

import ElectronStore from 'electron-store'

const store = new ElectronStore<ConfigStore>({
    encryptionKey: 'encryptionKey',
    accessPropertiesByDotNotation: true,
})

export const setStoreObject = (object: Partial<ConfigStore>): void => {
    return store.set(object)
}

tsconfig.json

{
  "compilerOptions": {
    "target": "esnext",
    "module": "NodeNext",
    "lib": ["esnext", "dom"],
    "allowJs": true,
    "outDir": "build",
    "strict": true,
    "noImplicitAny": false,
    "esModuleInterop": true,
    "moduleResolution": "NodeNext",
    "resolveJsonModule": true,
    "moduleDetection": "force",
    "isolatedModules": true,

    "noUnusedLocals": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "inlineSources": true,
    "sourceRoot": "/"
  },
  "include": [
    "src/index.ts",
    "src/setup/**/*.ts",
    "src/backend/**/*.ts",
    "src/backend/**/*.d.ts",
    "src/electron/**/*.ts",
    "src/electron/**/*.d.ts",
    "src/shared/**/*.ts",
    "src/shared/**/*.d.ts",
  ],
  "exclude": ["node_modules", "src/frontend", "src/**/tests"]
}
timeowilliams commented 2 months ago

Which OS and version are you currently using?

Electron has 3 different processes (preload, main & renderer) > which process context is this code being ran in?

Are you currently running the tsx src/scripts/modules/backend.ts in the main thread?

Make sure that the store is only initialized once (try to make use of the singleton pattern) and in a context where it can be created (my recommendation is to create this in the main processs) and use IPC connection at the renderer level if you need to send updates to the store.

I also recommend separating the tsconfig.json into two parts > one for the frontend (the renderer process)(tsconfig.web.json) & the backend (tsconfig.node.json).

Then your tsconfig.json will look something like this:

{
  "files": [],
  "references": [{ "path": "./tsconfig.node.json" }, { "path": "./tsconfig.web.json" }]
}

Here's how it can look:

tsconfig.node.json

{
  "extends": "@electron-toolkit/tsconfig/tsconfig.node.json",
  "include": [
    "electron.vite.config.*",
    "src/main/**/*",
    "src/preload/**/*",
    "src/main/*",
    "src/main/**"
  ],
  "compilerOptions": {
    "composite": true,
    "target": "ESNext",
    "moduleResolution": "NodeNext",
    "types": ["electron-vite/node"],
    "baseUrl": ".",
    "paths": {
      "@electron-toolkit/*": ["node_modules/@electron-toolkit/*"]
    }
  },
  "exclude": ["node_modules"]
}

And the `tsconfig.web.json':

{
  "extends": "@electron-toolkit/tsconfig/tsconfig.web.json",
  "include": [
    "src/renderer/src/env.d.ts",
    "src/renderer/src/**/*",
    "src/renderer/src/**/*.tsx",
    "src/preload/*.d.ts",
    "src/renderer/src/**/*.ts",  
    "src/renderer/src/**/*.tsx"  
  ],
  "compilerOptions": {
    "composite": true,
    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "jsx": "preserve",
    "jsxImportSource": "solid-js",
    "allowJs": true,
    "noEmit": true,
    "strict": true,
    "types": ["vinxi/types/client"],
    "baseUrl": ".",
    "paths": {
      "@renderer/*": ["src/renderer/src/*"]
    }
  }
}
Crease29 commented 1 month ago

Heya,

I'm having the same issue and I'm using the vite-electron-builder template for my electron app. I have shared some code in this discussion thread: https://github.com/cawa-93/vite-electron-builder/discussions/1010

Apart from what I've written in that thread, I've also tried calling Store.initRenderer(); in the main process, where it creates the browser window and then running the following in the renderer:

import Store from 'electron-store';

const store = new Store();

Then I'm getting the following error: image

P.S.: I'm running on