所用工具介绍

阅读源码的过程中,遇到了很多工具包,都不知道是干什么的,以至于读起来挺吃力的,所以以下就是随手查随手记的。

作用 简例 参考链接
node-pty 用在terminal中,把UTF-16/UCS-2的内容解析为UTF-8编码的内容,让系统能看得懂 ```javascript

pty.onData(recv => terminal.write(recv)); terminal.onData(send => pty.write(send));

  1. | [https://juejin.cn/post/6918911964009725959](https://juejin.cn/post/6918911964009725959) |
  2. | nsfw | not suitable for work,是LinuxWindowsOSX文件监视服务的本机抽象,一般用于鉴黄 | | |
  3. | spdlog | C++日志输出库 | | |
  4. | [@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
  5. import { IDialogService } from '@opensumi/ide-overlay';
  6. @Injectable()
  7. class DemoService {
  8. @Autowired(IDialogService)
  9. private readonly dialogService: IDialogService;
  10. run() {
  11. this.dialogService.info('Hello OpenSumi');
  12. }
  13. }

| 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! }); });

  1. | |
  2. <a name="flOZN"></a>
  3. ## 代码运行顺序(core版本)
  4. npm run start => ./scripts/start (rebuilding modules) => 进入packages/startup 运行npm run start => 即命令运行start:client:open start:server start:webview => 分别运行startup/entry/app.tsxserver.tswebpack.webview.js => render-app.tsx中定义renderApp,其中运行app = new ClientApp(opts);app.start(...)
  5. <a name="cn7IL"></a>
  6. ## 零散笔记
  7. 默认webpack配置,core/tools/dev-tool/src/webpack.js,可配HostPortdefaultWorkspaceEXTENSION_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=)
  8. <a name="VzK0S"></a>
  9. ## 生命周期
  10. ```javascript
  11. const app = new ClientAPP(/*..options*/);
  12. app.start();

�start 方法的流程比较简单直观,它主要负责以下工作:

  • 创建前后端连接,对于 Web ,将使用 Websocket,对于 Electron 端,则使用 IPC 通信
  • 初始化 ApplicationService, 用于缓存一些系统级的状态,如当前 OpenSumi 后端运行的 OS 等
  • 执行所有的 贡献点
    • initialize
    • onStart
    • onDidStart
  • 渲染主界面

这里的 Contributions 实际上就是一系列的生命周期方法,它们通过 Contributions 机制中的 ClientAppContribution 串联起来,会在 OpenSumi 运行过程中不同阶段调用。除了上述 start 中的生命周期方法之外,还有关闭窗口、连接变化等相关的方法。
image.png

initialize

在packages/core-browser/src/bootstrap/app.ts中,定义了initializeContributions()这个方法,可以在生成ClientApp实例的时候去定义app.appInitialized这个函数。目前定义后会执行,但会渲染不出页面,所以暂时无用。

renderApp

在此阶段前,加入postMessage取参模块,在packages/startup/entry/web/app.tsx中,在renderApp之前,去读取参数(readOnly),根据参数以改变渲染app的参数opts。

  1. // 在packages/startup/entry/web/app.tsx中去监听message,并根据参数调整页面配置
  2. window.addEventListener ('message', (event) => {
  3. if (event.origin === 'http://172.16.205.219:3000') {
  4. // eslint-disable-next-line no-console
  5. console.log ('event.origin', event.origin);
  6. // eslint-disable-next-line no-console
  7. console.log ('event.data', event.data);
  8. if (event.data.readOnly) {
  9. // eslint-disable-next-line no-console
  10. console.log ('yes read only');
  11. renderAppOpts = {
  12. modules: [...ReadOnlyCommonBrowserModules, ExpressFileServerModule, SampleModule, RemoteOpenerModule],
  13. layoutConfig: {
  14. ...defaultConfig,
  15. ...{
  16. [SlotLocation.top]: {
  17. modules: ['@opensumi/menu-bar-example', 'toolbar'],
  18. },
  19. },
  20. ...{
  21. [SlotLocation.action]: {
  22. modules: ['@opensumi/ide-toolbar-action'],
  23. },
  24. },
  25. },
  26. useCdnIcon: true,
  27. useExperimentalShadowDom: true,
  28. defaultPreferences: {
  29. 'general.theme': 'opensumi-dark',
  30. 'general.icon': 'vscode-icons',
  31. 'application.confirmExit': 'never',
  32. 'editor.quickSuggestionsDelay': 100,
  33. 'editor.forceReadOnly': true,
  34. },
  35. };
  36. renderApp (renderAppOpts);
  37. }
  38. }
  39. }, 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中,

  1. this.connectionPath = connectionPath || `${this.config.wsPath}/service`;