Electron 编译问题记录
在开发桌面客户端时,我们选用electron框架结合react,在实际开发中遇到语法转换问题,记录如下。
* Electron: 跨屏客户端框架
* Electron Forge: 配套模板工具,支持发行包生成,如OSX下的dmg
* React: 前端页面框架
* Babel: ES6语法转换
高级语法转换失败
通过electron forge创建的模板工程可以正常运行,但是如果你尝试写一些新的高级语法,比如类成员定义:
import React from 'react';
export default class App extends React.Component {
testFiled = ()=>{
console.log('test func')
}
render() {
this.testFiled()
return (<div>
<h2>Welcome to React!</h2>
</div>);
}
}
这段代码中,我们定义了一个Component,并且添加了一个日志方法,没有什么实际含义,如果运行electron-forge start
那么会得到错误提示:
错误排查
根据electron forge
的项目说明,这显得很奇怪。
https://github.com/electron-userland/electron-forge
在项目首页找一下线上,可以看到这么一段话:
# How do I use this with webpack/babel/typescript/random build tool?
As of Electron Forge 6+ by default we only do vanilla JavaScript but if you want to do some fancy build tool stuff you should check out the plugins section of our docs site. We currently have plugins for Webpack, Parcel and Electron Compile.
实际上6+以上的版本在创建的模板工程并不能很好的支持js的最新语法,但是我门希望仍然用向对象的语法来编写工程。查看工程项目中使用的electron forge
版本,是5.2.2
。我们需要继续查看这个版本新官方是怎么建议的https://github.com/electron-userland/electron-forge/tree/v5.2.2:
# Project Goals
1. Starting with Electron should be as simple as a single command.
2. Developers shouldn't have to worry about babel, browserify, webpack, native module rebuilding, etc. Everything should "just work" for them out of the box.
3. Everything from creating the project to packaging the project for release should be handled by one dependency in a standard way while still offering users maximum choice and freedom.
在老版本的说明中,提到了不需要单独配置便可以工作起来,这显然和我们遇到的实际情况不同。现在只能查询package.json中的依赖配置和babel官方说明来解决问题,打开配置,可以看到默认配置了以下几个babel库
我们看下这几个库的作用:
- babel-plugin-transform-async-to-generator:async/await语法转换,详见https://babeljs.io/docs/en/6.26.3/babel-plugin-transform-async-to-generator
- babel-plugin-transform-es2015-classes: 类继承语法,详见https://babeljs.io/docs/en/6.26.3/babel-plugin-transform-es2015-classes
- babel-preset-env: 用于替换
babel-preset-latest (or babel-preset-es2015, babel-preset-es2016, and babel-preset-es2017 together).
这些老写法的,详见https://babeljs.io/docs/en/6.26.3/babel-preset-env - babel-preset-react: 支持react,比如jsx转义,详见https://babeljs.io/docs/en/6.26.3/babel-preset-react
新增babel依赖库
babel的plugin非常多,依赖关系也比较复杂,从我们的日志来看,缺少的是类成员的语法转换,这个本事是一个高级羽凡,因此我们需要找到对应的plugin:
- babel-plugin-transform-class-properties: 处于实现性质的高级语法,详见https://babeljs.io/docs/en/6.26.3/babel-plugin-transform-class-properties 同时我们将stage调整为stage-0
目前babel已经迭代到v7.x版本,项目中使用的是6.x,因此新增依赖库也需要查阅对应版本下的说明文档,避免版本兼不兼容问题,这个也是是错中的教训。
配置babelrc
添加完依赖之后,我们还需要做一下配置
动态加载import
为了支持动态加载,我们也需要引入相应的插件,这个插件有两个分别是babel提供的babel-plugin-syntax-dynamic-import
和airbnd提供的babel-plugin-dynamic-import-node
笔者这里使用Airbnb的可以正常加载动态页面。