所用工具介绍
阅读源码的过程中,遇到了很多工具包,都不知道是干什么的,以至于读起来挺吃力的,所以以下就是随手查随手记的。
作用 | 简例 | 参考链接 | |
---|---|---|---|
node-pty | 用在terminal中,把UTF-16/UCS-2的内容解析为UTF-8编码的内容,让系统能看得懂 | ```javascript |
pty.onData(recv => terminal.write(recv)); terminal.onData(send => pty.write(send));
| [https://juejin.cn/post/6918911964009725959](https://juejin.cn/post/6918911964009725959) |
| nsfw | not suitable for work,是Linux、Windows和OSX文件监视服务的本机抽象,一般用于鉴黄 | | |
| spdlog | C++日志输出库 | | |
| [@opensumi/di](https://web.npm.alibaba-inc.com/package/@opensumi/di) | 基于 Angular DI 的设计自行实现的一个依赖注入的工具,[https://angular.io/guide/dependency-injection](https://angular.io/guide/dependency-injection%E3%80%82) | 在依赖注入的编码模式下,我们如果想使用一个模块内的服务,不再需要依赖其具体实现,而只需要依赖其显示声明的 Token 即可。<br />以在模块中使用弹窗服务能力 IDialogService 为例:```javascript
import { IDialogService } from '@opensumi/ide-overlay';
@Injectable()
class DemoService {
@Autowired(IDialogService)
private readonly dialogService: IDialogService;
run() {
this.dialogService.info('Hello OpenSumi');
}
}
| https://opensumi.com/zh/docs/develop/basic-design/dependence-injector | | browserfs | BrowserFS 是一个浏览器内文件系统,它模拟Node JS 文件系统 API,并支持从各种后端存储和检索文件。 | 以下代码将 zip 文件挂载到/zip,将内存存储挂载到/tmp,将IndexedDB 浏览器本地存储挂载到/home:```javascript // Note: This is the new fetch API in the browser. You can use XHR too. fetch(‘mydata.zip’).then(function(response) { return response.arraybuffer(); }).then(function(zipData) { var Buffer = BrowserFS.BFSRequire(‘buffer’).Buffer;
BrowserFS.configure({ fs: “MountableFileSystem”, options: { “/zip”: { fs: “ZipFS”, options: { // Wrap as Buffer object. zipData: Buffer.from(zipData) } }, “/tmp”: { fs: “InMemory” }, “/home”: { fs: “IndexedDB” } } }, function(e) { if (e) { // An error occurred. throw e; } // Otherwise, BrowserFS is ready to use! }); });
| |
<a name="flOZN"></a>
## 代码运行顺序(core版本)
npm run start => ./scripts/start (rebuilding modules) => 进入packages/startup 运行npm run start => 即命令运行start:client:open start:server start:webview => 分别运行startup/entry/app.tsx、server.ts、webpack.webview.js => render-app.tsx中定义renderApp,其中运行app = new ClientApp(opts);app.start(...)
<a name="cn7IL"></a>
## 零散笔记
默认webpack配置,core/tools/dev-tool/src/webpack.js,可配Host,Port,defaultWorkspace,EXTENSION_DIR<br />下图为各个模块的前端Model的名字,只要在packages/startup/src/browser/common-modules.ts中注释掉对应的模块就会消失。<br />![截屏2022-04-14 12.00.32.png](https://cdn.nlark.com/yuque/0/2022/png/912821/1649916308227-ab550177-643f-4acf-a0cf-6fec0a6b1d1f.png#clientId=u6f51876f-d4d4-4&crop=0&crop=0&crop=1&crop=1&from=drop&id=ua081e5e6&margin=%5Bobject%20Object%5D&name=%E6%88%AA%E5%B1%8F2022-04-14%2012.00.32.png&originHeight=528&originWidth=614&originalType=binary&ratio=1&rotation=0&showTitle=false&size=91855&status=done&style=none&taskId=u72e552f7-00cf-4bbb-87c5-995d7671b62&title=)
<a name="VzK0S"></a>
## 生命周期
```javascript
const app = new ClientAPP(/*..options*/);
app.start();
�start 方法的流程比较简单直观,它主要负责以下工作:
- 创建前后端连接,对于 Web ,将使用 Websocket,对于 Electron 端,则使用 IPC 通信
- 初始化 ApplicationService, 用于缓存一些系统级的状态,如当前 OpenSumi 后端运行的 OS 等
- 执行所有的 贡献点
- initialize
- onStart
- onDidStart
- 渲染主界面
这里的 Contributions 实际上就是一系列的生命周期方法,它们通过 Contributions 机制中的 ClientAppContribution 串联起来,会在 OpenSumi 运行过程中不同阶段调用。除了上述 start 中的生命周期方法之外,还有关闭窗口、连接变化等相关的方法。
initialize
在packages/core-browser/src/bootstrap/app.ts中,定义了initializeContributions()这个方法,可以在生成ClientApp实例的时候去定义app.appInitialized这个函数。目前定义后会执行,但会渲染不出页面,所以暂时无用。
renderApp
在此阶段前,加入postMessage取参模块,在packages/startup/entry/web/app.tsx中,在renderApp之前,去读取参数(readOnly),根据参数以改变渲染app的参数opts。
// 在packages/startup/entry/web/app.tsx中去监听message,并根据参数调整页面配置
window.addEventListener ('message', (event) => {
if (event.origin === 'http://172.16.205.219:3000') {
// eslint-disable-next-line no-console
console.log ('event.origin', event.origin);
// eslint-disable-next-line no-console
console.log ('event.data', event.data);
if (event.data.readOnly) {
// eslint-disable-next-line no-console
console.log ('yes read only');
renderAppOpts = {
modules: [...ReadOnlyCommonBrowserModules, ExpressFileServerModule, SampleModule, RemoteOpenerModule],
layoutConfig: {
...defaultConfig,
...{
[SlotLocation.top]: {
modules: ['@opensumi/menu-bar-example', 'toolbar'],
},
},
...{
[SlotLocation.action]: {
modules: ['@opensumi/ide-toolbar-action'],
},
},
},
useCdnIcon: true,
useExperimentalShadowDom: true,
defaultPreferences: {
'general.theme': 'opensumi-dark',
'general.icon': 'vscode-icons',
'application.confirmExit': 'never',
'editor.quickSuggestionsDelay': 100,
'editor.forceReadOnly': true,
},
};
renderApp (renderAppOpts);
}
}
}, false);
默认配置
对于全局配置,我们一般是从 ~/.sumi/settings.json 文件中读取;
针对工作区的配置文件,我们一般是从 ${worksace_path}/.sumi/settings.json 文件中读取,但在存在多个工作区存在的多工作区 项目,我们则是从 ${workspace_name}.sumi-workspace 文件中读取;
自定义集成参数
在集成 OpenSumi 框架的时候,我们往往需要进行独立的配置,下面列举了一些可在集成阶段通过传入配置项进行配置的参数:
Browser 配置
定义可见 @opensumi/ide-core-browser 中的 AppConfig 定义。
参数 | 参数说明 | 默认值 |
---|---|---|
appName | 客户端的唯一名称,一般在客户端启动时的标题展示使用,同时也作为插件进程输出的客户端名称 | OpenSumi |
defaultPreferences | 对客户端的整体配置进行初始化定义,常见的自定义参数如:颜色主题:general.theme、图标主题:general.icon、语言:general.language、排除文件选项:filesExclude、排除文件监听选项:watchExclude 等等,理论上可针对所有 IDE 中定义的配置进行默认值设置 | 无 |
extensionCandidate | 额外指定的插件路径,一般用于内置插件 | 无 |
preferenceDirName | 设置工作区配置文件的文件夹名称,对于集成环境,我们更推荐使用 workspacePreferenceDirName 和 userPreferenceDirName 进行更加精细的配置存储文件夹名称配置 | .sumi |
injector | 初始化的 DI 实例,一般可在外部进行 DI 初始化之后传入,便于提前进行一些依赖的初始化 | 无 |
websocket配置
在core/packages/core-browser/src/bootstrap/app.ts中,
this.connectionPath = connectionPath || `${this.config.wsPath}/service`;