Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Winston logger library NOT compatible with bytecodePlugin #703

Open
4 tasks done
praveentrigent opened this issue Jan 23, 2025 · 3 comments
Open
4 tasks done

Winston logger library NOT compatible with bytecodePlugin #703

praveentrigent opened this issue Jan 23, 2025 · 3 comments

Comments

@praveentrigent
Copy link

praveentrigent commented Jan 23, 2025

Describe the bug

I’m encountering an issue with the bytecodePlugin when used in my electron app. The bug occurs in a file that uses the winston library for logging. While the app runs correctly without the bytecodePlugin, enabling it causes the app to throw the following error at runtime:

TypeError: Cannot read properties of undefined (reading 'info')

Complete Error:

App threw an error during load
TypeError: Cannot read properties of undefined (reading 'info')
    at Object.<anonymous> (~/Documents/ai-electron-app/some-app/out/main/utils/rubrify.jsc:1:115)
    at Module._extensions..jsc.Module._extensions..cjsc (~/Documents/ai-electron-app/some-app/out/main/bytecode-loader.cjs:71:26)

The issue seems related to how the plugin handles the winston library or its dynamic behavior. Without the plugin, everything works as expected.

Steps performed to Reproduce

  1. Used the winston library for logging in logger.js:
const winston = require('winston');
const util = require('util');
const { app, ipcMain } = require('electron');
const path = require('path');

// Combine message and splat for proper formatting
const combineMessageAndSplat = () => ({
  transform(info) {
    const { [Symbol.for('splat')]: args = [], message } = info;
    info.message = util.format(message, ...args);
    return info;
  },
});

// Create the logger instance
const createLogger = () => winston.createLogger({
  format: winston.format.combine(
    winston.format.timestamp(),
    combineMessageAndSplat(),
    winston.format.printf((info) => `${info.timestamp} ${info.level}: ${info.message}`),
  ),
});

// Create the renderer logger instance
const createRendererLogger = () => winston.createLogger({
  format: winston.format.combine(
    winston.format.timestamp(),
    combineMessageAndSplat(),
    winston.format.printf((info) => `${info.timestamp} ${info.level}: ${info.message}`),
  ),
});

// Determine log directory path
const logDirPath = app.isPackaged ? app.getPath('logs') : './logs';

// Initialize the main logger
const logger = createLogger();
logger.add(new winston.transports.File({
  level: 'debug',
  filename: path.join(logDirPath, 'main.log'),
  options: { flags: 'a' },
}));

// In development, also log to the console
if (!app.isPackaged) {
  logger.add(new winston.transports.Console());
}

// Initialize the renderer logger
const rendererLogger = createRendererLogger();
rendererLogger.add(new winston.transports.File({
  level: 'debug',
  filename: path.join(logDirPath, 'renderer.log'),
  options: { flags: 'a' },
}));

// In development, also log to the console
if (!app.isPackaged) {
  rendererLogger.add(new winston.transports.Console());
}

// Handle IPC events
ipcMain.on('log-info', (_event, message) => {
  rendererLogger.info(message);
});

ipcMain.on('log-error', (_event, message) => {
  rendererLogger.error(message);
});

ipcMain.on('log-warn', (_event, message) => {
  rendererLogger.warn(message);
});

module.exports = { logger, rendererLogger };
  1. Added the bytecodePlugin to the electron vite config (electron.vite.config.js):
import { bytecodePlugin, defineConfig, externalizeDepsPlugin, loadEnv } from "electron-vite";
import json from "@rollup/plugin-json";
import react from "@vitejs/plugin-react";
import { globSync } from "glob";
import path from "path";
import copy from "rollup-plugin-copy";
import { builtinModules } from "module";

// Helper function to generate entry points
const generateMainEntries = () => {
  const entries = globSync("src/main/**/*.js");
  return Object.fromEntries(
    entries.map((file) => {
      const name = path
        .relative("src/main", file)
        .replace(path.extname(file), "");
      return [name, path.resolve(__dirname, file)];
    })
  );
};

export default defineConfig({
  main: {
    build: {
      minify: true,
      sourcemap: true,
      rollupOptions: {
        input: generateMainEntries(),
        output: {
          entryFileNames: "[name].js",
        },
        external: [...builtinModules, "electron", "electron-store", "conf", "ajv", "@radix-ui/*", "@reduxjs/toolkit","react","react-dom"],
        plugins: [json(),externalizeDepsPlugin(),bytecodePlugin(),copy({...})],
      },
    },
  },
  preload: {
    build: {
      rollupOptions: {
        input: path.resolve(__dirname, "src/preload/preload.js"),
        plugins: [
          json(),
          bytecodePlugin(),
          externalizeDepsPlugin(),
        ],
      },
    },
  },
  renderer: {
    plugins: [
      react(),
      copy(
        {...}
      ),
    ],
    css: {...},
    build: {...},
    resolve: {...},
    define: {...},
  },
});
  1. Build the application using electron-vite preview or electron-vite dev (If you build the application, everything will build inside out/ directory just fine. But when running it using electron-vite preview it throws error.

  2. Run the application.


Expected Behavior

The app should run without errors when using the bytecodePlugin, with the winston logger functionality intact.


Observed Behavior

The app throws the following error when bytecodePlugin is enabled:

TypeError: Cannot read properties of undefined (reading 'info')

Additional Details

  • The issue is resolved when the bytecodePlugin is disabled, indicating it is related to how the plugin handles the winston library.
  • Externalizing winston in the Vite configuration did not resolve the issue.
  • I tried sandbox: false in my main window code but the issue persisted
  • I tried removing the ipc.* statements from the above logger code, yet the isse persisted.

Observations

  • I noticed a similar issue was raised in the context of electron-store (#568). In that case, the suggested workaround was to use an alternative library. While exploring alternatives can be helpful, it doesn’t fully address the underlying compatibility issues with the bytecodePlugin.

  • I believe resolving this would benefit the community by improving the usability of the bytecodePlugin with widely used libraries like winston. I would greatly appreciate any guidance or insights on addressing this issue. Your expertise and support can help make this plugin even more robust and user-friendly.

See also: #568

Electron-Vite Version

2.3.0

Electron Version

33.3.1

Vite Version

5.4.11

Validations

@alex8088
Copy link
Owner

  1. Bad config
  2. You should install winston into dependencies

It is recommended that you use the following way to create projects.
https://electron-vite.org/guide/#scaffolding-your-first-electron-vite-project

recommended: https://github.com/alex8088/electron-winston

@praveentrigent
Copy link
Author

Thanks for the response @@alex8088 !

I have installed winston into dependencies only (see screenshot). However, I will try to install electron-winston and also scaffold the project from electron vite project in the recommended way and update in a couple of days.

Image

@praveentrigent
Copy link
Author

@alex8088 I used the right way to scaffold the project and moved required code files into the new one and installed electron-winston and it is working fine Thanks for that!!.

But what is the way to configure log files in electron-winston? I want main.log and renderer.log.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants