{"id":11048,"date":"2026-02-19T10:44:07","date_gmt":"2026-02-19T01:44:07","guid":{"rendered":"https:\/\/code-plus.jp\/gp\/?p=11048"},"modified":"2026-05-28T15:41:58","modified_gmt":"2026-05-28T06:41:58","slug":"electron-app-11048","status":"publish","type":"post","link":"https:\/\/code-plus.jp\/gp\/electron-app-11048\/","title":{"rendered":"Electron \u30a2\u30d7\u30ea\u3092\u4f5c\u308b\u3068\u304d\u306e\u6ce8\u610f\u70b9\u307e\u3068\u3081 - \u30d1\u30c3\u30b1\u30fc\u30b8\u30f3\u30b0\u30fbIPC\u30fb\u30e1\u30e2\u30ea\u7ba1\u7406\u307e\u3067"},"content":{"rendered":"<p>\u5b9f\u969b\u306b Electron \u3067\u30c7\u30b9\u30af\u30c8\u30c3\u30d7\u30a2\u30d7\u30ea\uff08\u8907\u6570\u30d5\u30a1\u30a4\u30eb\u3078\u306e\u4e00\u62ec\u30c6\u30ad\u30b9\u30c8\u7f6e\u63db\u30c4\u30fc\u30eb\uff09\u30920\u304b\u3089\u4f5c\u308a\u307e\u3057\u305f\u3002<br>\u958b\u767a\u4e2d\u306b\u4f55\u5ea6\u3082\u30cf\u30de\u308a\u3001\u305d\u306e\u305f\u3073\u306b\u89e3\u6c7a\u7b56\u3092\u8a18\u9332\u3057\u3066\u304d\u307e\u3057\u305f\u3002\u6b21\u56de\u307e\u305f\u540c\u3058\u8f4d\u3092\u8e0f\u307e\u306a\u3044\u3088\u3046\u3001\u3053\u3053\u306b\u5099\u5fd8\u9332\u3068\u3057\u3066\u307e\u3068\u3081\u3066\u304a\u304d\u307e\u3059\u3002<\/p>\r\n\r\n<a href=\"https:\/\/code-plus.jp\/gp\/multi-grep-replacer-8480\/\" class=\"linkbox my-1.5r\">\r\n<h4 class=\"linkbox-title fz-md\">\u8907\u6570\u30eb\u30fc\u30eb\u3067\u4e00\u62ecgrep\u7f6e\u63db\u30c4\u30fc\u30eb\u300cMulti Grep Replacer\u300d<\/h4>\r\n<picture class=\"linkbox-thumbnail\">\r\n<img decoding=\"async\" width=\"300\" height=\"200\" src=\"https:\/\/code-plus.jp\/gp\/wp-content\/uploads\/e4700776b3f5c511edac5bbe594e4107.png?ver=20260528154158\" alt=\"\u8907\u6570\u30eb\u30fc\u30eb\u3067\u4e00\u62ecgrep\u7f6e\u63db\u30c4\u30fc\u30eb\u300cMulti Grep Replacer\u300d\" loading=\"lazy\" \/>\r\n<\/picture>\r\n<span class=\"linkbox-excerpt\">Web\u958b\u767a\u3084\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u3067\u3001\u3053\u3093\u306a\u7d4c\u9a13\u306f\u3042\u308a\u307e\u305b\u3093\u304b\uff1f\ud83d\udd04 \u540c\u3058\u7f6e\u63db\u4f5c\u696d\u3092\u4f55\u5ea6\u3082\u7e70\u308a\u8fd4\u3057\u3066\u3044\u308b\ud83d\ude13 \u30b5\u30af\u30e9\u30a8\u30c7\u30a3\u30bf\u30675\u3064\u306e\u7f6e\u63db\u30d1\u30bf\u30fc\u30f3\u30921\u3064\u305a\u3064\u5b9f\u884c\u3059\u308b\u306e\u304c\u9762\u5012\u3081\u3093\u3069\u304f\u3055\u304b\u3063\u305f\u306e\u3067\u3001\u8907\u6570\u30eb\u30fc\u30eb\u3067\u4e00\u62ec\u7f6e\u63db\u3067\u304d\u308b\u300cMulti Grep Replacer\u300d \u3092\u4f5c\u3063\u3066\u307f...\r\n&emsp;<u class=\"linkbox-more\">\u7d9a\u304d\u3092\u8aad\u3080<\/u>\r\n<\/span>\r\n<\/a>\r\n\r\n<!-- \u2605\u76ee\u6b21\u30ea\u30b9\u30c8 -->\r\n<ul class=\"tocList mt-1r\" data-toc-id=\"js-tocBWGD\" style=\"height:28rem\"><\/ul>\r\n<ins class=\"tocBtn is-fixed\" data-toc-id=\"js-tocBWGD\"><\/ins>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<hr class=\"separator mt-3r\">\r\n\r\n<h2 class=\"fz-xl\">1. \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u69cb\u6210\u30fb\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3\u306e\u57fa\u672c<\/h2>\r\n<p>Electron \u30a2\u30d7\u30ea\u306f <b class=\"bold\">\u30e1\u30a4\u30f3\u30d7\u30ed\u30bb\u30b9\uff08Node.js\uff09<\/b> \u3068 <b class=\"bold\">\u30ec\u30f3\u30c0\u30e9\u30fc\u30d7\u30ed\u30bb\u30b9\uff08Chromium\uff09<\/b> \u306e2\u5c64\u69cb\u9020\u306b\u306a\u3063\u3066\u3044\u308b\u3002\u3053\u306e\u5206\u96e2\u3092\u6700\u521d\u304b\u3089\u304d\u3061\u3093\u3068\u610f\u8b58\u3057\u3066\u8a2d\u8a08\u3057\u306a\u3044\u3068\u3001\u5f8c\u304b\u3089\u5927\u5e45\u306a\u30ea\u30d5\u30a1\u30af\u30bf\u304c\u5fc5\u8981\u306b\u306a\u308b\u3002<\/p>\r\n<pre><code class=\"language-\">src\/\r\n\u251c\u2500\u2500 main\/           # \u30e1\u30a4\u30f3\u30d7\u30ed\u30bb\u30b9\uff08Node.js\uff09\r\n\u2502   \u251c\u2500\u2500 main.js\r\n\u2502   \u251c\u2500\u2500 file-operations.js\r\n\u2502   \u251c\u2500\u2500 replacement-engine.js\r\n\u2502   \u2514\u2500\u2500 config-manager.js\r\n\u251c\u2500\u2500 renderer\/       # \u30ec\u30f3\u30c0\u30e9\u30fc\u30d7\u30ed\u30bb\u30b9\uff08Chromium\uff09\r\n\u2502   \u251c\u2500\u2500 index.html\r\n\u2502   \u251c\u2500\u2500 css\/\r\n\u2502   \u2514\u2500\u2500 js\/\r\n\u2514\u2500\u2500 preload\/\r\n    \u2514\u2500\u2500 preload.js  # \u30bb\u30ad\u30e5\u30a2\u306a\u6a4b\u6e21\u3057\u5f79\r\n<\/code><\/pre>\r\n<p><b class=\"bold\">\u539f\u5247\u3068\u3057\u3066\u4f55\u3092\u3069\u3061\u3089\u306b\u7f6e\u304f\u304b\uff1a<\/b><\/p>\r\n<ul style=\"list-style-type:bullet;\" class=\"my-0.5r\">\r\n<li>\u30d5\u30a1\u30a4\u30ebI\/O\u30fbNode.js API \u2192 \u30e1\u30a4\u30f3\u30d7\u30ed\u30bb\u30b9<\/li>\r\n<li>UI\u63cf\u753b\u30fb\u30e6\u30fc\u30b6\u30fc\u30a4\u30f3\u30bf\u30e9\u30af\u30b7\u30e7\u30f3 \u2192 \u30ec\u30f3\u30c0\u30e9\u30fc\u30d7\u30ed\u30bb\u30b9<\/li>\r\n<li>\u4e21\u8005\u306e\u901a\u4fe1 \u2192 preload.js \u7d4c\u7531\u306e IPC<\/li>\r\n<\/ul>\r\n<hr class=\"separator mt-3r\">\r\n<h2 class=\"fz-xl\">2. \u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u8a2d\u5b9a\u306f\u6700\u521d\u304b\u3089\u6b63\u3057\u304f<\/h2>\r\n<p>Electron \u306e\u65b0\u3057\u3044\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3067\u306f\u3001\u4ee5\u4e0b\u306e\u8a2d\u5b9a\u304c\u5fc5\u9808\u3002<b class=\"bold\">\u5f8c\u304b\u3089\u5909\u3048\u3088\u3046\u3068\u3059\u308b\u3068\u5168\u4f53\u306b\u5f71\u97ff\u3059\u308b\u306e\u3067\u3001\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u4f5c\u6210\u6642\u306e Task 1 \u3067\u5fc5\u305a\u8a2d\u5b9a\u3059\u308b\u3002<\/b><\/p>\r\n<pre><code class=\"language-javascript\">\/\/ main.js - BrowserWindow \u751f\u6210\u6642\r\nconst mainWindow = new BrowserWindow({\r\n  webPreferences: {\r\n    nodeIntegration: false,     \/\/ \u30ec\u30f3\u30c0\u30e9\u30fc\u304b\u3089 Node.js \u3092\u76f4\u63a5\u4f7f\u308f\u305b\u306a\u3044\r\n    contextIsolation: true,     \/\/ \u30ec\u30f3\u30c0\u30e9\u30fc\u3068 preload \u306e\u5b9f\u884c\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u3092\u5206\u96e2\r\n    preload: path.join(__dirname, &#39;..\/preload\/preload.js&#39;)\r\n  }\r\n});\r\n<\/code><\/pre>\r\n<p><code>contextIsolation: true<\/code> \u306b\u3059\u308b\u3068\u3001\u30ec\u30f3\u30c0\u30e9\u30fc\u30d7\u30ed\u30bb\u30b9\u304b\u3089 <code>process<\/code> \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306b\u76f4\u63a5\u30a2\u30af\u30bb\u30b9\u3067\u304d\u306a\u304f\u306a\u308b\u3002\u958b\u767a\u4e2d\u306b <code>ReferenceError: process is not defined<\/code> \u304c\u51fa\u305f\u3089\u3001\u30ec\u30f3\u30c0\u30e9\u30fc\u3067 <code>process<\/code> \u3092\u4f7f\u304a\u3046\u3068\u3057\u3066\u3044\u308b\u7b87\u6240\u3092\u63a2\u3059\u3002<\/p>\r\n<p><b class=\"bold\">\u5b89\u5168\u306a API \u516c\u958b\u306f contextBridge \u7d4c\u7531\u3067\uff1a<\/b><\/p>\r\n<pre><code class=\"language-javascript\">\/\/ preload.js\r\nconst { contextBridge, ipcRenderer } = require(&#39;electron&#39;);\r\n\r\ncontextBridge.exposeInMainWorld(&#39;electronAPI&#39;, {\r\n  selectFolder: () =&gt; ipcRenderer.invoke(&#39;select-folder&#39;),\r\n  searchFiles: (options) =&gt; ipcRenderer.invoke(&#39;search-files&#39;, options),\r\n  \/\/ ...\r\n});\r\n<\/code><\/pre>\r\n<hr class=\"separator mt-3r\">\r\n<h2 class=\"fz-xl\">3. IPC\u901a\u4fe1\u306e\u8a2d\u8a08<\/h2>\r\n<p>\u30e1\u30a4\u30f3\u3068\u30ec\u30f3\u30c0\u30e9\u30fc\u306e\u901a\u4fe1\u306f <code>ipcMain.handle<\/code> \/ <code>ipcRenderer.invoke<\/code> \u306e\u7d44\u307f\u5408\u308f\u305b\uff08Promise \u30d9\u30fc\u30b9\uff09\u3092\u4f7f\u3046\u3002\u53e4\u3044 <code>send<\/code> \/ <code>on<\/code> \u3088\u308a\u3053\u3061\u3089\u304c\u65ad\u7136\u6271\u3044\u3084\u3059\u3044\u3002<\/p>\r\n<p><b class=\"bold\">\u30e1\u30a4\u30f3\u30d7\u30ed\u30bb\u30b9\u5074\uff1a<\/b><\/p>\r\n<pre><code class=\"language-javascript\">ipcMain.handle(&#39;execute-replacement&#39;, async (event, config) =&gt; {\r\n  try {\r\n    const result = await replacementEngine.processFiles(\/* ... *\/);\r\n    return { success: true, ...result };\r\n  } catch (error) {\r\n    return { success: false, error: error.message };\r\n  }\r\n});\r\n<\/code><\/pre>\r\n<p><b class=\"bold\">\u30ec\u30f3\u30c0\u30e9\u30fc\u5074\uff1a<\/b><\/p>\r\n<pre><code class=\"language-javascript\">const result = await window.electronAPI.executeReplacement(config);\r\nif (result.success) { \/* \u6210\u529f\u51e6\u7406 *\/ }\r\n<\/code><\/pre>\r\n<p><b class=\"bold\">IPC \u3067\u6c17\u3092\u3064\u3051\u308b\u3053\u3068\uff1a<\/b><\/p>\r\n<ul style=\"list-style-type:bullet;\" class=\"my-0.5r\">\r\n<li>\u5165\u529b\u5024\u306f\u5fc5\u305a\u691c\u8a3c\u3059\u308b\uff08\u30d1\u30b9\u30c8\u30e9\u30d0\u30fc\u30b5\u30eb\u5bfe\u7b56\u306a\u3069\uff09<\/li>\r\n<li>\u30a8\u30e9\u30fc\u60c5\u5831\u306e\u9732\u51fa\u3092\u30b3\u30f3\u30c8\u30ed\u30fc\u30eb\u3059\u308b\uff08\u30b9\u30bf\u30c3\u30af\u30c8\u30ec\u30fc\u30b9\u3092\u305d\u306e\u307e\u307e\u8fd4\u3055\u306a\u3044\uff09<\/li>\r\n<li>\u623b\u308a\u5024\u306e\u69cb\u9020\u3092 <code>{ success: boolean, ... }<\/code> \u3067\u7d71\u4e00\u3057\u3066\u304a\u304f\u3068\u6271\u3044\u3084\u3059\u3044<\/li>\r\n<li>\u9032\u6357\u901a\u77e5\u306f <code>webContents.send<\/code> \u3067\u30ec\u30f3\u30c0\u30e9\u30fc\u306b\u30d7\u30c3\u30b7\u30e5\u3059\u308b<\/li>\r\n<\/ul>\r\n<hr class=\"separator mt-3r\">\r\n<h2 class=\"fz-xl\">4. \u30d1\u30c3\u30b1\u30fc\u30b8\u7248\uff08.app\uff09\u306a\u3089\u3067\u306f\u306e\u843d\u3068\u3057\u7a74<\/h2>\r\n<p><b class=\"bold\">\u3053\u3053\u304c\u6700\u5927\u306e\u30cf\u30de\u308a\u30dd\u30a4\u30f3\u30c8\u3060\u3063\u305f\u3002<\/b> \u958b\u767a\u7248\uff08<code>npm start<\/code>\uff09\u3067\u306f\u52d5\u304f\u306e\u306b <code>.app<\/code> \u306b\u3059\u308b\u3068\u52d5\u304b\u306a\u3044\u3001\u3068\u3044\u3046\u30d1\u30bf\u30fc\u30f3\u304c\u8907\u6570\u767a\u751f\u3057\u305f\u3002<\/p>\r\n<h3 class=\"fz-ml\">4-1. \u74b0\u5883\u5224\u5b9a\u306f <code>app.isPackaged<\/code> \u3092\u4f7f\u3046<\/h3>\r\n<pre><code class=\"language-javascript\">\/\/ \u274c NODE_ENV \u4f9d\u5b58\u306f .app \u3067\u306f\u3046\u307e\u304f\u52d5\u304b\u306a\u3044\u3053\u3068\u304c\u3042\u308b\r\nthis.isDevelopment = process.env.NODE_ENV === &#39;development&#39;;\r\n\r\n\/\/ \u2705 \u3053\u308c\u304c\u78ba\u5b9f\r\nthis.isDevelopment = !app.isPackaged;\r\n<\/code><\/pre>\r\n<h3 class=\"fz-ml\">4-2. \u30ea\u30bd\u30fc\u30b9\u30d5\u30a1\u30a4\u30eb\u306e\u30d1\u30b9\u89e3\u6c7a<\/h3>\r\n<p>\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb\u306a\u3069\u3092\u30a2\u30d7\u30ea\u306b\u540c\u68b1\u3059\u308b\u5834\u5408\u3001\u30d1\u30c3\u30b1\u30fc\u30b8\u7248\u3067\u306f <code>__dirname<\/code> \u304c\u5909\u308f\u308b\u305f\u3081\u56fa\u5b9a\u30d1\u30b9\u304c\u901a\u3089\u306a\u304f\u306a\u308b\u3002<\/p>\r\n<pre><code class=\"language-javascript\">\/\/ \u274c \u56fa\u5b9a\u30d1\u30b9\uff08\u30d1\u30c3\u30b1\u30fc\u30b8\u7248\u3067\u5931\u6557\uff09\r\nstatic DEFAULT_CONFIG_PATH = path.join(__dirname, &#39;..\/..\/config\/default.json&#39;);\r\n\r\n\/\/ \u2705 \u52d5\u7684\u30d1\u30b9\u89e3\u6c7a\r\nstatic get DEFAULT_CONFIG_PATH() {\r\n  if (app.isPackaged) {\r\n    return path.join(process.resourcesPath, &#39;config\/default.json&#39;);\r\n  }\r\n  return path.join(__dirname, &#39;..\/..\/config\/default.json&#39;);\r\n}\r\n<\/code><\/pre>\r\n<p><code>package.json<\/code> \u306e <code>build.extraResources<\/code> \u306b\u540c\u68b1\u3057\u305f\u3044\u30d5\u30a1\u30a4\u30eb\u3092\u6307\u5b9a\u3059\u308b\u3053\u3068\u3082\u5fd8\u308c\u305a\u306b\uff1a<\/p>\r\n<pre><code class=\"language-json\">{\r\n  &quot;build&quot;: {\r\n    &quot;extraResources&quot;: &lsqb;&quot;config\/**\/*&quot;&rsqb;\r\n  }\r\n}\r\n<\/code><\/pre>\r\n<h3 class=\"fz-ml\">4-3. HTML \u306e\u8aad\u307f\u8fbc\u307f\u306f <code>loadFile<\/code> \u3067\u7d71\u4e00<\/h3>\r\n<pre><code class=\"language-javascript\">\/\/ \u274c \u30d1\u30c3\u30b1\u30fc\u30b8\u7248\u3067\u30cf\u30de\u308b\u8907\u96d1\u306a\u6761\u4ef6\u5206\u5c90\r\nif (app.isPackaged) {\r\n  await mainWindow.loadURL(`file:\/\/${absolutePath}`);\r\n} else {\r\n  await mainWindow.loadFile(absolutePath);\r\n}\r\n\r\n\/\/ \u2705 loadFile \u3067\u7d71\u4e00\uff08Electron \u304c\u81ea\u52d5\u7684\u306b\u30d1\u30b9\u89e3\u6c7a\uff09\r\nawait mainWindow.loadFile(path.join(__dirname, &#39;..\/renderer\/index.html&#39;));\r\n<\/code><\/pre>\r\n<h3 class=\"fz-ml\">4-4. DevTools \u306f\u30d1\u30c3\u30b1\u30fc\u30b8\u7248\u3067\u306f\u958b\u304b\u306a\u3044<\/h3>\r\n<pre><code class=\"language-javascript\">mainWindow.once(&#39;ready-to-show&#39;, () =&gt; {\r\n  mainWindow.show();\r\n  if (!app.isPackaged) {\r\n    mainWindow.webContents.openDevTools();\r\n  }\r\n});\r\n<\/code><\/pre>\r\n<hr class=\"separator mt-3r\">\r\n<h2 class=\"fz-xl\">5. \u30a6\u30a3\u30f3\u30c9\u30a6\u7ba1\u7406\u30fb\u30e9\u30a4\u30d5\u30b5\u30a4\u30af\u30eb\u306e\u6ce8\u610f\u70b9<\/h2>\r\n<h3 class=\"fz-ml\">5-1. \u30b7\u30f3\u30b0\u30eb\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u5236\u5fa1<\/h3>\r\n<p>\u3053\u308c\u3092\u5b9f\u88c5\u3057\u3066\u3044\u306a\u3044\u3068\u30012\u56de\u76ee\u306e\u8d77\u52d5\u3067\u30a6\u30a3\u30f3\u30c9\u30a6\u304c\u51fa\u306a\u3044 or 2\u3064\u8d77\u52d5\u3057\u3066\u7af6\u5408\u3059\u308b\u3002<\/p>\r\n<pre><code class=\"language-javascript\">const gotTheLock = app.requestSingleInstanceLock();\r\n\r\nif (!gotTheLock) {\r\n  app.quit();\r\n  return;\r\n}\r\n\r\napp.on(&#39;second-instance&#39;, () =&gt; {\r\n  if (mainWindow) {\r\n    if (mainWindow.isMinimized()) mainWindow.restore();\r\n    mainWindow.focus();\r\n    mainWindow.show();\r\n  }\r\n});\r\n<\/code><\/pre>\r\n<h3 class=\"fz-ml\">5-2. \u30a4\u30d9\u30f3\u30c8\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u91cd\u8907\u767b\u9332\u3092\u907f\u3051\u308b<\/h3>\r\n<p><code>closed<\/code> \u30a4\u30d9\u30f3\u30c8\u306a\u3069\u3092\u8907\u6570\u7b87\u6240\u3067\u767b\u9332\u3059\u308b\u3068\u30e1\u30e2\u30ea\u30ea\u30fc\u30af\u30fb\u52d5\u4f5c\u4e0d\u5b89\u5b9a\u306e\u539f\u56e0\u306b\u306a\u308b\u30021\u304b\u6240\u306e\u307f\u306b\u96c6\u7d04\u3059\u308b\u3002<\/p>\r\n<pre><code class=\"language-javascript\">\/\/ \u2705 1\u304b\u6240\u306e\u307f\u767b\u9332\r\nmainWindow.on(&#39;closed&#39;, () =&gt; {\r\n  mainWindow = null;\r\n});\r\n<\/code><\/pre>\r\n<h3 class=\"fz-ml\">5-3. macOS \u306e <code>activate<\/code> \u30a4\u30d9\u30f3\u30c8\u5bfe\u5fdc<\/h3>\r\n<p>Dock \u30af\u30ea\u30c3\u30af\u6642\u306b\u30a6\u30a3\u30f3\u30c9\u30a6\u3092\u518d\u8868\u793a\u3059\u308b\u51e6\u7406\u3092\u5fd8\u308c\u304c\u3061\uff1a<\/p>\r\n<pre><code class=\"language-javascript\">app.on(&#39;activate&#39;, () =&gt; {\r\n  if (BrowserWindow.getAllWindows().length === 0) {\r\n    createMainWindow();\r\n  } else if (mainWindow) {\r\n    mainWindow.show();\r\n    mainWindow.focus();\r\n  }\r\n});\r\n<\/code><\/pre>\r\n<h3 class=\"fz-ml\">5-4. <code>ready-to-show<\/code> \u304c\u767a\u706b\u3057\u306a\u3044\u5834\u5408\u306e\u30d5\u30a9\u30fc\u30eb\u30d0\u30c3\u30af<\/h3>\r\n<p>\u307e\u308c\u306b\u30a4\u30d9\u30f3\u30c8\u304c\u767a\u706b\u3057\u306a\u3044\u30b1\u30fc\u30b9\u306b\u5099\u3048\u3066\u4fdd\u967a\u3092\u304b\u3051\u3066\u304a\u304f\uff1a<\/p>\r\n<pre><code class=\"language-javascript\">mainWindow.once(&#39;ready-to-show&#39;, () =&gt; {\r\n  mainWindow.show();\r\n});\r\n\r\n\/\/ \u30d5\u30a9\u30fc\u30eb\u30d0\u30c3\u30af\r\nsetTimeout(() =&gt; {\r\n  if (mainWindow &amp;&amp; !mainWindow.isVisible()) {\r\n    mainWindow.show();\r\n  }\r\n}, 1000);\r\n<\/code><\/pre>\r\n<hr class=\"separator mt-3r\">\r\n<h2 class=\"fz-xl\">6. \u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u6700\u9069\u5316\u306e\u8003\u3048\u65b9<\/h2>\r\n<p>\u30d5\u30a1\u30a4\u30eb\u6570\u30fb\u30b5\u30a4\u30ba\u306b\u5fdc\u3058\u3066\u51e6\u7406\u6226\u7565\u3092\u52d5\u7684\u306b\u5207\u308a\u66ff\u3048\u308b\u3068\u3001\u5927\u91cf\u30d5\u30a1\u30a4\u30eb\u51e6\u7406\u3067\u3082\u5b89\u5b9a\u3057\u305f\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u7dad\u6301\u3067\u304d\u308b\u3002<\/p>\r\n<pre><code class=\"language-javascript\">function determineStrategy(files) {\r\n  const avgSize = totalSize \/ files.length;\r\n\r\n  if (avgSize &gt; 50 * 1024 * 1024) return &#39;stream&#39;;   \/\/ \u5927\u5bb9\u91cf\u30d5\u30a1\u30a4\u30eb\r\n  if (files.length &gt; 100)         return &#39;batch&#39;;    \/\/ \u591a\u6570\u30d5\u30a1\u30a4\u30eb\r\n  return &#39;standard&#39;;                                  \/\/ \u901a\u5e38\r\n}\r\n<\/code><\/pre>\r\n<p><b class=\"bold\">\u305d\u308c\u305e\u308c\u306e\u4f7f\u3044\u6240\uff1a<\/b><\/p>\r\n<ul style=\"list-style-type:bullet;\" class=\"my-0.5r\">\r\n<li>stream \u51e6\u7406\u306a50MB \u8d85\u306e\u30d5\u30a1\u30a4\u30eb\u30021MB \u30c1\u30e3\u30f3\u30af\u5358\u4f4d\u3067\u51e6\u7406\u3057\u3066\u30e1\u30e2\u30ea\u3092\u6291\u3048\u308b<\/li>\r\n<li>batch \u51e6\u7406\u306a100 \u30d5\u30a1\u30a4\u30eb\u4ee5\u4e0a\u3002\u6700\u5927\u540c\u6642\u51e6\u7406\u6570\uff08\u4f8b\uff1a10 \u30d5\u30a1\u30a4\u30eb\u4e26\u5217\uff09\u3092\u5236\u5fa1<\/li>\r\n<li>standard \u51e6\u7406\u306a\u305d\u308c\u4ee5\u5916\u306e\u30c7\u30d5\u30a9\u30eb\u30c8<\/li>\r\n<\/ul>\r\n<p>\u5b9f\u6e2c\u3067\u306f 1,000 \u30d5\u30a1\u30a4\u30eb\u3092 1 \u79d2\u4ee5\u4e0b\u3067\u51e6\u7406\u3067\u304d\u305f\u3002\u4e26\u884c\u6570\u306e\u8abf\u6574\uff08<code>maxConcurrentFiles<\/code>\uff09\u304c\u52b9\u3044\u3066\u3044\u308b\u3002<\/p>\r\n<hr class=\"separator mt-3r\">\r\n<h2 class=\"fz-xl\">7. \u30e1\u30e2\u30ea\u7ba1\u7406<\/h2>\r\n<p>Electron \u30a2\u30d7\u30ea\u306f\u30e1\u30e2\u30ea\u30ea\u30fc\u30af\u3092\u8d77\u3053\u3057\u3084\u3059\u3044\u3002\u7279\u306b\u9577\u6642\u9593\u8d77\u52d5\u3059\u308b\u30c4\u30fc\u30eb\u3067\u306f\u6bb5\u968e\u7684\u306a\u30e1\u30e2\u30ea\u76e3\u8996\u304c\u91cd\u8981\u3002<\/p>\r\n<pre><code class=\"language-javascript\">const THRESHOLDS = {\r\n  warning:   150 * 1024 * 1024,  \/\/ 150MB - \u8efd\u5ea6\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\r\n  critical:  200 * 1024 * 1024,  \/\/ 200MB - \u7a4d\u6975\u7684\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\r\n  emergency: 250 * 1024 * 1024,  \/\/ 250MB - \u5168\u9762\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7\r\n};\r\n\r\n\/\/ 10\u79d2\u3054\u3068\u306b\u30c1\u30a7\u30c3\u30af\r\nsetInterval(() =&gt; checkMemory(), 10000);\r\n<\/code><\/pre>\r\n<p><b class=\"bold\">\u30e1\u30e2\u30ea\u30ea\u30fc\u30af\u306e\u4e3b\u306a\u539f\u56e0\u3068\u5bfe\u7b56\uff1a<\/b><\/p>\r\n<ul style=\"list-style-type:bullet;\" class=\"my-0.5r\">\r\n<li><b class=\"bold\">EventListener \u306e\u4ed8\u3051\u5916\u3057\u5fd8\u308c<\/b> \u2192 \u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u7834\u68c4\u6642\u306b\u5fc5\u305a <code>removeEventListener<\/code><\/li>\r\n<li><b class=\"bold\">Timer \u306e\u6b8b\u7559<\/b> \u2192 <code>clearTimeout<\/code> \/ <code>clearInterval<\/code> \u3092\u78ba\u5b9f\u306b<\/li>\r\n<li><b class=\"bold\">\u5faa\u74b0\u53c2\u7167<\/b> \u2192 WeakMap \/ WeakRef \u306e\u6d3b\u7528<\/li>\r\n<li><b class=\"bold\">\u5c65\u6b74\u30c7\u30fc\u30bf\u306e\u7121\u5236\u9650\u84c4\u7a4d<\/b> \u2192 \u4e00\u5b9a\u4ef6\u6570\u3092\u8d85\u3048\u305f\u3089\u53e4\u3044\u3082\u306e\u3092\u524a\u9664<\/li>\r\n<\/ul>\r\n<hr class=\"separator mt-3r\">\r\n<h2 class=\"fz-xl\">8. \u975e\u540c\u671f\u51e6\u7406\u306e\u5fb9\u5e95<\/h2>\r\n<p><b class=\"bold\">\u6700\u521d\u671f\u306e\u30cf\u30de\u308a\u3069\u3053\u308d\u305d\u306e1\u3002<\/b> <code>async\/await<\/code> \u306e\u4f7f\u3044\u65b9\u304c\u4e2d\u9014\u534a\u7aef\u3060\u3068 <code>SyntaxError: await is only valid in async functions<\/code> \u304c\u51fa\u308b\u3002<\/p>\r\n<pre><code class=\"language-javascript\">\/\/ \u274c \u95a2\u6570\u304c async \u3067\u306a\u3044\u306e\u306b await\r\ncreateMainWindow() {\r\n  await logger.error(&#39;failed&#39;);  \/\/ SyntaxError!\r\n}\r\n\r\n\/\/ \u2705 \u95a2\u6570\u5168\u4f53\u3092 async \u306b\r\nasync createMainWindow() {\r\n  await logger.error(&#39;failed&#39;);\r\n}\r\n<\/code><\/pre>\r\n<p>IPC \u30cf\u30f3\u30c9\u30e9\u30fc\u306f\u307b\u307c\u5168\u3066 <code>async<\/code> \u306b\u3059\u308b\u3002UI \u3092\u30d6\u30ed\u30c3\u30af\u3057\u306a\u3044\u3088\u3046\u3001\u91cd\u3044\u51e6\u7406\u306f\u5168\u3066\u975e\u540c\u671f\u3067\u5b9f\u884c\u3059\u308b\u3002<\/p>\r\n<hr class=\"separator mt-3r\">\r\n<h2 class=\"fz-xl\">9. \u958b\u767a\u74b0\u5883\u30fb\u30c4\u30fc\u30eb\u8a2d\u5b9a\u306e\u306f\u307e\u308a\u3069\u3053\u308d<\/h2>\r\n<h3 class=\"fz-ml\">ESLint \u306e\u8a2d\u5b9a\u5024\u306f\u5927\u6587\u5b57\u5c0f\u6587\u5b57\u3092\u53b3\u5bc6\u306b<\/h3>\r\n<pre><code class=\"language-javascript\">\/\/ \u274c \u30bf\u30a4\u30dd\uff08\u5927\u6587\u5b57\u6df7\u5165\uff09\r\necmaVersion: &#39;laTEST&#39;\r\n\r\n\/\/ \u2705\r\necmaVersion: &#39;latest&#39;\r\n<\/code><\/pre>\r\n<h3 class=\"fz-ml\">Jest \u306e\u8a2d\u5b9a\u30d7\u30ed\u30d1\u30c6\u30a3\u306f camelCase<\/h3>\r\n<pre><code class=\"language-javascript\">\/\/ \u274c\r\nmodule.exports = {\r\n  TESTEnvironment: &#39;node&#39;,  \/\/ Unknown option \u30a8\u30e9\u30fc\r\n  TESTMatch: &lsqb;&#39;...&#39;&rsqb;\r\n}\r\n\r\n\/\/ \u2705\r\nmodule.exports = {\r\n  testEnvironment: &#39;node&#39;,\r\n  testMatch: &lsqb;&#39;&lt;rootDir&gt;\/tests\/**\/*.test.js&#39;&rsqb;\r\n}\r\n<\/code><\/pre>\r\n<h3 class=\"fz-ml\"><code>electron-builder<\/code> \u306f <code>devDependencies<\/code> \u306b<\/h3>\r\n<p><code>dependencies<\/code> \u306b\u5165\u308c\u308b\u3068\u672c\u756a\u30d3\u30eb\u30c9\u306b\u542b\u307e\u308c\u3066\u30b5\u30a4\u30ba\u304c\u81a8\u308c\u308b\u3002<\/p>\r\n<pre><code class=\"language-json\">{\r\n  &quot;devDependencies&quot;: {\r\n    &quot;electron-builder&quot;: &quot;^24.0.0&quot;\r\n  }\r\n}\r\n<\/code><\/pre>\r\n<hr class=\"separator mt-3r\">\r\n<h2 class=\"fz-xl\">10. \u30c6\u30b9\u30c8\u6226\u7565<\/h2>\r\n<h3 class=\"fz-ml\">\u958b\u767a\u7248\u3068\u30d1\u30c3\u30b1\u30fc\u30b8\u7248\u306e\u4e21\u65b9\u3067\u30c6\u30b9\u30c8\u3059\u308b<\/h3>\r\n<p><code>npm start<\/code> \u3067\u52d5\u3044\u3066\u3082 <code>.app<\/code> \u3067\u52d5\u304b\u306a\u3044\u3053\u3068\u304c\u3042\u308b\uff08\u524d\u8ff0\u306e\u901a\u308a\uff09\u3002\u5404 Task \u5b8c\u4e86\u6642\u306b\u5fc5\u305a\u4e21\u65b9\u78ba\u8a8d\u3059\u308b\u7fd2\u6163\u3092\u3064\u3051\u308b\uff1a<\/p>\r\n<pre><code class=\"language-bash\">npm start              # \u958b\u767a\u7248\r\nnpm run build:dev      # \u30d1\u30c3\u30b1\u30fc\u30b8\u7248\u30d3\u30eb\u30c9\r\nopen dist\/mac-arm64\/App.app  # \u30d1\u30c3\u30b1\u30fc\u30b8\u7248\u78ba\u8a8d\r\n<\/code><\/pre>\r\n<h3 class=\"fz-ml\">Jest \u306e\u30c6\u30b9\u30c8\u30d5\u30a1\u30a4\u30eb\u547d\u540d<\/h3>\r\n<p><code>*.test.js<\/code> \u306e\u5f62\u5f0f\u3067\u306a\u3044\u3068 Jest \u304c\u8a8d\u8b58\u3057\u306a\u3044\u3002<\/p>\r\n<h3 class=\"fz-ml\">\u30c6\u30b9\u30c8\u30b3\u30fc\u30c9\u3068\u5b9f\u88c5\u306e\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\u306f\u5b8c\u5168\u4e00\u81f4\u304c\u5fc5\u8981<\/h3>\r\n<pre><code class=\"language-javascript\">\/\/ \u274c \u5b9f\u88c5\u304c &#39;Invalid path&#39; \u3092\u8fd4\u3059\u306e\u306b\r\nexpect(error).rejects.toThrow(&#39;Invalid input&#39;);\r\n\r\n\/\/ \u2705\r\nexpect(error).rejects.toThrow(&#39;Invalid path&#39;);\r\n<\/code><\/pre>\r\n<h3 class=\"fz-ml\">\u975e\u540c\u671f\u30c6\u30b9\u30c8\u306e\u30af\u30ea\u30fc\u30f3\u30a2\u30c3\u30d7<\/h3>\r\n<pre><code class=\"language-javascript\">afterEach(async () =&gt; {\r\n  \/\/ \u30bf\u30a4\u30de\u30fc\u30fb\u30ea\u30b9\u30ca\u30fc\u30fbDB\u63a5\u7d9a\u306a\u3069\u78ba\u5b9f\u306b\u30af\u30ea\u30a2\r\n  await cleanup();\r\n});\r\n<\/code><\/pre>\r\n<hr class=\"separator mt-3r\">\r\n<h2 class=\"fz-xl\">11. \u30d3\u30eb\u30c9\u30fb\u914d\u5e03\u306e\u8a2d\u5b9a<\/h2>\r\n<p><code>package.json<\/code> \u306e <code>build<\/code> \u30bb\u30af\u30b7\u30e7\u30f3\u3067\u4e3b\u8981\u306a\u8a2d\u5b9a\u3092\u307e\u3068\u3081\u308b\uff1a<\/p>\r\n<pre><code class=\"language-json\">{\r\n  &quot;build&quot;: {\r\n    &quot;appId&quot;: &quot;com.yourapp.name&quot;,\r\n    &quot;productName&quot;: &quot;Your App Name&quot;,\r\n    &quot;copyright&quot;: &quot;Copyright \u00a9 2025 Your Name&quot;,\r\n    &quot;compression&quot;: &quot;maximum&quot;,\r\n    &quot;files&quot;: &lsqb;&quot;src\/&lt;strong&gt;\/*&quot;, &quot;config\/&lt;\/strong&gt;\/*&quot;, &quot;package.json&quot;&rsqb;,\r\n    &quot;extraResources&quot;: &lsqb;&quot;config\/**\/*&quot;&rsqb;,\r\n    &quot;mac&quot;: {\r\n      &quot;hardenedRuntime&quot;: true,\r\n      &quot;category&quot;: &quot;public.app-category.developer-tools&quot;,\r\n      &quot;target&quot;: &lsqb;\r\n        { &quot;target&quot;: &quot;dmg&quot;, &quot;arch&quot;: &lsqb;&quot;x64&quot;, &quot;arm64&quot;&rsqb; },\r\n        { &quot;target&quot;: &quot;zip&quot;, &quot;arch&quot;: &lsqb;&quot;x64&quot;, &quot;arm64&quot;&rsqb; }\r\n      &rsqb;\r\n    },\r\n    &quot;win&quot;: {\r\n      &quot;target&quot;: &lsqb;{ &quot;target&quot;: &quot;nsis&quot;, &quot;arch&quot;: &lsqb;&quot;x64&quot;&rsqb; }&rsqb;\r\n    }\r\n  }\r\n}\r\n<\/code><\/pre>\r\n<p><b class=\"bold\">macOS \u306e\u6ce8\u610f\u70b9\uff1a<\/b><\/p>\r\n<ul style=\"list-style-type:bullet;\" class=\"my-0.5r\">\r\n<li><code>hardenedRuntime: true<\/code> \u3092\u8a2d\u5b9a\u3057\u3066\u304a\u304b\u306a\u3044\u3068 Gatekeeper \u306b\u5f15\u3063\u304b\u304b\u308b<\/li>\r\n<li>\u521d\u56de\u8d77\u52d5\u6642\u306f\u53f3\u30af\u30ea\u30c3\u30af\u2192\u300c\u958b\u304f\u300d\u304c\u5fc5\u8981\uff08codesign \u306a\u3057\u306e\u5834\u5408\uff09<\/li>\r\n<\/ul>\r\n<p><b class=\"bold\">\u30d3\u30eb\u30c9\u30b9\u30af\u30ea\u30d7\u30c8\uff1a<\/b><\/p>\r\n<pre><code class=\"language-json\">{\r\n  &quot;scripts&quot;: {\r\n    &quot;start&quot;: &quot;electron .&quot;,\r\n    &quot;build&quot;: &quot;electron-builder&quot;,\r\n    &quot;build:production&quot;: &quot;NODE_ENV=production electron-builder&quot;\r\n  }\r\n}\r\n<\/code><\/pre>\r\n<hr class=\"separator mt-3r\">\r\n<h2 class=\"fz-xl\">12. \u30ed\u30ae\u30f3\u30b0\u6226\u7565<\/h2>\r\n<p>\u30c7\u30d0\u30c3\u30b0\u3057\u3084\u3059\u3044\u30a2\u30d7\u30ea\u306b\u3059\u308b\u306b\u306f\u3001\u6700\u521d\u304b\u3089\u30ed\u30ae\u30f3\u30b0\u6226\u7565\u3092\u6301\u3064\u3053\u3068\u304c\u91cd\u8981\u3002\u7279\u306b\u30d1\u30c3\u30b1\u30fc\u30b8\u30f3\u30b0\u5f8c\u306e\u554f\u984c\u8abf\u67fb\u306b\u30ed\u30b0\u304c\u52b9\u304f\u3002<\/p>\r\n<p><b class=\"bold\">\u30d1\u30c3\u30b1\u30fc\u30b8\u30f3\u30b0\u72b6\u614b\u3092\u30ed\u30b0\u306b\u51fa\u3059\uff1a<\/b><\/p>\r\n<pre><code class=\"language-javascript\">console.log(`\ud83d\udce6 Is packaged: ${app.isPackaged}`);\r\nconsole.log(`\ud83d\uddc2\ufe0f Resources: ${process.resourcesPath || &#39;N\/A&#39;}`);\r\nconsole.log(`\ud83d\udcc1 Config path: ${resolvedPath}`);\r\n<\/code><\/pre>\r\n<p><b class=\"bold\">\u69cb\u9020\u5316\u30ed\u30b0\u3092\u4f7f\u3046\uff1a<\/b><\/p>\r\n<p>\u5358\u306a\u308b <code>console.log<\/code> \u3067\u306f\u306a\u304f\u3001<code>{ context: { ... }, level: &#39;info&#39; }<\/code> \u306e\u3088\u3046\u306a\u69cb\u9020\u5316\u30c7\u30fc\u30bf\u3067\u51fa\u529b\u3057\u3066\u304a\u304f\u3068\u3001AI \u306b\u3088\u308b\u5206\u6790\u3084\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u7d71\u8a08\u306e\u96c6\u8a08\u304c\u5bb9\u6613\u306b\u306a\u308b\u3002<\/p>\r\n<p><b class=\"bold\">\u30ed\u30b0\u30ec\u30d9\u30eb\u3092\u4f7f\u3044\u5206\u3051\u308b\uff1a<\/b><\/p>\r\n<ul style=\"list-style-type:bullet;\" class=\"my-0.5r\">\r\n<li><code>debug<\/code> \u2192 \u8a73\u7d30\u306a\u5185\u90e8\u72b6\u614b<\/li>\r\n<li><code>info<\/code> \u2192 \u4e3b\u8981\u306a\u51e6\u7406\u306e\u958b\u59cb\u30fb\u5b8c\u4e86<\/li>\r\n<li><code>warn<\/code> \u2192 \u60f3\u5b9a\u5185\u306e\u554f\u984c\uff08\u30e1\u30e2\u30ea\u8b66\u544a\u306a\u3069\uff09<\/li>\r\n<li><code>error<\/code> \u2192 \u60f3\u5b9a\u5916\u306e\u554f\u984c\uff08\u30d5\u30a1\u30a4\u30eb\u8aad\u307f\u8fbc\u307f\u5931\u6557\u306a\u3069\uff09<\/li>\r\n<\/ul>\r\n<hr class=\"separator mt-3r\">\r\n<h2 class=\"fz-xl\">13. \u307e\u3068\u3081\uff1a\u6b21\u56de\u3078\u306e7\u3064\u306e\u30c1\u30a7\u30c3\u30af\u30ea\u30b9\u30c8<\/h2>\r\n<p>Electron \u30a2\u30d7\u30ea\u3092\u4f5c\u308b\u3068\u304d\u3001\u6700\u521d\u304b\u3089\u4ee5\u4e0b\u3092\u610f\u8b58\u3057\u3066\u304a\u3051\u3070\u307b\u3068\u3093\u3069\u306e\u30cf\u30de\u308a\u30dd\u30a4\u30f3\u30c8\u306f\u56de\u907f\u3067\u304d\u308b\u3002<\/p>\r\n<ol style=\"list-style-type:decimal;\" class=\"my-0.5r\">\r\n<li><p><b class=\"bold\">\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u8a2d\u5b9a\u306f Task 1 \u3067\u5b8c\u4e86\u3055\u305b\u308b<\/b><br><code>nodeIntegration: false<\/code> + <code>contextIsolation: true<\/code> + <code>preload.js<\/code> \u7d4c\u7531\u306e API \u516c\u958b<\/p>\r\n<\/li>\r\n<li><p><b class=\"bold\">\u74b0\u5883\u5224\u5b9a\u306f <code>app.isPackaged<\/code> \u3067\u7d71\u4e00\u3059\u308b<\/b><br><code>NODE_ENV<\/code> \u3084 <code>__dirname<\/code> \u3078\u306e\u4f9d\u5b58\u306f\u5371\u967a\u3002\u52d5\u7684\u306a\u30d1\u30b9\u89e3\u6c7a\u3092\u6a19\u6e96\u5316\u3059\u308b<\/p>\r\n<\/li>\r\n<li><p><b class=\"bold\">HTML \u8aad\u307f\u8fbc\u307f\u306f <code>loadFile<\/code> \u306b\u7d71\u4e00\u3059\u308b<\/b><br><code>loadURL(&#39;file:\/\/...&#39;)<\/code> \u3068\u306e\u6761\u4ef6\u5206\u5c90\u306f\u4e0d\u8981<\/p>\r\n<\/li>\r\n<li><p><b class=\"bold\">\u30b7\u30f3\u30b0\u30eb\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u5236\u5fa1\u3092\u6700\u521d\u304b\u3089\u5165\u308c\u308b<\/b><br><code>app.requestSingleInstanceLock()<\/code> \u3092\u5fd8\u308c\u308b\u30682\u56de\u76ee\u8d77\u52d5\u3067\u8a70\u307e\u308b<\/p>\r\n<\/li>\r\n<li><p><b class=\"bold\">\u30a4\u30d9\u30f3\u30c8\u30cf\u30f3\u30c9\u30e9\u30fc\u306e\u91cd\u8907\u767b\u9332\u3092\u9632\u3050<\/b><br><code>closed<\/code> \u306a\u3069\u306e\u30a6\u30a3\u30f3\u30c9\u30a6\u30a4\u30d9\u30f3\u30c8\u306f1\u304b\u6240\u306e\u307f\u767b\u9332\u3059\u308b<\/p>\r\n<\/li>\r\n<li><p><b class=\"bold\">\u958b\u767a\u7248\u30fb\u30d1\u30c3\u30b1\u30fc\u30b8\u7248\u306e\u4e21\u65b9\u3067\u30c6\u30b9\u30c8\u3059\u308b<\/b><br>\u5404 Task \u5b8c\u4e86\u306e\u305f\u3073\u306b <code>.app<\/code> \u52d5\u4f5c\u78ba\u8a8d\u3092\u5fc5\u9808\u306b\u3059\u308b<\/p>\r\n<\/li>\r\n<li><p><b class=\"bold\">\u975e\u540c\u671f\u51e6\u7406\u3092\u5fb9\u5e95\u3059\u308b<\/b><br>\u30d5\u30a1\u30a4\u30ebI\/O\u30fbIPC \u30cf\u30f3\u30c9\u30e9\u30fc\u30fb\u30ed\u30ac\u30fc\u547c\u3073\u51fa\u3057\u306f\u5168\u3066 <code>async\/await<\/code> \u3067\u7d71\u4e00\u3059\u308b<\/p>\r\n<\/li>\r\n<\/ol>\r\n<hr class=\"separator mt-3r\">\r\n<p>\u4ee5\u4e0a\u3001\u5b9f\u969b\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u767a\u751f\u3057\u305f\u30a8\u30e9\u30fc\u3068\u89e3\u6c7a\u7b56\u3092\u30d9\u30fc\u30b9\u306b\u307e\u3068\u3081\u307e\u3057\u305f\u3002<br>Electron \u306f\u5b66\u7fd2\u30b3\u30b9\u30c8\u306f\u3042\u308b\u304c\u3001Web \u6280\u8853\u3067\u30cd\u30a4\u30c6\u30a3\u30d6\u30a2\u30d7\u30ea\u304c\u4f5c\u308c\u3066\u826f\u3044\u3067\u3059\u3002<\/p>\r\n\r\n<hr class=\"separator mt-3r\">\r\n\r\n<h2 class=\"fz-xl\">\u95a2\u9023\u8a18\u4e8b<\/h2>\r\n\r\n<a href=\"https:\/\/code-plus.jp\/gp\/multi-grep-replacer-8480\/\" class=\"linkbox my-1.5r\">\r\n<h4 class=\"linkbox-title fz-md\">\u8907\u6570\u30eb\u30fc\u30eb\u3067\u4e00\u62ecgrep\u7f6e\u63db\u30c4\u30fc\u30eb\u300cMulti Grep Replacer\u300d<\/h4>\r\n<picture class=\"linkbox-thumbnail\">\r\n<img decoding=\"async\" width=\"300\" height=\"200\" src=\"https:\/\/code-plus.jp\/gp\/wp-content\/uploads\/e4700776b3f5c511edac5bbe594e4107.png?ver=20260528154158\" alt=\"\u8907\u6570\u30eb\u30fc\u30eb\u3067\u4e00\u62ecgrep\u7f6e\u63db\u30c4\u30fc\u30eb\u300cMulti Grep Replacer\u300d\" loading=\"lazy\" \/>\r\n<\/picture>\r\n<span class=\"linkbox-excerpt\">Web\u958b\u767a\u3084\u30d7\u30ed\u30b0\u30e9\u30df\u30f3\u30b0\u3067\u3001\u3053\u3093\u306a\u7d4c\u9a13\u306f\u3042\u308a\u307e\u305b\u3093\u304b\uff1f\ud83d\udd04 \u540c\u3058\u7f6e\u63db\u4f5c\u696d\u3092\u4f55\u5ea6\u3082\u7e70\u308a\u8fd4\u3057\u3066\u3044\u308b\ud83d\ude13 \u30b5\u30af\u30e9\u30a8\u30c7\u30a3\u30bf\u30675\u3064\u306e\u7f6e\u63db\u30d1\u30bf\u30fc\u30f3\u30921\u3064\u305a\u3064\u5b9f\u884c\u3059\u308b\u306e\u304c\u9762\u5012\u3081\u3093\u3069\u304f\u3055\u304b\u3063\u305f\u306e\u3067\u3001\u8907\u6570\u30eb\u30fc\u30eb\u3067\u4e00\u62ec\u7f6e\u63db\u3067\u304d\u308b\u300cMulti Grep Replacer\u300d \u3092\u4f5c\u3063\u3066\u307f...\r\n&emsp;<u class=\"linkbox-more\">\u7d9a\u304d\u3092\u8aad\u3080<\/u>\r\n<\/span>\r\n<\/a>","protected":false},"excerpt":{"rendered":"Electron \u3067\u30c7\u30b9\u30af\u30c8\u30c3\u30d7\u30a2\u30d7\u30ea\u30920\u304b\u3089\u4f5c\u3063\u305f\u7d4c\u9a13\u3092\u3082\u3068\u306b\u3001\u30bb\u30ad\u30e5\u30ea\u30c6\u30a3\u8a2d\u5b9a\u30fb\u30d1\u30c3\u30b1\u30fc\u30b8\u30f3\u30b0\u6642\u306e\u30d1\u30b9\u554f\u984c\u30fb\u30b7\u30f3\u30b0\u30eb\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u5236\u5fa1\u30fb\u975e\u540c\u671f\u51e6\u7406\u30fb\u30e1\u30e2\u30ea\u7ba1\u7406\u306a\u3069\u5b9f\u969b\u306b\u30cf\u30de\u3063\u305f\u30dd\u30a4\u30f3\u30c8\u3068\u89e3\u6c7a\u7b56\u309213\u9805\u76ee\u306b\u307e\u3068\u3081\u305f\u958b\u767a\u8005\u5411\u3051\u5099\u5fd8\u9332\u3067\u3059\u3002","protected":false},"author":1,"featured_media":11057,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"sns_share_botton_hide":"","vkExUnit_sns_title":"","_vk_print_noindex":"","footnotes":"","vk-ltc-link":"","vk-ltc-target":"0"},"categories":[29],"tags":[677,674,679,678,680,675,676,343,315,141,124,113,95,96],"class_list":["post-11048","post","type-post","status-publish","format-standard","has-post-thumbnail","category-application","tag-app-ispackaged","tag-electron-builder","tag-679","tag-678","tag-680","tag-ipc","tag-context-isolation","tag-343","tag-macos","tag-vibe-coding","tag-node-js","tag-javascript","tag-electron","tag-96"],"veu_head_title_object":{"title":"","add_site_title":""},"_links":{"self":[{"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/posts\/11048","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/comments?post=11048"}],"version-history":[{"count":1,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/posts\/11048\/revisions"}],"predecessor-version":[{"id":12305,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/posts\/11048\/revisions\/12305"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/media\/11057"}],"wp:attachment":[{"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/media?parent=11048"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/categories?post=11048"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code-plus.jp\/gp\/wp-json\/wp\/v2\/tags?post=11048"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}