一.Electron基本结构
VS Code作为Electron的成功案例,一头扎进源码之前,有必要简单梳理下Electron的基本结构
从实现上来看:
Electron = Node.js + Chromium + Native API
也就是说Electron拥有Node运行环境,依靠Chromium提供基于Web技术(HTML、CSS、JS)的界面交互支持,另外还具有一些平台特性,比如桌面通知
从API设计上来看,Electron App一般都有1个Main Process和多个Renderer Process:
main process:主进程环境下可以访问Node及Native API
renderer process:渲染器进程环境下可以访问Browser API和Node API及一部分Native API
API设计如此,那么Electron App的项目结构也至少包括这两部分内容
主进程
相当于后台服务,常用于:
多窗体管理(创建/切换)
应用生命周期管理
作为进程通信基站(IPC Server)
自动更新
工具条菜单栏注册
渲染器进程
界面交互相关的,具体的业务功能,都由renderer进程来做,3个基本原则:
尽量用renderer干活,包括网络请求
太耗时的用Worker拆出去
需要跨renderer共享的用子进程拆出去,交由main管理
You can use all packages that work with Node.js in the main process as well as in the renderer process if you have webPreferences.nodeIntegration set to true in the BrowserWindow options. This is the default.
It’s actually recommended to do as much as possible in the renderer process.
二.vscode源码结构
以下内容参考源码版本为v1.19.3
目录结构
├── build # gulp编译构建脚本
├── extensions # 内置插件
├── gulpfile.js # gulp task
├── i18n # 国际化翻译包
├── out # 编译输出目录
├── product.json # App meta信息
├── resources # 平台相关静态资源,图标等
├── scripts # 工具脚本,开发/测试
├── src # 源码目录
└── test # 测试套件
src下的结构如下:
├── bootstrap-amd.js # 子进程实际入口
├── bootstrap.js # 子进程环境初始化
├── buildfile.js # 构建config
├── cli.js # CLI入口
├── main.js # 主进程入口
├── paths.js # AppDataPath与DefaultUserDataPath
├── typings
│ └── xxx.d.ts # ts类型声明
└── vs
├── base # 通用工具/协议和UI库
│ ├── browser # 基础UI组件,DOM操作、交互事件、DnD等
│ ├── common # diff描述,markdown解析器,worker协议,各种工具函数
│ ├── node # Node工具函数
│ ├── parts # IPC协议(Electron、Node),quickopen、tree组件
│ ├── test # base单测用例
│ └── worker # Worker factory和main Worker(运行IDE Core:Monaco)
├── buildunit.json
├── code # VS Code主窗体相关
├── css.build.js # 用于插件构建的CSS loader
├── css.js # CSS loader
├── editor # 对接IDE Core(读取编辑/交互状态),提供命令、上下文菜单、hover、snippet等支持
├── loader.js # AMD loader(用于异步加载AMD模块,类似于require.js)
├── nls.build.js # 用于插件构建的NLS loader
├── nls.js # NLS(National Language Support)多语言loader
├── platform # 支持注入服务和平台相关基础服务(文件、剪切板、窗体、状态栏)
└── workbench # 协调editor并给viewlets提供框架,比如目录查看器、状态栏等,全局搜索,集成Git、Debug
其中最关键的部分(业务相关的)是:
src/vs/code:主窗体、工具栏菜单创建
src/vs/editor:代码编辑器,IDE核心相关
src/vs/workbench:UI布局,功能服务对接
P.S.IDE Core可独立使用,叫Monaco
每层按目标执行环境细分组织:
common:可跨环境复用的
browser:依赖浏览器API的,比如DOM操作
node:依赖Node API的
三.启动流程
启动流程相关文件递进关系如下:
功能入口
src/main.js
src/vs/code/electron-main/main.ts
src/vs/code/electron-main/app.ts
src/vs/code/electron-main/windows.ts
src/vs/code/electron-main/window.ts
UI入口
src/vs/workbench/electron-browser/bootstrap/index.html
src/vs/workbench/electron-browser/bootstrap/index.js
src/vs/workbench/workbench.main js index文件
src/vs/workbench/electron-browser/main.ts
src/vs/workbench/electron-browser/shell.ts 界面与功能服务的接入点
src/vs/workbench/electron-browser/workbench.ts 创建界面
src/vs/workbench/browser/layout.ts 布局计算,绝对定位
Electron CLI启动应用
启动步骤:
# 编译构建(ts转换,打包)
npm run compile
# 通过Electron启动应用
./scripts/code.sh
code.sh的作用类似于Electron Demo中常见的:
"name": "electron-quick-start",
"version": "1.0.0",
"description": "A minimal Electron application",
"main": "main.js",
"scripts": {
"start": "electron ."
}
主要部分如下:
# Configuration
export NODE_ENV=development
export VSCODE_DEV=1
export VSCODE_CLI=1
export ELECTRON_ENABLE_LOGGING=1
export ELECTRON_ENABLE_STACK_DUMPING=1
# Launch Code
exec "$CODE" . "$@"
配置dev环境变量,最后通过exec执行:
./.build/electron/Code - OSS.app/Contents/MacOS/Electron .
Electron CLI会把pkg.main作为入口文件去加载执行:
"name": "code-oss-dev",
"version": "1.19.3",
"distro":