Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结

记录:electron-vue大佬博客

一、应用打包

使用electron-builder库,先安装它。
1、cnpm i electron-builder -D

2、尝试使用npm run build打包react项目
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第1张图片
注意事项一
注:electron-is-dev 需要变成生产依赖
在这里插入图片描述
3、根据electron-builder配置文档去实施
4、配置分基础配置,和不同操作系统配置,对象会覆盖基础配置。
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第2张图片
5、增加基础描述,为了使打包的信息详细。
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第3张图片
6、增加scripts // pack是出来一个安装完毕的文件,而dist 是打包出来的安装包

 "pack": "electron-builder --dir",
 "dist": "electron-builder",

7、package.json 内置钩子 preXXX和postXXX
在这里插入图片描述
表示在运行pack时,先执行prepack命名,再执行pack,最后执行postpack
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第4张图片

此时pack肯定是失败的,因为还缺少很多配置项,所以
注意事项二:extends: null

Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第5张图片

二、错误解决方案

1、错误一:

运行npm run pack 打包命令后,出现报错。Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第6张图片
检测是拉取[email protected]相关资源失败,
解决方案: 回退至[email protected]
但是发现npm install [email protected] 也报错
在这里插入图片描述
解决方案:cnpm去安装[email protected]

成功!

如果想使用electron@7.+的版本,可以自行去release中寻找,查找合适的资源点,然后即可pack。

注:使用淘宝镜像去安装可以解决上述所有问题

npm i --registry=https://registry.npm.taobao.org

补充

可以手动去下载 release 的任意版本,并放置Cache 目录下,如
‪C:\Users\lenovo\AppData\Local\electron\Cache\electron-v7.1.2-win32-x64.zip
Electron:运行npm run build构建环境失败解决方案


2、错误二:

在这里插入图片描述
软件生产环境的依赖需要被明确,不能放入开发环境依赖中。


3、错误三:

打包成功后,运行exe执行文件没有页面。
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第7张图片
原因:create-react-app 生成的文件是在build文件夹下。但electron认为整个项目打包出的文件是在pack过程中指定出需要使用的一些文件。即我们缺失了支持以及服务electron相关的文件。
解决方案: 手动添加要打包哪些文件,在files对象中。
注:glob打包路径 **/*,2个星号即匹配所有文件夹和子文件,1个星号匹配当前路径下的所有文件

  "build": {
    "appId": "cloudDoc",
    "productName": "七牛云文档",
    "copyright": "Copyright © 2019 ${author}",
    "files": [
      "main.js", // 主进程
      "build/**/*", // create-react-app 渲染进程1
      "settings/**/*", // 渲染进程2
      "./src/menuTemplate.js", // 菜单项
      "./src/AppWindow.js", // 进程封装 类
      "./src/utils/QiniuManager.js", // 七牛服务 类
      "./src/utils/mainHelper.js" // 主进程工具
    ],
    "extends": null
  },

然后继续打包一次,又发生了错误。

3、错误三:
react渲染进程的资源定位失败
在这里插入图片描述
是因为build出来的都是绝对路径,需要改成相对路径。
注:react自身打包出来是绝对路径是为了方便资源的代理,但是对于桌面端场景,相对路径更合适。
解决方案: 将create-react-app打包路径改成相对路径。 修改package.json,然后重新打包react项目,并打包electron
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第8张图片

三、pack到底做了什么

简要分析

1、首先我们electron打包出的项目,其运行需要chromeV8引擎的支持。
2、主要占内存的文件是app.asar(130mb)和七牛云文档.exe(95mb)
3、为了刨根问底,app.asar到底含有什么文件,我们可以使用官方解压缩工具

解压缩app.asar

1、未配置files的app.asar解压出来,是整个项目的文件目录。
2、配置过files后,解压出来是以main.js为入口,携带node_modules,package.json,以及一系列files包含的文件。
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第9张图片
3、最后打包出来的可执行文件只有一个
在这里插入图片描述
它的功能就是加载resrouces/app.asar文件中的内容(从package.json中的main字段获取main.js,进行一系列加载)

