Electron 安裝報錯 'Electron failed to install correctly'

按照electron官方文檔,開始了打造你的第一個 Electron 應用

index.js,index.html,package.json一切都準備就緒,然後敲下了命令

npm run start

然後報錯了。。報錯信息如下


> [email protected] start F:\work\front-end\electron\demo
> electron .

F:\work\front-end\electron\demo\node_modules\electron\index.js:14
    throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again')
    ^

Error: Electron failed to install correctly, please delete node_modules/electron and try installing again
    at getElectronPath (F:\work\front-end\electron\demo\node_modules\electron\index.js:14:11)
    at Object.<anonymous> (F:\work\front-end\electron\demo\node_modules\electron\index.js:18:18)
    at Module._compile (internal/modules/cjs/loader.js:774:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:785:10)
    at Module.load (internal/modules/cjs/loader.js:641:32)
    at Function.Module._load (internal/modules/cjs/loader.js:556:12)
    at Module.require (internal/modules/cjs/loader.js:681:19)
    at require (internal/modules/cjs/helpers.js:16:16)
    at Object.<anonymous> (F:\work\front-end\electron\demo\node_modules\electron\cli.js:3:16)
    at Module._compile (internal/modules/cjs/loader.js:774:30)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: `electron .`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\admin\AppData\Roaming\npm-cache\_logs\2019-12-27T09_00_14_091Z-debug.log

納尼,第一個應用就身先士卒了?!!那怎麼繼續下去?
於是我打開了報錯的代碼,如下

var fs = require('fs')
var path = require('path')

var pathFile = path.join(__dirname, 'path.txt')

function getElectronPath () {
  if (fs.existsSync(pathFile)) {
    var executablePath = fs.readFileSync(pathFile, 'utf-8')
    if (process.env.ELECTRON_OVERRIDE_DIST_PATH) {
      return path.join(process.env.ELECTRON_OVERRIDE_DIST_PATH, executablePath)
    }
    return path.join(__dirname, 'dist', executablePath)
  } else {
    throw new Error('Electron failed to install correctly, please delete node_modules/electron and try installing again')
  }
}

module.exports = getElectronPath()

可以看出是因爲沒有找到 path.txt 文件,我看了下目錄,果然沒有這個文件,那這個文件是本來就有的麼,我去github查了一下,github上也沒有啊,在源碼搜了一下,發現在 install.js 中有創建這個文件,那這個install.js是什麼時候運行的呢,我們來看下package.json,發現script中有個postinstall命令,這個命令是指裝完包運行,所以是裝完包運行這個命令報錯了?
我們進這個目錄運行下命令 node install,發現報錯如下

PS F:\work\front-end\electron\electron-quick-start\node_modules\electron> node install
(node:10024) UnhandledPromiseRejectionWarning: Error: EPERM: operation not permitted, lstat 'C:\Users\LIUXIU~1\AppData\Local\Temp\electron-download-CEvWd4\electron-v7.1.7-win32-x64.zip'
(node:10024) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting
a promise which was not handled with .catch(). (rejection id: 1)
(node:10024) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

嗯?怎麼沒有權限?趕緊用管理員權限打開命令行,運行上面的命令,還是一樣的報錯。。
繼續輸入命令 npm config ls -l ,輸出以下內容

tmp = "C:\\Users\\admin\\AppData\\Local\\Temp"

tmp爲npm安裝模塊時的臨時目錄,若該目錄有權限問題,則npm在安裝其他模塊時,也會報出operation not permitted錯誤,npm可正常安裝其他模塊,故可排除目錄權限的問題
讓我們仔細看下代碼

downloadArtifact({
  version,
  artifactName: 'electron',
  force: process.env.force_no_cache === 'true',
  cacheRoot: process.env.electron_config_cache,
  platform: process.env.npm_config_platform || process.platform,
  arch: process.env.npm_config_arch || process.arch
}).then((zipPath) => extractFile(zipPath)).catch((err) => onerror(err))

