[Electron][TypeScript] output/input files
Tags: electron, typescript
Published: 2021-05-16 01:08:23

## Intro
This time, I will try outputting logs, loading external settings files.

* [[TypeScript] Try Electron](https://dev.to/masanori_msl/typescript-try-electron-43a0)
* [[Electron][TypeScript][PDF.js] Create images from PDF](https://dev.to/masanori_msl/electron-typescript-pdf-js-create-images-from-pdf-55af)
* [[PDF-LIB][Electron][TypeScript] Edit PDF](https://dev.to/masanori_msl/pdf-lib-electron-typescript-edit-pdf-58hp)

#### Environments
* Node.js ver.16.1.0
* TypeScript ver.4.2.4
* Electron ver.12.0.2
* electron-log ver.4.3.5
* electron-store ver.8.0.0

## Outputting logs
For outputting logs on Electron applications, I choosed "electron-log".

* [GitHub - megahertz/electron-log: Just a simple logging module for your Electron application](https://github.com/megahertz/electron-log)

### From Electron side
I can output logs like below.

#### main.ts
```ts
...
import * as log from 'electron-log';
...
log.debug('hello');

function createWindow (filePath: string): BrowserWindow {
  log.error('create window');
...
}
```

#### Result
##### Console
```
08:09:23.097 > hello
08:09:23.160 > create window
```
#### main.log
```
[2021-05-16 08:09:23.097] [debug] hello
[2021-05-16 08:09:23.160] [error] create window
```

By default, the log files are saved in "C:/Users/example/AppData/Roaming/{ApplicationName}/logs".

And they are divided in "main.log" and "renderer.log".

So if I call "log.debug('hello')" from "preload.ts", the logs are written in "renderer.log".

### Change saving directory and file names
I can change the saving directory and the file names.

```ts
log.debug('before');
log.transports.file.resolvePath = () => 'C:/Users/example/OneDrive/Documents/sample.log';
log.debug('after');
```

Of cource, before changing the path, the logs are saved at default path.
And "log.transports.file.resolvePath" is only affected in the same file.

So if I execute "log.transports.file.resolvePath" only in "main.ts", the logs of "preload.ts" are saved in "C:/Users/example/AppData/Roaming/{ApplicationName}/logs/renderer.log".

### Client side
"electron-log" only can be used in Node.js applications.
So I can't use it in client side.

So I add outputting log functions in the contextBridge.

#### global.d.ts
```ts
declare global {
    interface Window {
        myapi: Sandbox
    };
}
export interface Sandbox {
    greet: (message: string) => void,
    saveFile: (name: string, data: Uint8Array) => void,
    logDebug: (callFrom: string, message: string) => void,
    logError: (callFrom: string, message: string) => void,
};
```
#### preload.ts
```ts
import { ipcRenderer, contextBridge } from 'electron';
import * as log from 'electron-log';

window.addEventListener('DOMContentLoaded', () => {
    log.warn('Loaded');
});
contextBridge.exposeInMainWorld('myapi', {
    greet: async (data: any) => await ipcRenderer.invoke('greet', data),
    saveFile: async (name: string, data: Uint8Array) => await ipcRenderer.invoke('saveFile', name, data),
    logDebug: (callFrom: string, message: string) => log.debug(`[${callFrom}] ${message}`),
    logError: (callFrom: string, message: string) => log.error(`[${callFrom}] ${message}`)
  }
);
```

#### main.page.ts
```ts
...
export async function load(filePath: string) {
    window.myapi.logDebug('main', 'call from client');
...
}
```
#### Result
```
[2021-05-16 08:59:06.969] [warn]  Loaded
[2021-05-16 08:59:06.978] [debug] [main] call from client
```

## Loading external settings files
When I searched how to load config files in Electron applications, I found "electron-store".

* [GitHub - sindresorhus/electron-store: Simple data persistence for your Electron app or module - Save and load user preferences, app state, cache, etc](https://github.com/sindresorhus/electron-store)

I can save user settings in "config.json".

main.ts
```ts
...
import ElectronStore from 'electron-store';

const settings = new ElectronStore();
settings.set({
  filePath: 'example'
});
...
```

The file is saved at "C:/Users/example/AppData/Roaming/{ApplicationName}".

#### config.json
```json
{
	"filePath": "example"
}
```

But in this time, I want to load external settings file like "appsettings.json" in ASP.NET Core.

So I just load JSON file by fs.

#### settingsLoader.ts
```ts
import * as fs from 'fs';
import { AppSettings } from "print.type";

export async function load(): Promise<AppSettings> {
    const fileData = await fs.promises.readFile('./appsettings.json', {
        encoding: 'utf-8'
    });
    return JSON.parse(fileData);
}
```
#### appsettings.json
```ts
{
    "filePath": "sample.pdf"
}
```