如何将 Babel 与 Electron 一起使用?

Posted

技术标签:

【中文标题】如何将 Babel 与 Electron 一起使用?【英文标题】:How do I use Babel with Electron? 【发布时间】:2021-03-30 12:13:21 【问题描述】:

我想用 ES6 导入语法构建一个 Electron 应用程序,这样我就可以在我的 Node.js 和浏览器端 JS 之间重用模块而无需重复代码,我发现 Electron 在 ES6 语法支持方面落后于时代令人沮丧。

我了解了this magical solution,却发现它已不再维护。

所以巴别塔来救援了,至少我是这么想的。 Google 在 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 模块,这似乎不以传统方式导出,解析电子可执行路径(字符串)而不是 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'
  

我意识到这可能是因为“电子”。在解析管道中做了一些特别的事情。但我肯定听说过 Babel 是在 Electron 中使用 ES6 导入语法的解决方案,我只是找不到关于这样做的实际指南。那么如何将 Babel 与 Electron 一起使用呢?

【问题讨论】:

IIRC 在电子锻造失败后,我切换到了电子反应样板。我在上面叠加了一堆东西,但它解决了眼前的问题——它可能不是你想要的,但它肯定是一个很好的起点。 @DaveNewton 感谢您提供的知识,但如果我必须在项目中使用一个名为 electron-react-boilerplate 的模块而不只是使用 ES6 导入语法做出反应,我可能只是在汇编中编写应用程序。我会经历同样多的时间/麻烦,并为自己保住一些尊严。 @J.Todd 有趣,但不真实 :) 正如我所说,我的观点是理解设置是一个很好的起点,因为它使用 ES6。也许只是拉出与 React 相关的东西。 Webpack 在使用 javascript 或 typescript 的电子项目中非常适合我。可能值得一看。 【参考方案1】:

我认为问题在于您对babel-node 的使用。 babel-node 是一个 node cli 克隆,它在执行 JS 代码之前进行 babel 转换。它不是编译器。没有为此 cli 定义 --out-file 标志。很遗憾,它没有警告您使用无法识别的标志。

为了编译你的 ES6 文件,你需要使用babel cli。在您的 compile 任务中将 babel-node 替换为 babel 应该可以解决问题。

您还需要将导入替换为import * as ... from ... 语法:

import * as url from 'url'
import * as path from 'path'

您还可以查看 Electron 12 的预览。它们支持支持 ES 模块的 Node 14。所以当 Electron 12 出来时,理论上应该可以不用 Babel 使用 ES 模块。

【讨论】:

以上是关于如何将 Babel 与 Electron 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Prisma 与 Electron 一起使用

如何将 Material UI 与 Electron React 样板一起使用?

最后如何将新的 babel-plugin-relay 与 Relay Classic 一起使用?

如何将 jest 与 coffeescript 和 ES6/ES2015 一起使用(例如通过 Babel)?

如何让 React 与 Grunt 和 Babel 一起工作?

如何将第三方二进制文件与 Electron 捆绑在一起?