四、生成安装包

  "build": {
    "appId": "cloudDoc",
    "productName": "七牛云文档",
    "copyright": "Copyright © 2019 ${author}",
    "files": [ //... 若干需药打包的文件]
    "extends": null, // 扩展入口
    "directories": {
      "buildResources": "assets" // 静态资源路径
    },
    "mac": { // mac系统
      "category": "public.app-category.productivity", // 安装在mac'效率'分类下
      "artifactName": "${productName}-${version}-${arch}.${ext}", // 安装包的名称
    },
    "dmg": { // mac安装软件dmg格式
      "background": "assets/adddmg.png",
      "icon": "assets/icon.icns",
      "iconSize": 100,
      "contents": [
        {
          "x": 380,
          "y": 280,
          "type": "link",
          "path": "/Applications"
        },
        {
          "x": 110,
          "y": 280,
          "type": "file",
        }
      ],
      "window": {
        "width": 500,
        "height": 500
      }
    },
    "win": { // window系统
      "target": [
        "msi","nsis"
      ],
      "icon": "assets/icon.ico",
      "artifactName": "${productName}-Web-Setup-${version}.${ext}",
      "publisherName": "Killer"
    },
    "nsis": { 
      "allowToChangeInstallationDirectory": true, // 改变目录
      "oneClick": false, // 是否一键安装
      "perMachine": false
    }
  }
!!!注: 安装路径绝不可以有中文,不然nsis安装包会生成失败。

五、打包优化

一、优化node_modules

1、create-react-app在build时,已将生产依赖dependencies,全部打包到了[chunk].js中,所以app.asar中的node_modules,是没必要全部被打包到应用中的。
2、故在进行electron打包时,将dependencies不相关模块,全部移到devDependencies中
3、打包完成后显示压缩至11mb。

二、优化main.js主进程代码

1、因为main.js不受webpack的控制,所以我们需要尝试用webpack去压缩它,并尝试优化files需要依赖的文件(不那么码农式的一个个复制,像这样)
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第10张图片

上述的文件都被单独打包在 build下(webpack 打包完主进程文件),删除上述文件后,运行打包会报下述错误:
在这里插入图片描述

是因为 electron-builder 打包 会默认以根目录的 main.js 为入口。
我们需要改变配置项

"build": {
// ...
    "extraMetadata": {
      "main": "./build/main.js"
    },

webpack 针对 electron 的打包优化有特殊的配置

const path = require('path')

module.exports = {
  mode: "production",
  target: 'electron-main',
  entry: {
    main: path.resolve(__dirname, 'main.js')
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js'
  },
  node: {
    __dirname: false
  }
}

2、新建webpack.config.js文件
2019年12月9日10:57:27,耗时,30分钟,打包啥的都没问题,但是运行exe失败了。

留下2个问题:

1、npm run build 和 npm run pack 这2个是create-react-app和electron分别的打包命令,但是devdenp和denp均设置不同。张轩大大是直接多打包运行,共用一个package.json,我暂不清楚是否有问题。
思考得出: create-react-app 的build 用了webpack,并将模块依赖打包入了[chunk].js,所以,开发和生产依赖的标识,并不会影响webpack打包该包。所以,仅需适配electron即可

2、webpack.config.js打包主进程main.js后,尝试使用extraMetadata:{main: “main.js”},引入调整后,运行exe,加载失败,尚不清楚原因。

暂留坑,有缘再解决。

六、自动更新

上传release

自动更新:是指远程客户端的版本与服务端版本不一致,进行更新的过程。
1、需要将本地上传好的文件,pack到某处,并进行一次release,这个过程就是publish。
2、完成github部署后,即可进行release发布。
3、electron-builder 在pack时,为我们提供了release过程,简单配置即可。

// package.json
"scripts:{
	// ...
    "release": "electron-builder",
    "prerelease": "npm run build"
 }

4、根据文档指示github需要去生成GH_TOKEN
并使用cross-env 添加参数至release命令中。
在这里插入图片描述
npm run release 发现代码已上传
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第11张图片
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第12张图片

使用electron-updater进行自动更新

1、npm install electron-updater --save-dev
在main.js中
在这里插入图片描述
app的ready事件内,
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第13张图片
2、然后运行npm run pack 打包测试下是否正常。

注意:使用updater后electron依赖必须明确版本而不能采用向上兼容^号。
在这里插入图片描述
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第14张图片
3、然后尝试运行exe,报错,error事件已经捕获,是因为我们需要重新release带有更新功能的项目,才能进行更新。
在这里插入图片描述
4、重新release当前带有更新模块的版本。
release成功后,会在resources文件夹下生成.yml,用于指向更新地址。
5、release结束后,本地打开exe查看,弹出弹窗。
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第15张图片
但是没有一个程序员会每次打包并release到github上来测试更新的代码。
6、在开发环境下可以手动模拟release创建的.yml文件
Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结_第16张图片
7、之后直接npm run dev 以开发者模式运行即可,开发模式可以检测到更新,我这里不截图了,自己也云里雾里的,我就粘贴代码了。

app.on('ready', () => {
  if (isDev) {
    autoUpdater.updateConfigPath = path.join(__dirname, 'dev-app-update.yml');
  }
  /**
   * autoUpdater
   *  checkForUpdatesAndNotify 仅在生成模式才能运行
   * 若是开发模式
   *  可以兼容使用 checkForUpdates
   */

  // 取消自动下载
  autoUpdater.autoDownload = false; // 仅生成模式
  autoUpdater.checkForUpdates(); // 兼容开发和生产模式

  // 检测异常
  autoUpdater.on('error', (error) => {
    dialog.showErrorBox(
      '检测更新异常',
      error === null ? 'unknown' : '有错误提示,但是我不知道怎么打印...'
    );
  });

  // 检测版本中...
  autoUpdater.on('checking-for-update', () => {
    console.log('checking for update ...');
  });

  // 如果检测到新版本
  autoUpdater.on('update-available', () => {
    dialog.showMessageBox({
      type: 'info',
      title: '应用有新的版本',
      message: '发现新版本,是否现在更新?',
      button: ['是', '否']
    }, (buttonIndex) => {
      if (buttonIndex === 0) {
        autoUpdater.downloadUpdate();
      }
    });
  });

  // 当前是新版本
  autoUpdater.on('update-not-available', () => {
    dialog.showMessageBox({
      title: '没有新版本',
      message: '当前已经是最新版本'
    });
  });

  // github拉取最新版本中...
  autoUpdater.on('download-progress', (progressObj) => {
    const { bytesPerSecond, progress, percent, total, transferred } = progressObj;
    console.log('bytesPerSecond: ' + bytesPerSecond + ',progress: ' + progress + ',percent: ' + percent + ',transferred: ' + transferred + '/total: ' + total);
  });

  // 拉取新版本完毕
  autoUpdater.on('update-downloaded', () => {
    dialog.showMessageBox({
      title: '安装更新',
      message: '更新下载完毕,应用将重启并进行安装'
    }, () => {
      setImmediate(() => autoUpdater.quitAndInstall())
    });
  });

// ...逻辑代码

你可能感兴趣的:(Electron学习之旅9,create-react-app和electron完成应用打包 + 注意事项,项目错误解决方案(down失败),pack到底做了什么,生成安装包,打包优化,自动更新,总结)