Процесс визуализации выходит из памяти после того, как приложение упаковано в EXE

#node.js #reactjs #electron #electron-packager

Вопрос:

Ожидаемое поведение В моем главном окне визуализации Я инициализирую пользовательский интерфейс из импортированного модуля. При запуске приложения в режиме разработки все работает, но как только я упаковываю приложение в EXE и пытаюсь запустить его, я получаю ошибку процесса визуализации из памяти.

Ожидаемое поведение заключается в том, что упакованное приложение должно работать в режиме разработки.

Фактическое поведение Я проверил электронные журналы и потребление памяти в диспетчере задач Windows. Использование памяти продолжает увеличиваться до тех пор, пока процесс визуализации не завершится сбоем, и электрон не зарегистрирует ошибку oom. Поскольку я новичок в electron, я прочитал документацию, но не смог понять, почему то же самое отлично работает в режиме разработки и выходит из строя в prod. Журнал : Renderer process oom - see https://www.electronjs.org/docs/tutorial/application-debugging for potential debugging information. Еще один журнал через некоторое время : [19156:0921/120104.184:ERROR:gpu_init.cc(440)] Passthrough is not supported, GL is swiftshader

Так вот что я пытаюсь сделать —

Импортируйте мой модуль, который обслуживается на локальном хосте:

Этот модуль предоставляет объект — Тессеракт, с помощью которого я инициализирую свой пользовательский интерфейс.

В компоненте, который отображается в моем главном окне браузера, я инициализирую пользовательский интерфейс следующим образом: Файл — индекс.tsx

 useEffect(() => {
if (tsToken) {
Tesseract.ui
.init(tsToken.tsToken, "random_id")
.then((sdk: any) => {
console.log("🚀 ~ file: index.js ~ line 3 ~ sdk", sdk);
// After this line nothing is logged and renderer process crashes (But works when I run electron in dev mode)
sdk.init({
...MasterConfig,
RootElement: document.getElementById("tesseract-root"),
});

    const authToken = sessionStorage.getItem("ts_token");
    ipcRenderer.send("set-globals", { TAC: authToken });
  })
  .catch((err: any) => console.error(err));
}
}, [tsToken]);

return <></>;
 

В приведенном выше фрагменте кода мы передаем корневой элемент методу init. Затем метод init инициализирует приложение react в этом корневом элементе.

EDIT:
This is the init method in that module

 SDK.prototype.init = async function (config) {
try {
  const parsedConfig = JSON.parse(this.META.uiConfig);
  window.Tesseract.ui["MasterConfig"] = merge(parsedConfig, config);
  window.Tesseract.ui["info"] = this.META;

  const projectType = window.Tesseract.ui.MasterConfig.ProjectConfig.type;
  console.log("🚀 ~ file: lib.js ~ line 51 ~ projectType", projectType)

  const MasterConfig = window.Tesseract.ui["MasterConfig"];
  console.log(MasterConfig);
  if (
    MasterConfig amp;amp;
    MasterConfig.UserProperties amp;amp;
    MasterConfig.UserProperties.userId
  ) {
    console.log("React init here");
    // Console logs upto this point and then everything fails
    // No error logged 
    try {
      RecorderUI.ReactApp({ ...parsedConfig, ...config }).then((obj) => {
        // This is never logged
        console.log("UI rendered");
        return obj;
      }).catch(err => console.log(err));
    } catch (err) {
      console.log(err);
      return err;
    }
  } else {
    const e = new Error("User Id Missing");
    e.name = "Missing unique user Id";
    throw e;
  }
} catch (err) {
  console.error(err);
  return err;
}
};
 

Это метод визуализации пользовательского интерфейса:

 export default async function entry(config) {
  // This is never logged so basically something is happening before this
  console.log("somemmthing something");
  console.log("Root Element: ", 
  window.Tesseract?.ui?.MasterConfig?.RootElement);
  try {
    const { RootElement } = config;
    RootElement.attachShadow({ mode: "open" });

    await IDBStore.create({
      version: 1,
      name: "ext",
      schema: {
        globals: "amp;key",
      },
    });

    const shadowRoot = RootElement.shadowRoot;
    const styleElement = document.createElement("style");
    styleElement.innerHTML = `${LoaderCss} ${SourcePreviewCSS} ${NotificationCss} ${LibraryCss} ${SelectModeCss} ${WebcamBoxCss} ${CameraBubbleCss} ${countdownCss} ${indexStyles} ${commonCss} ${colorsCss} ${homeCss} ${recordCss} ${advancedOptionsCss} ${recordingTypesCss} ${toggleOptionsCss} ${tourOverlayCss} ${headerCss} ${checkboxCss} ${tooltipCss} ${dropdownCss} ${toggleCss} ${recordButtonCss} ${bannersCss} ${toolsCss} ${canvasCss} ${paintCss} ${recordingControlsCss} ${controlsMainCss}`;
  const reactRoot = document.createElement("div");
  reactRoot.setAttribute("id", "react-root");
  shadowRoot.appendChild(styleElement);
  shadowRoot.appendChild(reactRoot);

  ReactDOM.render(
    <Provider store={store}>
      <App />
    </Provider>,
    reactRoot
  );
  window.addEventListener("message", handleMessaging, false);
} catch (err) {
  console.error(err);
  return new Error(err);
}
}
 

Я прочитал множество сообщений в блогах, проблемы с github, но не смог найти причину этого. Мне нужна помощь в определении того, в чем разница во внутренней работе электрона, которая вызывает такую разницу в ч/б, работающую в режиме разработки, по сравнению с упаковкой приложения.

Комментарии:

1. Если у вас возникли проблемы, которые, по вашему мнению, вызваны ошибками, задайте их в репозитории Electron GitHub . Мы не можем исправлять ошибки.

2. Привет @IanKemp, хотя это происходит в электронном приложении, но я на 100% уверен, что это node.js утечка памяти. Я мало что знаю об утечках памяти nodejs. Я прочитал основные вещи, которые нужно проверить, которые могут вызвать утечку памяти, но пока не повезло. Я могу объяснить, как мы создали этот модуль «Tessseract», который инициализирует пользовательский интерфейс, если это поможет

3. @IanKemp Я добавил соответствующие методы в вопросы. Не могли бы вы взглянуть ?