Electron无法下载问题(yarn 4.0版本)

Electron无法下载问题

Electron打包,我把npm切换成yarn时,导致electron二进制包下载不了。

问题1:

执行:yarn install 报错,electron二进制文件下载不了。因为被墙了

我使用的yarn是4.0版本。正常通过npm命令安装的是1.0版本

原因

之前一直使用 yarn1 版本,但发现低版本对 TS 语言支持的不是很好,编译的时候会报错误信息。查了资料以后说是要升级到 yarn3 版本以上 TS 就不会报错了。目前最新的是4.0版本,升到最新以后发现之前的 Electron 配置文件 config 不能使用了

ini 复制代码
ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/
ELECTRON_BUILDER_BINARIES_MIRROR=https://npmmirror.com/mirrors/electron-builder-binaries/

导致上面的环境变量配置不上去,一直下载 electron 时报错。

解决方案

在工程根目录下创建 shell脚本,yarn_install.sh 文件:

bash 复制代码
#!/bin/bash
​
rm -rf node_modules && rm -rf yarn.lock && rm -rf dist
export ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
export ELECTRON_BUILDER_BINARIES_MIRROR="https://npmmirror.com/mirrors/electron-builder-binaries/"
yarn cache clean --all && yarn install

通过命令行上下文中指定ELECTRON_MIRROR和ELECTRON_BUILDER_BINARIES_MIRROR变量。可以让命令:yarn install 正常执行

问题2

当我使用 electron-builder 工具打包 windows/macos/linux 平时的包时报错:

bash 复制代码
  • electron-builder  version=24.13.3 os=22.6.0
  • loaded configuration  file=/Users/yuhang/yuyue/project/webstorm/electron-vite-template/build.json
  • writing effective config  file=build/builder-effective-config.yaml
  • packaging       platform=darwin arch=arm64 electron=29.1.2 appOutDir=build/mac-arm64
  ⨯ Get "https://github.com/electron/electron/releases/download/v29.1.2/electron-v29.1.2-darwin-arm64.zip": Method Not Allowed
github.com/develar/app-builder/pkg/download.(*Downloader).follow.func1
        /Volumes/data/Documents/app-builder/pkg/download/downloader.go:206
github.com/develar/app-builder/pkg/download.(*Downloader).follow
        /Volumes/data/Documents/app-builder/pkg/download/downloader.go:234
github.com/develar/app-builder/pkg/download.(*Downloader).DownloadNoRetry
        /Volumes/data/Documents/app-builder/pkg/download/downloader.go:128
github.com/develar/app-builder/pkg/download.(*Downloader).Download
        /Volumes/data/Documents/app-builder/pkg/download/downloader.go:112
github.com/develar/app-builder/pkg/electron.(*ElectronDownloader).doDownload
        /Volumes/data/Documents/app-builder/pkg/electron/electronDownloader.go:192
github.com/develar/app-builder/pkg/electron.(*ElectronDownloader).Download
        /Volumes/data/Documents/app-builder/pkg/electron/electronDownloader.go:177
github.com/develar/app-builder/pkg/electron.downloadElectron.func1.1
        /Volumes/data/Documents/app-builder/pkg/electron/electronDownloader.go:73
github.com/develar/app-builder/pkg/util.MapAsyncConcurrency.func2
        /Volumes/data/Documents/app-builder/pkg/util/async.go:68
runtime.goexit
        /usr/local/Cellar/go/1.17/libexec/src/runtime/asm_arm64.s:1133  
  ⨯ /Users/yuhang/yuyue/project/webstorm/electron-vite-template/node_modules/app-builder-bin/mac/app-builder_arm64 process failed ERR_ELECTRON_BUILDER_CANNOT_EXECUTE
