{"id":23093799,"url":"https://github.com/hiyangguo/electron-with-react","last_synced_at":"2026-05-08T13:36:42.186Z","repository":{"id":112517971,"uuid":"127121902","full_name":"hiyangguo/electron-with-react","owner":"hiyangguo","description":"A electron start demo with electron and react , use creat-react-app build and support less and so on.","archived":false,"fork":false,"pushed_at":"2018-03-28T10:16:19.000Z","size":7388,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-09T07:15:52.112Z","etag":null,"topics":["create-react-app","electron","guide","react"],"latest_commit_sha":null,"homepage":"http://hiyangguo.github.io/2018/03/27/build-a-app-width-electron-and-react/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hiyangguo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-03-28T10:09:35.000Z","updated_at":"2020-01-16T02:50:31.000Z","dependencies_parsed_at":"2023-05-15T13:00:37.990Z","dependency_job_id":null,"html_url":"https://github.com/hiyangguo/electron-with-react","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hiyangguo%2Felectron-with-react","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hiyangguo%2Felectron-with-react/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hiyangguo%2Felectron-with-react/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hiyangguo%2Felectron-with-react/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hiyangguo","download_url":"https://codeload.github.com/hiyangguo/electron-with-react/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247061784,"owners_count":20877169,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["create-react-app","electron","guide","react"],"created_at":"2024-12-16T21:54:04.832Z","updated_at":"2026-05-08T13:36:37.131Z","avatar_url":"https://github.com/hiyangguo.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"这篇文章主要记录了，使用 Electron 构建的一个 APP 过程中，所遇到的关键步骤和遇到的问题。\n\n# 最终效果图\n![最终效果图](/images/electron-preview.gif)\n[查看源码][bt-radish-app]\n\n\u003c!-- more --\u003e\n\n# 起步\n首先使用 `create-react-app` 新建一个 react app。因为这玩意儿新建的时候会帮你初始化`npm`，相当刺激。\n```bash\nnpx create-react-app test-app\n```\n\n\u003e [npx 是什么][what-is-npx]\n\n安装好以后，我们需要按照 Electron 官方示例开始继续。\n``` bash\nnpm install --save-dev electron\n```\n然后。。。就卡住了，卡住了有木有？！是我们姿势不对么？这里什么也没写啊。什么鬼？\n那我们加个参数，看看到底是什么情况\n```bash\nnpm install  --save-dev electron --verbose \n```\n之后我们就能看到了，是下载 electron 的时候，下不下来。\n```bash\n\u003e electron@1.8.4 postinstall /Users/godfery/GitRepo/hiyangguo.github.io/node_modules/electron\n\u003e node install.js\n\n\n... and 1 more\n```\n这里是卡在了下载 electron 的地方，所以我们需要使用国内的镜像。\n在根目录新建一个 `.npmrc` 文件，内容如下:\n```\n## 这里推荐使用淘宝镜像，当然也可以使用其他镜像\nelectron_mirror=https://npm.taobao.org/mirrors/electron/\n```\n也可以使用声明临时变量的方式 \n```bash\nexport electron_mirror=\"https://npm.taobao.org/mirrors/electron/\"\n```\n\n之后再执行`npm install  --save-dev electron` 就可以顺利的安装了。\n然后修改`package.json`\n```diff\n{\n  \"name\": \"test-app\",\n  \"version\": \"0.1.0\",\n+ \"main\": \"main.js\",\n  \"private\": true,\n  \"dependencies\": {\n    \"react\": \"^16.2.0\",\n    \"react-dom\": \"^16.2.0\",\n    \"react-scripts\": \"1.1.1\"\n  },\n  \"scripts\": {\n+   \"start-electron\": \"electron .\",\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\"\n  },\n  \"devDependencies\": {\n    \"electron\": \"^1.8.4\"\n  }\n}\n\n```\n\n之后在根目录新建一个`main.js`文件\n```javascript\nconst { app, BrowserWindow } = require('electron')\n\n// 保持一个对于 window 对象的全局引用，如果你不这样做，\n// 当 JavaScript 对象被垃圾回收， window 会被自动地关闭\nlet win\n\nfunction createWindow() {\n  // 创建浏览器窗口。\n  win = new BrowserWindow({ width: 800, height: 600 })\n\n  // 然后加载应用的 index.html。\n  win.loadURL('http://localhost:3000')\n\n  // 打开开发者工具。\n  win.webContents.openDevTools()\n\n  // 当 window 被关闭，这个事件会被触发。\n  win.on('closed', () =\u003e {\n    // 取消引用 window 对象，如果你的应用支持多窗口的话，\n    // 通常会把多个 window 对象存放在一个数组里面，\n    // 与此同时，你应该删除相应的元素。\n    win = null\n  })\n}\n\n// Electron 会在初始化后并准备\n// 创建浏览器窗口时，调用这个函数。\n// 部分 API 在 ready 事件触发后才能使用。\napp.on('ready', createWindow)\n\n// 当全部窗口关闭时退出。\napp.on('window-all-closed', () =\u003e {\n  // 在 macOS 上，除非用户用 Cmd + Q 确定地退出，\n  // 否则绝大部分应用及其菜单栏会保持激活。\n  if (process.platform !== 'darwin') {\n    app.quit()\n  }\n})\n\napp.on('activate', () =\u003e {\n  // 在macOS上，当单击dock图标并且没有其他窗口打开时，\n  // 通常在应用程序中重新创建一个窗口。\n  if (win === null) {\n    createWindow()\n  }\n})\n```\n\n最后运行\n```\nnpm run start\nnpm run start-electron\n```\n\n当当当当！\n![electron-with-react-preview](/images/electron-with-react-preview.png)\n\n# 安装扩展\n既然是用`react`开发，肯定是要用[React Developer Tools][react-developer-tools]的，这里就来说一下，如何在`electron`中使用拓展。(以 mac 为例)\n1. 打开 Chrome 浏览器，导航到 `chrome://extensions`，找到 React Developer Tools 插件的 ID：**fmkadmapgofadopljbjfkapdkoienihi**\n2. 进入 `~/Library/Application Support/Google/Chrome/Default/Extensions` 目录。在 Finder 中，点击 前往 \u003e 前往文件夹。（或使用快捷键 `shift + command + G`）。粘贴即可。\n3. 进入 `fmkadmapgofadopljbjfkapdkoienihi` 文件夹，子目录`3.2.1_0`中的的文件拷贝项目根目录下`chrome-extensions`目录中，并重命名为`react-dev-tools`。\n4. 修改代码\n```diff\nconst { app, BrowserWindow } = require('electron')\n+ const path = require('path')\n\n// 保持一个对于 window 对象的全局引用，如果你不这样做，\n// 当 JavaScript 对象被垃圾回收， window 会被自动地关闭\nlet win\n\nfunction createWindow() {\n+ installExtensions()\n\n  // 创建浏览器窗口。\n  win = new BrowserWindow({ width: 800, height: 600 })\n\n  // 然后加载应用的 index.html。\n  win.loadURL('http://localhost:3000')\n\n  // 打开开发者工具。\n  win.webContents.openDevTools()\n\n  // 当 window 被关闭，这个事件会被触发。\n  win.on('closed', () =\u003e {\n    // 取消引用 window 对象，如果你的应用支持多窗口的话，\n    // 通常会把多个 window 对象存放在一个数组里面，\n    // 与此同时，你应该删除相应的元素。\n    win = null\n  })\n}\n\n// Electron 会在初始化后并准备\n// 创建浏览器窗口时，调用这个函数。\n// 部分 API 在 ready 事件触发后才能使用。\napp.on('ready', createWindow)\n\n// 当全部窗口关闭时退出。\napp.on('window-all-closed', () =\u003e {\n  // 在 macOS 上，除非用户用 Cmd + Q 确定地退出，\n  // 否则绝大部分应用及其菜单栏会保持激活。\n  if (process.platform !== 'darwin') {\n    app.quit()\n  }\n})\n\napp.on('activate', () =\u003e {\n  // 在macOS上，当单击dock图标并且没有其他窗口打开时，\n  // 通常在应用程序中重新创建一个窗口。\n  if (win === null) {\n    createWindow()\n  }\n})\n\n+ function installExtensions() {\n+   BrowserWindow.addDevToolsExtension(path.join(__dirname, 'chrome-extensions', 'react-dev-tools'));\n+ }\n```\n\n之后重启 electron\n![安装好 react-developer-tools的 截图](/images/electron-with-react-dev-tools-preview.png)\n\n# create-react-app  使用 less\n## 方法一\n[官方推荐的方式][creat-react-app-adding-a-css-preprocessor-sass-less-etc]。\n\n大致是说：\n  - 安装 less \n  - 使用 less 编译\n  - 添加 watch 监控文件变更实时编译\n  - 引入最终编译的 css 文件\n\n妈耶，简直 low 到爆啊。\n\n## 方法二\n运行 `npm run eject` ，然后改 webpack 的 config 。这方法破坏了整个项目，简直了。也不推荐。\n\n## 方法三\n那就没有什么既不破坏项目，又可以方便的使用 less 的方法呢？当然有\n使用 **[react-app-rewired][react-app-rewired]** 即可，方便简单的扩展 create-react-app\n1. 安装 **react-app-rewired**\n```bash\nnpm install react-app-rewired react-app-rewire-less --save-dev\n```\n2. 在根目录创建`config-overrides.js` 文件。\n```javascript\nconst rewireLess = require('react-app-rewire-less');\nmodule.exports = function override(config, env) {\n  config = rewireLess(config, env);\n  return config;\n};\n```\n3. 将 `packge.json` 中所有的 `react-scripts` 换成 `react-app-rewired`\n```diff\n{\n  \"name\": \"test-app\",\n  \"version\": \"0.1.0\",\n  \"main\": \"main.js\",\n  \"private\": true,\n  \"dependencies\": {\n    \"react\": \"^16.2.0\",\n    \"react-dom\": \"^16.2.0\",\n    \"react-scripts\": \"1.1.1\"\n  },\n  \"scripts\": {\n    \"start-electron\": \"electron .\",\n-   \"start\": \"react-scripts start\",\n+   \"start\": \"react-app-rewired start\",\n-   \"build\": \"react-scripts build\",\n+   \"build\": \"react-app-rewired build\",\n-   \"test\": \"react-scripts test --env=jsdom\",\n+   \"test\": \"react-app-rewired test --env=jsdom\",\n-   \"eject\": \"react-scripts eject\"\n  },\n  \"devDependencies\": {\n    \"electron\": \"^1.8.4\",\n    \"react-app-rewire-less\": \"^2.1.1\",\n    \"react-app-rewired\": \"^1.5.0\"\n  }\n}\n```\n4. 运行  `npm run start`\n\n# electron 跨域\nelectron 可以禁用跨域检查\n```diff\nwin = new BrowserWindow({\n    width: 800,\n    height: 600,\n+   //禁用跨域检查\n+   webPreferences: {\n+     webSecurity: false\n+   }\n})\n```\n\n开发过程不再赘述，有兴趣可以直接[查看源码][bt-radish-app]。\n\n# 打包\n## 修改 electron 代码\n修改`package.json`中的 `script`， 添加`NODE_ENV` 环境变量用于区分环境\n```diff\n- \"start-electron\": \"electron .\",\n+ \"start-electron\": \"NODE_ENV=development electron .\",\n```\n然后修改 `main.js`\n```diff\nconst { app, BrowserWindow } = require('electron')\nconst path = require('path')\n+ const url = require('url')\n+ const IS_DEV = process.env.NODE_ENV === 'development'\n\n// 保持一个对于 window 对象的全局引用，如果你不这样做，\n// 当 JavaScript 对象被垃圾回收， window 会被自动地关闭\nlet win\n\nfunction createWindow() {\n  installExtensions()\n\n  // 创建浏览器窗口。\n  win = new BrowserWindow({\n    width: 800,\n    height: 600,\n    //禁用跨域检查\n    webPreferences: {\n      webSecurity: false\n    }\n  })\n\n-  // 然后加载应用的 index.html。\n-  win.loadURL('http://localhost:3000')\n+  // 加载应用\n+  const staticIndexPath = path.join(__dirname, './index.html');\n+  const main = IS_DEV ? `http://localhost:3000` : url.format({\n+    pathname: staticIndexPath,\n+    protocol: 'file:',\n+    slashes: true\n+  });\n+  win.loadURL(main)\n\n  // 打开开发者工具。\n-  win.webContents.openDevTools()\n+  IS_DEV \u0026\u0026win.webContents.openDevTools()\n\n  // 当 window 被关闭，这个事件会被触发。\n  win.on('closed', () =\u003e {\n    // 取消引用 window 对象，如果你的应用支持多窗口的话，\n    // 通常会把多个 window 对象存放在一个数组里面，\n    // 与此同时，你应该删除相应的元素。\n    win = null\n  })\n}\n\n// Electron 会在初始化后并准备\n// 创建浏览器窗口时，调用这个函数。\n// 部分 API 在 ready 事件触发后才能使用。\napp.on('ready', createWindow)\n\n// 当全部窗口关闭时退出。\napp.on('window-all-closed', () =\u003e {\n  // 在 macOS 上，除非用户用 Cmd + Q 确定地退出，\n  // 否则绝大部分应用及其菜单栏会保持激活。\n  if (process.platform !== 'darwin') {\n    app.quit()\n  }\n})\n\napp.on('activate', () =\u003e {\n  // 在macOS上，当单击dock图标并且没有其他窗口打开时，\n  // 通常在应用程序中重新创建一个窗口。\n  if (win === null) {\n    createWindow()\n  }\n})\n\nfunction installExtensions() {\n  BrowserWindow.addDevToolsExtension(path.join(__dirname, 'chrome-extensions', 'react-dev-tools'));\n}\n```\n## 打包\n由于 `create-react-app` 默认打包的路径为 `/` 根目录，而在 electron 中，需要使用相对路径所以需要再次次改`package.json`\n```diff\n{\n  \"name\": \"test-app\",\n  \"version\": \"0.1.0\",\n  \"main\": \"main.js\",\n  \"private\": true,\n+ \"homepage\": \"./\",\n  \"dependencies\": {\n    \"react\": \"^16.2.0\",\n    \"react-dom\": \"^16.2.0\",\n    \"react-scripts\": \"1.1.1\"\n  },\n  \"scripts\": {\n    \"start-electron\": \"NODE_ENV=development electron .\",\n    \"start\": \"react-app-rewired start\",\n    \"build\": \"react-app-rewired build\",\n    \"test\": \"react-app-rewired test --env=jsdom\"\n  },\n  \"devDependencies\": {\n    \"electron\": \"^1.8.4\",\n    \"react-app-rewire-less\": \"^2.1.1\",\n    \"react-app-rewired\": \"^1.5.0\"\n  }\n}\n```\n打包工具这里使用的是[electron-builder][electron-builder-home]。\n### 操作步骤\n1. 安装 `electron-builder` \n```bash\nnpm install electron-builder --save-dev\n```\n2. 修改配置，添加必要的文件。\n  - 修改 `name`，`verison`，`description`，`author`字段\n  - 在 `./public`文件夹中放入 `icon.png` 文件\n  - 将 `main.js` 重命名为 `electron.js`，让如根目录`./public` 目录下。同时修改 `package.json`\n  - 由于`electron-builder`中不能使用`dependencies`，所以**务必将所有的`dependencies`加入`devDependencies`**。\n最终的 `package.json`文件：\n\n```diff\n{\n  \"name\": \"test-app\",\n  \"version\": \"0.1.0\",\n  \"description\": \"A Eleactron app with react.\",\n  \"author\": \"Godfery.Yang\u003chiyangguo@qq.com\u003e\",\n- \"main\": \"main.js\",\n+ \"main\": \"./public/electron.js\",\n  \"private\": true,\n  \"homepage\": \"./\",\n-  \"dependencies\": {\n-    \"react\": \"^16.2.0\",\n-    \"react-dom\": \"^16.2.0\",\n-    \"react-scripts\": \"1.1.1\"\n-  },\n+  \"build\": {\n+    \"mac\": {\n+      \"category\": \"demo\"\n+    },\n+    \"files\": [\n+      {\n+        \"from\": \"./\",\n+        \"to\": \"./\",\n+        \"filter\": [\n+          \"**/*\",\n+          \"!node_modules\"\n+        ]\n+      }\n+    ],\n+    \"directories\": {\n+      \"buildResources\": \"public\"\n+    }\n+  },\n  \"scripts\": {\n    \"start-electron\": \"NODE_ENV=development electron .\",\n    \"start\": \"react-app-rewired start\",\n    \"build\": \"react-app-rewired build\",\n    \"test\": \"react-app-rewired test --env=jsdom\",\n+   \"packager\": \"npm run build \u0026\u0026 rm -rf dist \u0026\u0026 electron-builder\"\n  },\n  \"devDependencies\": {\n    \"electron\": \"^1.8.4\",\n    \"electron-builder\": \"^20.8.1\",\n+    \"react\": \"^16.2.0\",\n    \"react-app-rewire-less\": \"^2.1.1\",\n    \"react-app-rewired\": \"^1.5.0\",\n+    \"react-dom\": \"^16.2.0\",\n+    \"react-scripts\": \"1.1.1\"\n  }\n}\n```\n\n之后运行`npm run packager` 即可得到 `dmg` 安装文件。\n\n\u003e 参考文章\n\u003e [From React to an Electron app ready for production](https://medium.com/@kitze/%EF%B8%8F-from-react-to-an-electron-app-ready-for-production-a0468ecb1da3)\n\u003e [如何加载一个开发者工具扩展](https://electronjs.org/docs/tutorial/devtools-extension#%E5%A6%82%E4%BD%95%E5%8A%A0%E8%BD%BD%E4%B8%80%E4%B8%AA%E5%BC%80%E5%8F%91%E8%80%85%E5%B7%A5%E5%85%B7%E6%89%A9%E5%B1%95)\n\u003e [Electron 官放文档](https://electronjs.org/docs)\n\n[what-is-npx]:https://zhuanlan.zhihu.com/p/27840803\n[react-developer-tools]:https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=zh-CN\n[creat-react-app-adding-a-css-preprocessor-sass-less-etc]:https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-a-css-preprocessor-sass-less-etc\n[react-app-rewired]:https://github.com/timarney/react-app-rewired\n[bt-radish-app]:https://github.com/hiyangguo/bt-radish-app\n[electron-builder-home]:https://electron.build/","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhiyangguo%2Felectron-with-react","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhiyangguo%2Felectron-with-react","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhiyangguo%2Felectron-with-react/lists"}