# Cloud Studio 云部署插件

本项目现分为`社区版(SaaS)`及`Cloud版`两个入口，根据 Cloud Studio 部署环境的域名来区分不同版本的渲染。社区版为现 **cloudstudio.net** 域名下的服务（即旧版 DeployKit 基于 Malagu 已支持的功能服务），Cloud 版为部署于腾讯云 **ide.cloud.tencent.com** 域名下的服务。两个版本均基于同一个插件版本发版维护，但不同入口之间的服务不互通。

## 开发流程

1、 安装依赖

```
yarn
```

2、 安装/更新 Malagu CLI Runtimes 供插件内置使用（社区版）

注意：更新 Malagu 依赖版本需修改`/src/common/utils`中 import 的 `/runtimes/xx.xx.xx` 路径中的版本号以及`package.json`中的 `@malagu/cli` 的版本号再重新安装依赖。

```
yarn install-runtimes
```

3、 安装/更新 Deploy CLI 供插件内置使用（Cloud版）

本地插件开发与验证，需根据自有的操作系统(如： MacOS)来下载对应 OS 的依赖包。测试或发布到 Cloud Studio 中需使用 Linux 版本的依赖包进行打包 vsix 包。

> 如有新版 Deploy CLI，需要后端同学直接提供 Deploy CLI 文件，将提供的文件放到 cli 目录即可。


4、 React 项目构建生成 WebView 所需文件

```
yarn build-webview
```
**注：如需更新 Malagu CLI 需在`package.json`内配置版本后重新执行`步骤1`和`步骤2`，然后更新`/src/common/utils.ts`中引用的版本号**


5、 本地 VSCode 在 DEBUG 菜单内使用 `Run Extension` 或者将插件打包到 Cloud Studio 调试

> 如若本地最新代码已执行过**步骤2/3/4**，需本地加速打包vsix包可在根目录的`package.json`中修改`vscode:prepublish`脚本酌情删减步骤。

```
vsce package
```


## 国际化

### 插件国际化