可以看到如下下載異常會拋出錯誤,繼續看 downloadArtifact這個方法,可以看到有個輸出url的地方

function downloadArtifact(_artifactDetails) {
    return __awaiter(this, void 0, void 0, function () {
        var artifactDetails, fileName, url, cache, cachedPath;
        var _this = this;
        return __generator(this, function (_a) {
            switch (_a.label) {
                case 0:
                    artifactDetails = _artifactDetails.isGeneric
                        ? __assign({}, _artifactDetails) : __assign({ platform: process.platform, arch: utils_1.getHostArch() }, _artifactDetails);
                    utils_1.ensureIsTruthyString(artifactDetails, 'version');
                    artifactDetails.version = utils_1.normalizeVersion(artifactDetails.version);
                    fileName = artifact_utils_1.getArtifactFileName(artifactDetails);
                    url = artifact_utils_1.getArtifactRemoteURL(artifactDetails);
                    cache = new Cache_1.Cache(artifactDetails.cacheRoot);
                    if (!!artifactDetails.force) return [3 /*break*/, 2];
                    d("Checking the cache for " + fileName + " (" + url + ")");
                    return [4 /*yield*/, cache.getPathForFileInCache(url, fileName)];

把這裏的url輸出看看,url值如下

https://github.com/electron/electron/releases/download/v7.1.7/electron-v7.1.7-win32-x64.zip

把這個url放到瀏覽器回車,發現國內從github上下載東西極慢,所以之前npm i 的時候,就會一直卡在electron執行node install.js那裏,最後因爲超時導致安裝依賴失敗,現在我們可以設置下環境變量改變這個url,可以看@electron/get/dist/cjs/artifact-utils.js文件中的url的值會取環境變量的值

function mirrorVar(name, options, defaultValue) {
    // Convert camelCase to camel_case for env var reading
    var lowerName = name.replace(/([a-z])([A-Z])/g, function (_, a, b) { return a + "_" + b; }).toLowerCase();
    return (process.env["NPM_CONFIG_ELECTRON_" + lowerName.toUpperCase()] ||
        process.env["npm_config_electron_" + lowerName] ||
        process.env["npm_package_config_electron_" + lowerName] ||
        process.env["ELECTRON_" + lowerName.toUpperCase()] ||
        options[name] ||
        defaultValue);
}
function getArtifactRemoteURL(details) {
    var opts = details.mirrorOptions || {};
    var base = mirrorVar('mirror', opts, BASE_URL);
    if (details.version.includes('nightly')) {
        base = mirrorVar('nightly_mirror', opts, NIGHTLY_BASE_URL);
    }
    var path = mirrorVar('customDir', opts, details.version);
    var file = mirrorVar('customFilename', opts, getArtifactFileName(details));
    return "" + base + path + "/" + file;
}

在 electron-quick-start/package.json 的script中加上

"install": "set ELECTRON_MIRROR=http://npm.taobao.org/mirrors/electron/&& node ./node_modules/electron/install.js",

運行npm run install,還是報錯,現在url輸出的是
https://npm.taobao.org/mirrors/electron/v7.1.7/electron-v7.1.7-win32-x64.zip
在瀏覽器打開,果然是404,這個url往前面幾級翻一下,發現https://npm.taobao.org/mirrors/electron是可以訪問的,原來淘寶鏡像上electron下的資源版本號前面都沒有v,所以我們要把url改爲https://npm.taobao.org/mirrors/electron/7.1.7/electron-v7.1.7-win32-x64.zip可以下載zip包,要解決這個問題需要改下代碼,在@electron/get/dist/cjs/artifact-utils.js文件的getArtifactRemoteURL方法中path後面添加一句

path = path.replace("v","");

重新運行npm run install,成功安裝~
運行npm run start,成功啓動electron應用~

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章