likes
comments
collection
share

theia的第一个拓展-Hello World

作者站长头像
站长
· 阅读数 21

前言

本篇文章是本人对theia中Hello World的理解,其实更像是导读,分为工作前提、创建项目、项目导读、工作区四个部分辅助阅读(保姆级别)。

工作前提

如果不喜欢看我墨迹,可以查看官方文档提供的工作前提 ,这也是最好的解决办法。

  1. 需要安装 theia
  2. 需要安装 nodejs 环境(当前是 v16.15.1)
  3. 需要安装 node-gyp 环境(当前是v9.1.0)
  4. 需要安装 Python3.6 或者其以上的版本
  5. 需要安装 visual studio 并且安装 使用C++的桌面开发 一项
  6. 需要安装 yarn 因为在官方中说明,yarn允许将 monorepos(包含多个npm包的存储库)构建到工作区中
  7. 需要安装 theia 插件开发的脚手架,npm install -g yo generator-theia-extension
  8. (额外补充说明):官方推荐 使用 scoop 作为包管理工具,并且如果有多个node版本的话 推荐使用 nvm 进行管理

开始构建

注意!本次的所有操作,上面的工作前提一定要做好,并且都应该把vpn关闭掉,因为会涉及安装失败问题,如果察觉到存在VPN,那么就会存在安装失败的问题!并且注意保证目录文件格式规范,例如:路径不能是中文、不能有间隔等,否则webpack在构建时会出问题

  1. 使用 yo theia-extension 启动项目,选择 Hello World 作为模板进行项目的初始化搭建。

theia的第一个拓展-Hello World

那么就会内部的生成器就会生成相关的项目架构,这个过程估计是一杯茶的时间了~
  1. 项目创建成功会在命令行中显示四个success提示

theia的第一个拓展-Hello World

这时候说明你的项目已经成功创建完毕,这时候会得到5个文件夹以及5个文件

theia的第一个拓展-Hello World

3.在官方文档 中指示出的重点文件就是,位于文件夹根目录中 package.json 文件,其中比较重要的就是这个文件中定义的工作区(workspaces),一共定义了三个工作区分别是'hello world', 'browser-app', 'electron-app',与左侧的创建的工程中的文件一一对应。注意!工作区对于后面的执行有很大的关系!!!

theia的第一个拓展-Hello World

hello-world文件夹

在这个文件中,书写我们需要拓展帮我们实现的代码,打开 /src/browser,可以看到有两个分别以指令名-contribution.ts指令名-frontend-module.ts文件(本篇文章的指令名是hello-world),进入文件中去,如果没有IOC-控制反转ID-依赖注入的思想的话,这代码可能就读起来有点吃力了,因为这并不是很存粹的TS代码,theia使用了inversifyJS这一个框架来实现依赖注入,如果你没有这方面的很强烈推荐阅读,并且读懂官方提供的示例。

hello-world-contribution.ts文件

我试着解读这里面的代码。这个hello-world的demo,只用到了inversifyJS中的injectableinjectContainerModule这三个API,其实extension的实现无非就是实现-注册-暴露这三步骤,这个文件中做的就是实现以及暴露,因为就只是简单的hellowrld代码,所以并没有把实现的代码封装出去。

@injectable()

@injectable装饰器的作用是,当我们的定义的接口被实现成类时,那么就可以使用@injectable()进行注释,简单理解就是会被inversifyJS收集起来,我们不需要知道inversifyJS底层是怎么实现的,只需要知道,每当我们需要获取时,就会返回这个函数的实例对象。

@inject()

当一个类依赖于一个接口/类时(因为在TS中定义了类其实也会隐式创建对应的接口),我们需要使用@inject装饰器来定义一个在运行时可用的接口标识符,在本篇的hello world中,这个标识不是inversifyJS给的只是一个Symbol值那么简单,它注入的是一个实例对象。我们依旧不知道inversifyJS底层是怎么实现的,也不需要关心它什么时候帮我们new的对象。

theia的第一个拓展-Hello World

因为只是一个Hello World的简单例子,所以代码解读就是创建一个HelloWorld.command的指令,并且在HelloWorldCommandContribute注册指令,在用户点击Edit菜单后,会显示出一个Say Hello的一项,用户点击时就会执行this.messageService.info('Hello World!')这段代码。

hello-world-frontend-module.ts文件