Exit code:
1  failedTask=build stackTrace=Error: /Users/yuhang/yuyue/project/webstorm/electron-vite-template/node_modules/app-builder-bin/mac/app-builder_arm64 process failed ERR_ELECTRON_BUILDER_CANNOT_EXECUTE
Exit code:
1
    at ChildProcess.<anonymous> (/Users/yuhang/yuyue/project/webstorm/electron-vite-template/node_modules/builder-util/src/util.ts:252:14)
    at Object.onceWrapper (node:events:629:26)
    at ChildProcess.emit (node:events:514:28)
    at maybeClose (node:internal/child_process:1105:16)
    at Process.ChildProcess._handle.onexit (node:internal/child_process:305:5)
​
Process finished with exit code 1
​

这个错误提示,electron二进制文件下载不了

原因

我查看了 electron下载部分的源代码有问题,需要改 node_modules 的代码。这种方式好像不太好

我查了很多资料 npm 好像可以配置文件里加参数解决。但 yarn 4.0版本,没什么资料。官方文档上查了以后发现,也不能配置 ELECTRON_MIRROR这些变量。

我查了electron的官网信息,说是会把这些缓存文件放在下面的路径:

  • Linux: $XDG_CACHE_HOME or ~/.cache/electron/
  • macOS: ~/Library/Caches/electron/
  • Windows: $LOCALAPPDATA/electron/Cache or ~/AppData/Local/electron/Cache/

没有完美解决方案,目前我的方式是自己去下载对应的 electron 版本到缓存路径中。这样打包的时候,直接读缓存不用去下载了。

解决方案

我自己用golang 写了脚本。轻量的脚手架,自动读取 package.json 文件中的 electron版本号。去第三方镜像网站自动下载。写到不同平台的缓存路径下。使用 golang 是因为可以跨平台,所以系统都可以直接使用。

electron-download.go脚本代码:

go 复制代码
package main
​
import (
  "encoding/json"
  "errors"
  "fmt"
  "github.com/cheggaaa/pb/v3"
  "io"
  "log"
  "net/http"
  "os"
  "os/user"
  "path"
  "path/filepath"
  "regexp"
  "runtime"
  "strconv"
  "strings"
  "time"
)
​
func main() {
  arch := [3]string{"x64", "i32", "arm64"}
  baseURL := "https://npmmirror.com/mirrors/electron/"
  var version, _ = readPackageFile()
​
  // 生成需要下载的electron二进制包
  var downloadUrls []string
  for _, s := range arch {
    url, err := buildDownloadURL(baseURL, version, s)
    if err == nil {
      downloadUrls = append(downloadUrls, url)
    }
  }
​
  downloadElectron(downloadUrls)
​
}
​
// 获取缓存目录
func getCacheDir() string {
  usr, _ := user.Current()
  platform := runtime.GOOS
  var cacheDir string
​
  if platform == "linux" {
    cacheDir = filepath.Join(usr.HomeDir, ".cache", "electron")
  } else if platform == "darwin" {
    cacheDir = filepath.Join(usr.HomeDir, "Library", "Caches", "electron")
  } else if platform == "windows" {
    cacheDir = filepath.Join(usr.HomeDir, "AppData", "Local", "electron", "Cache")
  }
​
  return cacheDir
}
​
// 生成下载地址
func buildDownloadURL(baseURL string, version string, arch string) (string, error) {
  platform := runtime.GOOS
  filename := ""
​
  if platform != "windows" && arch == "i32" {
    return "", errors.New("")
  } else {
    filename = fmt.Sprintf("electron-v%s-%s-%s.zip", version, platform, arch)
  }
​
  url := baseURL + version + "/" + filename
  return url, nil
}
​
// 下载Electron
func downloadElectron(downloadUrls []string) {
  cacheDir := getCacheDir()
​
  for _, url := range downloadUrls {
​
    // 使用 path 包获取文件名
    filename := path.Base(url)
​
    // 如果 URL 中包含查询参数,需要额外处理
    if strings.ContainsRune(filename, '?') {
      filename = strings.Split(filename, "?")[0]
    }
    savePath := filepath.Join(cacheDir, filename)
​
    file := downloadFile(url, savePath)
    if file {
      fmt.Printf("下载完成,保存至: %s\n", savePath)
    }
​
  }
​
}
​
// 下载文件
func downloadFile(url string, savePath string) bool {
  // 检查本地文件是否已存在
  if _, err := os.Stat(savePath); err == nil {
    fmt.Printf("\n文件已存在,无需下载:%s\n本地文件路径:%s \n\n", url, savePath)
    return false
  }
​
  client := http.DefaultClient
  client.Timeout = 60 * 10 * time.Second
  reps, err := client.Get(url)
  if err != nil {
    log.Panic(err.Error())
  }
  if reps.StatusCode == http.StatusOK {
    //保存文件
    file, err := os.Create(savePath)
    if err != nil {
      log.Panic(err.Error())
    }
    defer file.Close() //关闭文件
    //获取下载文件的大小
    length := reps.Header.Get("Content-Length")
    size, _ := strconv.ParseInt(length, 10, 64)
    body := reps.Body //获取文件内容
    bar := pb.Full.Start64(size)
    bar.SetWidth(120)                         //设置进度条宽度
    bar.SetRefreshRate(10 * time.Millisecond) //设置刷新速率
    defer bar.Finish()
    // create proxy reader
    barReader := bar.NewProxyReader(body)
    //写入文件
    writer := io.Writer(file)
    io.Copy(writer, barReader)
    //defer fmt.Printf("\n下载完成,保存至: %s\n", savePath)
  }
  return true
}
​
// 读取当前目录下的文件
func readPackageFile() (string, error) {
​
  // 读取 package.json 文件
  filePath := "package.json"
  jsonData, err := os.ReadFile(filePath)
  if err != nil {
    panic(err)
  }
​
  var parsedData map[string]interface{}
  err = json.Unmarshal(jsonData, &parsedData)
  if err != nil {
    return "", err
  }
​
  electronVersion := parsedData["devDependencies"].(map[string]interface{})["electron"].(string)
  re := regexp.MustCompile(`\d+.\d+.\d+`)
  versionNumbers := re.FindString(electronVersion)
  return versionNumbers, nil
}
​

可以去我的 github 上下载对应的执行文件放到 package.json 同级目录就可以了。

进入到项目根目录,执行命令:

arduino 复制代码
yarn install && ./electron-download-mac-arm64 // mac m1版本
yarn install && ./electron-download-mac-amd64 // mac x86版本
yarn install && ./electron-download-linux-amd64 // linux x86版本
yarn install && ./electron-download-linux-arm64 // linux x86版本
yarn install && ./electron-download-linux-arm64 // windows x86版本
yarn install && ./electron-download-windows-amd64.exe // mac x86版本
yarn install && ./electron-download-windows-arm64.exe // mac x86版本
​

当前环境已经安装好了

  • mac执行打包脚本:
ini 复制代码
export ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
export ELECTRON_BUILDER_BINARIES_MIRROR="https://npmmirror.com/mirrors/electron-builder-binaries/"
yarn run build:mac
  • windows32位打包:
ini 复制代码
export ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
export ELECTRON_BUILDER_BINARIES_MIRROR="https://npmmirror.com/mirrors/electron-builder-binaries/"
yarn run build:win32
​
  • windows64位打包:
ini 复制代码
export ELECTRON_MIRROR="https://npmmirror.com/mirrors/electron/"
export ELECTRON_BUILDER_BINARIES_MIRROR="https://npmmirror.com/mirrors/electron-builder-binaries/"
yarn run build:win64
​

都需要配置环境变量

相关推荐
我要洋人死19 分钟前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人30 分钟前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人31 分钟前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR36 分钟前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香38 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q24985969341 分钟前
前端预览word、excel、ppt
前端·word·excel
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
逐·風6 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#