如何在Electron中使用Babel?

5
我想用ES6的import语法来构建Electron应用程序,这样我就可以在Node.js和浏览器端JS之间重复使用模块而不会出现代码重复问题。但是我发现,Electron在支持ES6语法方面严重滞后。
我了解到这个神奇的解决方案,点击这里去看,结果发现它已经不再维护了。
因此,我想到了Babel。然而,关于Babel + Electron的教程并不多见。我还想加入Nodemon。
以下是我的设置: package.json
{
  "name": "infinitum",
  "version": "1.0.0",
  "description": "",
  "main": "compiled.js",
  "directories": {
    "test": "tests"
  },
  "scripts": {
    "start": " electron .",
    "compile": "nodemon --exec babel-node app.js --out-file compiled.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.12.10",
    "@babel/node": "^7.12.10",
    "@babel/preset-env": "^7.12.11",
    "electron": "^11.1.0",
    "nodemon": "^2.0.6"
  }
}

正如您将在以下的输出和调试日志中看到的那样,这里的问题在于我们试图编译使用ES6语法的节点模块,但任何Electron应用都依赖于Electron模块,后者似乎不是以传统的方式导出,而是解决了electron可执行路径(字符串),而不是一个Node.js模块。这是一个循环问题。
app.js
import {app, BrowserWindow} from 'electron'
import 'url'
import 'path'

let win

function createWindow() {
   win = new BrowserWindow({width: 800, height: 600})
   win.loadURL(url.format ({
      pathname: path.join(__dirname, 'index.html'),
      protocol: 'file:',
      slashes: true
   }))
}

app.on('ready', createWindow)
.babelrc文件
{
  "presets": [
    "@babel/preset-env"
  ]
}

我正在运行:

npm run compile

导致错误的原因是:

C:\Users\jonat\documents\github\infinitum\app.js:23
_electron.app.on('ready', createWindow);
              ^

TypeError: Cannot read property 'on' of undefined
    at Object.<anonymous> (C:\Users\jonat\documents\github\infinitum\/app.js:16:5)
    at Module._compile (internal/modules/cjs/loader.js:1076:30)
    at Module._compile (C:\Users\jonat\Documents\GitHub\infinitum\node_modules\pirates\lib\index.js:99:24)
    at Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
    at Object.newLoader [as .js] (C:\Users\jonat\Documents\GitHub\infinitum\node_modules\pirates\lib\index.js:104:7)
    at Module.load (internal/modules/cjs/loader.js:941:32)
    at Function.Module._load (internal/modules/cjs/loader.js:782:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at Object.<anonymous> (C:\Users\jonat\Documents\GitHub\infinitum\node_modules\@babel\node\lib\_babel-node.js:172:21)
    at Module._compile (internal/modules/cjs/loader.js:1076:30)

所以为了调试,我尝试了这个app.js
import electron from 'electron'
console.log("typeof electron:", typeof electron, "\nelectron:", electron)

输出:

typeof electron: string
electron: C:\Users\jonat\documents\github\infinitum\node_modules\electron\dist\electron.exe

而进一步的澄清,像这样的app.js:
import * as name from 'electron'
console.log({ name })

日志:

{
  name: {
    default: 'C:\\Users\\jonat\\documents\\github\\infinitum\\node_modules\\electron\\dist\\electron.exe'
  }
}

我意识到这可能是因为“electron .”在解析流水线中有特殊作用。但我确实听说过Babel是在Electron中使用ES6导入语法的解决方案,只是找不到实际操作指南。那么我该如何在Electron中使用Babel?


我记得我在遭遇electron-forge问题后切换到了electron-react-boilerplate。我在其基础上添加了一堆东西,但它解决了眼前的问题——也许不是你要找的,但肯定是一个很好的起点。 - Dave Newton
@DaveNewton 感谢您的知识分享,但是如果我必须在没有 React 的项目中使用一个名为 electron-react-boilerplate 的模块,仅仅为了使用 ES6 的 import 语法,那么我宁愿用汇编语言编写应用程序。这样我将会花费同样的时间和精力,同时也能保留一些尊严。 - J.Todd
@J.Todd 很有趣,但不是真的 :) 我的观点,正如我所说,是这是一个很好的起点来理解设置,因为它使用了ES6。也许只需删除与React相关的内容。 - Dave Newton
Webpack在使用JavaScript或TypeScript的Electron项目中表现良好。值得一试。 - Rhayene
1个回答

3
我认为问题出在你对babel-node的使用上。 babel-node是一个 node 命令行克隆工具,在执行JS代码前会进行Babel转换。它不是一个编译器,此命令行界面未定义--out-file标志。很遗憾,它没有警告您正在使用一个未被识别的标志。
为了编译您的ES6文件,您需要使用babel命令行界面。将compile任务中的babel-node替换为babel即可解决问题。
此外,您需要将导入语句替换为import * as ... from ...语法。
import * as url from 'url'
import * as path from 'path'

你也可以查看Electron 12的预览版。它们支持Node 14,而Node 14支持ES模块。因此,当Electron 12发布时,理论上可以使用ES模块而无需使用Babel。


看起来 Electron 还没有添加 ES 支持。现在我们已经更新到 21 版本了,但我还在使用第 17 版本。 - bdotsamir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接