由于官方目前还未提供 Webpack 版国际化的解决方案，且较为复杂，故使用与其他项目一致的工具库 [vscode-nls-i18n](https://github.com/axetroy/vscode-nls-i18n)

**使用方法**

1. 新增语言： 新增对应语言的 json 配置，如中文简体：package.nls.zh-cn.json
2. 新增词条： 在所有的 nls 配置中新增条目
3. 代码引用：

```
import { localize } from 'vscode-nls-i18n';
// 对应nls配置中的key
localize('module.key')
```


### Webview 国际化

本项目中的 Webview 分为两种形式展示，一种直接按字符串方式引用，一种是通过构建 React 项目生成的文件引用。其中字符串方式使用同上 `插件国际化` ，React 构建的项目则通过 [react-intl](https://formatjs.io/docs/react-intl/) 进行国际化。

**使用方法**

1. 新增语言： 在 i18n 目录下新增对应语言的 ts 文件，如：en.ts
2. 新增词条： 在 i18n 目录下所有的 ts 文件中新增条目
3. 代码引用：

```
import { IntlProvider, FormattedMessage } from 'react-intl';

// 引入所有使用的语言配置
import zh from '../../i18n/zh';
import en from '../../i18n/en';

// 根据获取到的vscode.env.language来选定使用的配置
const handleI18nMessages = (lang: string) => {
	let res = {};
	switch (lang) {
		case 'zh-CN':
			res = zh;
			break;
		case 'zh-cn':
			res = zh;
			break;
		default:
			res = en
			break;
	}
	return res;
}

// language: 当前对应的react-intl可识别的语言， messages: 所应用的具体语言包
<IntlProvider locale={language} messages={handleI18nMessages(language)}>
...
</IntlProvider>

```

## 使用 React 构建 Webview

由于本项目中使用的 Webview 较多且复杂，故使用 React 进行项目构建再进行引用。由于插件中的 Webview 引用每个都是一个单独且完整的 html，故需要对 React 项目进行改造支持多入口打包。React 项目涉及所有内容均位于`/web`目录。

> 项目基于 CRA 官方 v5.0.1（支持 Webpack5）进行改造。


**多入口配置**

1. 初始项目时通过 eject 展示所有配置。
2. 在 `/config/path.js` 中新增对应入口，请参考代码中的 `multiEntry`。
3. 在 `/config/webpack.config.js` 中修改 `entry` 属性，新增步骤 2 中对应的入口路径。
4. 在 `/config/webpack.config.js` 中修改 `plugins` 属性，新增 `HtmlWebpackPlugin` 配置打包后生成的 html 入口。
5. 在 `/config/webpackDevServer.config.js`中修改 `historyApiFallback` 新增 `rewrites` 项配置访问跳转。
6. 执行命令 `yarn build `生成打包后的文件于 `/build` 目录中，插件中根据 `asset-manifest.json` 来引用不同入口的 js 和 css 文件。

> 新增入口页面时需修改以上 2、3、4、5 中的内容。


**插件引用不同入口的 js 和 css 文件**

按插件创建 Webview 的正常流程生成 html 内容，在对应标签内引入 js 和 css。

1、读取 `asset-manifest.json` 找到需引用的对应 js 和 css，如：

```
const manifest = __non_webpack_require__(path.join(this._context.extensionPath, 'web', 'build', 'asset-manifest.json'));
const mainScript = manifest.files['main.js'];
const mainStyle = manifest.files['main.css'];
```

2、 将 js 和 css 文件解析成 vscode 可识别的路径， 如：

```
const scriptPathOnDisk = vscode.Uri.file(path.join(this._context.extensionPath, 'web', 'build', mainScript));
		const scriptUri = scriptPathOnDisk.with({ scheme: 'vscode-resource' });
```

3、 在 head 中引入 css，在 body 中引入 js， 如：

```
<link rel="stylesheet" type="text/css" href="${styleUri}">
```

```
<script nonce="${nonce}" src="${scriptUri}"></script>
```


**Web Style 配色注意事项**

由于 VSCode 可以切换主题配色，所以 Webview 页面中使用的色彩搭配需遵从 VSCode 自身的色彩体系规则并结合设计提供的大致颜色进行不同主题的适配。

1、 查询 VSCode 色彩变量： 本地 vscode 调用`"打开 Webview 开发人员工具"`**（或者打开Cloud Studio工作空间页面浏览器debug）**，审查某个元素后查看`右侧 Styles`标签下拉找到以`--vscode开头`的变量

2、 根据设计同的颜色找到 VSCode 对应一致或相似的颜色变量，赋值到对应样式的色码中。 列如：

```
body {
	color: var(--vscode-foreground);
}
```

3、 通过切换 VSCode 的`颜色主题`来验证不同主题下的色彩搭配是否和谐。(一般验证默认主题中的深色和浅色即可)


## 插件与 Webview 通信

本项目对插件与 Webview 通信使用了 sap-devx/webview-rpc，可较为方便地进行交互。
[@sap-devx/webview-rpc Github 文档](https://github.com/SAP/vscode-webview-rpc-lib)

1、 在 Webview 中

```
// 页面入口引入依赖库，并进行初始化
import { RpcBrowser } from '@sap-devx/webview-rpc/out.browser/rpc-browser';
import '@sap-devx/webview-rpc/out.browser/rpc-common';

const rpc = new RpcBrowser(window, vscode);

// 发消息给 vscode 插件（如需等待vscode回调值，则可使用 async/await 获取）
rpc.invoke('test',['a','b']);

// 注册指定方法来处理vscode发来的消息
rpc.registerMethod({ func: (value: string) => setLanguage(value), name: 'getLanguage' });

```

2、 在 vscode 中

```
// webview 组件入口引如依赖库，并进行初始化
import { RpcExtension } from '@sap-devx/webview-rpc/out.ext/rpc-extension';

const rpc = new RpcExtension(webviewView.webview);

// 发消息给 webview （如需等待webview回调值，则可使用 async/await 获取）
rpc.invoke('refresh', ['data']);
```


## 本地开发可能遇到的问题

1. MacOS 下运行 deploycli 后提示系统软件信任问题：根据系统提示到 `设置-通用` 菜单里信任该软件运行。

2. MacOS 下运行 deploycli 后提示无执行权限： 通过 `sudo chmod +x deploycli` 命令修改文件的可执行权限。