这个文件的主要使用的类就是ContainerModuleContainerModule这个类,其实是方便我们把业务分成各个模块进行导出的,如果开发的项目比较大时,可以是用这个方法进行有效管理,因为如果全部的绑定都在Contaniner中进行绑定时,就会显得十分臃肿。

ContainerModule这个类中只有一个参数就是回调函数,回调函数中却又若干个形参,这里主要使用的就是bind参数,bind回调函数会根据传入的标识符生成一个被绑定的对象,这个对象会被放进到ContainerModule中。to回调函数会接受一个类,进而进行绑定。可以抽象理解为以下,仅供入门参考,但是事实上它实现起来与WeakMap更相似。

  containers: {
     hello-world-frontend-module: {
         // 指令
         CommandContribution: {
             HelloWorldCommandContribution: {
                 registerCommands(...): void ...
             },
             ... // 如果有更多
         },
         // 菜单
         MenuContribution: {
             HelloWorldMenuContribution: {
                 registerMenus(...): void ...
             },
             ... // 如果有更多
         }
     },
     other-frontend-module: {
         ...
     },
     ...
  }

那么当执行代码后,theia就会根据你暴露的绑定,执行相关的命令,在这个例子中可以简单分解成两部分理解,用户点击Edit按钮列表中,系统会增加一个选项,叫做Say Hello,这一步相当于系统执行了MenuContribution中的HelloWorldMenuContribution类中的代码,然后点击Say Hello按钮,那么就会在右下角弹出一个信息窗口,显示Hello World,因为HelloWorldMenuContribution依赖了HelloWorldCommandContribution中注册的指令,所以也会它会去找CommandContribution对应的HelloWorldCommandContribution实例。

工作区

其实上面在根目录的package.json中简单的提及过,一个拓展的工作区有三个,那么该执行哪一个才能看到效果?区别又是什么?

hello-world工作区

在这个工作区中,是留给程序员编写代码的,然后暴露出相关的命令给theia执行,里面的package.json并没有script可以启动的命令.

...
  "scripts": {
    "prepare": "yarn run clean && yarn run build",
    "clean": "rimraf lib",
    "build": "tsc",
    "watch": "tsc -w"
  },
...

browser-app工作区

这个工作区就有意思了,它最终运行后,结果是显示在浏览器上的。多说无益,直接上代码和图片才是真理。

  1. 第一步打开项目,进入browser-app文件下 cd ./browser-app,打开终端输入yarn start browser-app后执行,打开任意浏览器,输入localhost:3000,忽略~你就会得到下面的页面

theia的第一个拓展-Hello World

这方面的文档可以在官方中找到关于browser-app工作区是如何启动的中找到。
  1. 点击左上角的Edit,选择Say Hello,注意观察右下角弹窗显示。

theia的第一个拓展-Hello World

electron-app工作区

其实第二种工作区的方式,在开发中好像并不是很常见,因为大部分人都喜欢在编辑器本身进行查看效果。

  1. 回到根目录下,在命令行中输入yarn rebuild:electron,然后等待一段时间后就会生成一个.browser_modules文件夹,但是现阶段没必要管,因为我们的操作并不是在这个文件夹中进行

theia的第一个拓展-Hello World

2. 进入`electron-app`文件夹中`cd ./electron-app`,打开命令行输入`yarn start electron-app`执行,忽略~你会得到以下的内容

theia的第一个拓展-Hello World

这方面的文档可以在官方中找到关于electron-app工作区是如何启动的中找到。

补充

上面那几个基本的操作就能满足我们的需求了吗,其实不然,如果我们修改了hello-world的代码,那么我们要怎么运行?貌似也没有介绍的样子?

  1. 其实很简单,比如我们在hello-world-contribution文件中修改我们的弹窗显示内容

theia的第一个拓展-Hello World

  1. 其实有过前端开发经验的已经看出来了,在hello-world中的package.json其实有一个script中的--prepare命令,这个指令可以直接让项目更新。在命令行中写入yarn prepare

  2. 再进入electron-app文件夹终端中输入yarn prepare后再执行yarn start electron-app,再根据上面的执行操作,得到下面的结果。

theia的第一个拓展-Hello World

总结

本篇是基于Hell world入门的引导文章,没有深入的讨论每个API的使用,只是浅谈该怎么运行和看懂代码。

参考

thiea官方文档:theia-ide.org/docs inversifyJS官方文档:github.com/inversify/I…