API 文档
一、快速开始
示例工程见仓库
二、详细说明
1、安装 IDE 组件
yarn add @codeblitzjs/ide-core
2、组件使用
从 bundle 中引入已打包的文件
import { AppRenderer } from '@codeblitzjs/ide-core/bundle';
import '@codeblitzjs/ide-core/bundle/codeblitz.css';
const App: React.FC = () => (
<AppRenderer
appConfig={{
workspaceDir: 'playground',
}}
/>
);
ReactDOM.render(<App />, document.getElementById('main'));
3、引入语言
可按需引入,或者全部引入
// 全部引入
import '@codeblitzjs/ide-core/languages';
// 或者按以下部分按需引入
// 内置语言包会不断升级增加支持的语言
// 可查看最新包中的文件 https://www.npmjs.com/package/@codeblitzjs/ide-core?activeTab=code
import '@codeblitzjs/ide-core/languages/acss';
import '@codeblitzjs/ide-core/languages/bat';
import '@codeblitzjs/ide-core/languages/clojure';
import '@codeblitzjs/ide-core/languages/coffeescript';
import '@codeblitzjs/ide-core/languages/cpp';
import '@codeblitzjs/ide-core/languages/csharp';
import '@codeblitzjs/ide-core/languages/css';
import '@codeblitzjs/ide-core/languages/docker';
import '@codeblitzjs/ide-core/languages/fsharp';
import '@codeblitzjs/ide-core/languages/go';
import '@codeblitzjs/ide-core/languages/groovy';
import '@codeblitzjs/ide-core/languages/handlebars';
import '@codeblitzjs/ide-core/languages/hlsl';
import '@codeblitzjs/ide-core/languages/html';
import '@codeblitzjs/ide-core/languages/ini';
import '@codeblitzjs/ide-core/languages/java';
import '@codeblitzjs/ide-core/languages/javascript';
import '@codeblitzjs/ide-core/languages/json';
import '@codeblitzjs/ide-core/languages/Kotlin';
import '@codeblitzjs/ide-core/languages/less';
import '@codeblitzjs/ide-core/languages/log';
import '@codeblitzjs/ide-core/languages/lua';
import '@codeblitzjs/ide-core/languages/make';
import '@codeblitzjs/ide-core/languages/markdown';
import '@codeblitzjs/ide-core/languages/objective-c';
import '@codeblitzjs/ide-core/languages/perl';
import '@codeblitzjs/ide-core/languages/php';
import '@codeblitzjs/ide-core/languages/powershell';
import '@codeblitzjs/ide-core/languages/pug';
import '@codeblitzjs/ide-core/languages/python';
import '@codeblitzjs/ide-core/languages/razor';
import '@codeblitzjs/ide-core/languages/ruby';
import '@codeblitzjs/ide-core/languages/rust';
import '@codeblitzjs/ide-core/languages/scss';
import '@codeblitzjs/ide-core/languages/shaderlab';
import '@codeblitzjs/ide-core/languages/shellscript';
import '@codeblitzjs/ide-core/languages/sql';
import '@codeblitzjs/ide-core/languages/swift';
import '@codeblitzjs/ide-core/languages/typescript';
import '@codeblitzjs/ide-core/languages/vb';
import '@codeblitzjs/ide-core/languages/velocity';
import '@codeblitzjs/ide-core/languages/vscode-proto3';
import '@codeblitzjs/ide-core/languages/vue';
import '@codeblitzjs/ide-core/languages/xml';
import '@codeblitzjs/ide-core/languages/yaml';
4、按需引入语言功能
语言使用 worker 插件提供 LSP 服务,具备智能提示、定义跳转等和 node LSP 等同的能力
1)引入扩展
import html from '@codeblitzjs/ide-core/extensions/codeblitz.html-language-features-worker';
import css from '@codeblitzjs/ide-core/extensions/codeblitz.css-language-features-worker';
import typescript from '@codeblitzjs/ide-core/extensions/codeblitz.typescript-language-features-worker';
import json from '@codeblitzjs/ide-core/extensions/codeblitz.json-language-features-worker';
配置中引入
<AppRender
appConfig={{
extensionMetadata: [html, css, typescript, json],
}}
/>
5、自定义布局组件
大多情况下无需更改布局,也因此无需设置 layoutComponent 和 layoutConfig 相关的属性
通常可直接使用 IDE 提供的布局,如果需要更改布局,可自定义布局组件
import {
AppRenderer,
SlotRenderer,
SplitPanel,
BoxPanel,
} from '@codeblitzjs/ide-core/bundle';
// 界面布局组件,可根据需要调整
// BoxPanel 定义了 flex 布局
// SplitPanel 定义可自由拖拽改变宽高的布局
// SlotRenderer 定义具体的视图,slot 为视图的 id,会关联 layoutConfig 的模块
const LayoutComponent = () => (
<BoxPanel direction="top-to-bottom">
<SplitPanel overflow="hidden" id="main-horizontal" flex={1}>
<SlotRenderer slot="left" minResize={220} minSize={49} />
<SplitPanel
id="main-vertical"
minResize={300}
flexGrow={1}
direction="top-to-bottom"
>
<SlotRenderer flex={2} flexGrow={1} minResize={200} slot="main" />
{/* <SlotRenderer flex={1} minResize={160} slot="bottom" /> */}
</SplitPanel>
</SplitPanel>
<SlotRenderer slot="statusBar" />
</BoxPanel>
);
// 组件使用
<AppRender
appConfig={{
layoutComponent: LayoutComponent,
}}
/>;
6、更改布局模块配置
import { AppRenderer, SlotLocation } from '@codeblitzjs/ide-core/bundle';
const layoutConfig = {
[SlotLocation.left]: {
// 左侧 tabbar,默认包含资源管理器和搜索,这里将 modules 设置为 ['@opensumi/ide-explorer']
// 则只会展示资源管理器,id 为内部的定义的 id
modules: ['@opensumi/ide-explorer'],
},
[SlotLocation.main]: {
modules: ['@opensumi/ide-editor'],
},
};
// 组件使用
<AppRender
appConfig={{
layoutConfig,
}}
/>;
_更复杂的用法需要了解 _OpenSumi_ 的用法,可自行查阅相关文档_
三、类型说明
codeblitz 组件支持很多配置,详细 TS 类型及说明如下
interface IAppRendererProps extends IConfig {
// 加载完成的回调
onLoad?(app: IAppInstance): void;
// 自定义 loading 组件
Landing?: React.ComponentType<LandingProps>;
}
export interface IConfig {
/**
* 应用相关配置
*/
appConfig: IAppConfig;
/**
* 运行相关配置
*/
runtimeConfig: RuntimeConfig;
}
// IAppOpts 大部分为 kaitian 的配置,一般无需了解
export type IAppConfig = Partial<IAppOpts> & {
/**
* 工作空间目录,最好确保不同项目名称不同,如 group/repository 的形式,工作空间目录会挂载到 /workspace 根目录下
*/
workspaceDir: string;
} & {
/**
* 插件配置
*/
plugins?: IPluginConfig;
};
/**
* 运行时相关配置
*/
export interface RuntimeConfig {
/**
* 场景标识,目前用于 indexedDB store name 标识,暂不强制
* 不填表示为默认场景,此时同一域名会共享 indexedDB
* 如果指定为 null,表示不作为一个场景,此时不使用 indexedDB,也即不缓存工作空间及全局偏好设置等数据
*/
scenario?: string | null;
/** 工作空间配置 */
workspace?: {
/**
* 文件系统配置
*/
filesystem: FileSystemConfiguration;
/**
* 文档保存事件
* @param data.filepath 文档相对工作空间路径
* @param data.content 文档内容
*/
onDidSaveTextDocument?: (data: {
filepath: string;
content: string;
}) => void;
/**
* 文档更改事件
* @param data.filepath 文档相对工作空间路径
* @param data.content 文档内容
*/
onDidChangeTextDocument?: (data: {
filepath: string;
content: string;
}) => void;
/**
* 文件创建事件
* @param files 相对工作空间文件路径
*/
onDidCreateFiles?: (files: string[]) => void;
/**
* 文件删除事件
* @param files 相对工作空间文件路径
*/
onDidDeleteFiles?: (files: string[]) => void;
/**
* 文件变更事件
* @param data.filepath 相对工作空间文件路径
* @param data.content 文件内容
*/
onDidChangeFiles?: (data: { filepath: string; content: string }[]) => void;
};
/** 默认打开的文件,多个文件时,会展示最右边的文件 */
defaultOpenFile?: string | string[];
/** 禁止文件树更改,此时无法新增、删除、重命名文件 */
disableModifyFileTree?: boolean;
/** 禁止文件树,删除、重命名文件 待文件系统完善后加入删除重命名功能 */
scmFileTree?: boolean;
/** 注销左下角 bar */
unregisterActivityBarExtra?: boolean;
/** 隐藏左侧 tabbar */
hideLeftTabBar?: boolean;
/**
* 启动时打开的 editor
* none 不打开任何 editor
* welcomePage 打开欢迎页
* 后续考虑支持 'newUntitledFile', 'welcomePageInEmptyWorkbench', 'gettingStarted'
* @default welcomePage
*/
startupEditor?: 'none' | 'welcomePage' | 'readme';
/**
* 隐藏编辑器区 tab
*/
hideEditorTab?: boolean;
/**
* 取消左侧选中行高亮
*/
disableHighlightLine?: boolean;
/**
* 隐藏编辑器的面包屑导航
*/
hideBreadcrumb?: boolean;
/**
* reporter 服务,可获取内部上报的埋点相关数据
*/
reporter?: IReporter;
/**
* 配置需注销的快捷键
*/
unregisterKeybindings?: string[];
/**
* 文本搜索相关的配置,用于开启了左侧搜索面板的配置选项
*/
textSearch?: {
/**
* 搜索组件配置,默认均开启支持
* true 代码支持,false 代表不支持,不支持时界面相关 UI 会被隐藏
* 对于支持 local 的选项,代码支持本地过滤,开启此项配置代表本地会对返回的结果做进一步过滤
*/
config?: {
/**
* 正则匹配
*/
regexp?: Boolean;
/**
* 大小写匹配
*/
caseSensitive?: SearchMode;
/**
* 单词匹配
*/
wordMatch?: SearchMode;
/**
* 是否支持替换,对于只读系统该选项会自动设置为 false
*/
replace?: Boolean;
/**
* 文件包含
*/
include?: SearchMode;
/**
* 文件排除
*/
exclude?: SearchMode;
};
/**
* 提供给定文本模式匹配的结果
* @param query 查询参数
* @param options 搜索选项
* @param progress 所有结果都必须调用的进度回调
*/
provideResults(
query: TextSearchQuery,
options: TextSearchOptions,
progress: Progress<TextSearchResult>,
): ProviderResult<void>;
};
fileSearch?: {
/**
* 搜索模式配置
*/
config?: {
/**
* 文件包含
*/
include?: SearchMode;
/**
* 文件排除
*/
exclude?: SearchMode;
};
/**
* 提供匹配特定文件路径模式的一组文件
* @param query 查询参数
* @param options 搜索选项
*/
provideResults(
query: { pattern: string },
options: FileSearchOptions,
): ProviderResult<string[]>;
};
/**
* 欢迎页自定义内容
*/
WelcomePage?: React.FC;
/**
* 空白页自定义内容
*/
EditorEmpty?: React.FC;
/**
* 当文件后缀名判断格式 不满足条件时,可通过此配置项进行自定义
* 优先会从语法服务中获取类型
* https://aone.alipay.com/v2/project/1158176/bug/100102353
*/
resolveFileType?: (path: string) => 'image' | 'text' | 'video' | undefined;
}
四、一些配置说明
defaultPreferences
常用设置
general.theme
{string} 主题色
内置了一套 ide 的主题色,亮色 'opensumi-light'
,暗色 'opensumi-dark'
general.language
{'zh-CN' | 'en-US'},国际化语言设置editor.scrollBeyondLastLine
{boolean} 最后一行禁止继续滚动editor.forceReadOnly
{boolean} 设置全局只读files.associations
{Record<string, string>} 设置文件 关联,方便给自定义的后缀文件高亮,如
{
"files.associations": {
"*.htm": "html",
"*.html": "html",
"*.acss": "css",
".prettierrc": "yaml"
}
}
editor.readonlyFiles
{string[]} 只读的文件列表editor.previewMode
{boolean} 是否开启预览模式editor.autoSave
{'off' | 'afterDelay' | 'editorFocusChange' | ''windowLostFocus} 自动保存的模式editor.autoSaveDelay
{number} 当自动保存是 afterDelay 时,保存的延时时长
unregisterKeybindings
IDE 上内置了很多的快捷键,如果不需要可以配置,因为平台差异,所以同时设置 mac 和 windows,举例如下
ctrlcmd+s
保存文件ctrlcmd+w
Electron: 关闭当前 tabalt+shift+w
Web: 关闭当前 tabalt+cmd+left
Electron: 前一个 tabctrlcmd+pageup
Electron: 前一个 tabctrl+shift+tab
Electron: 前一个 tabctrlcmd+shift+[
Electron Mac: 前一个 tabctrlcmd+ctrl+left
Web: 前一个 tabalt+pageup
Web: 前一个 tabalt+cmd+right
Electron: 后一个 tabctrlcmd+pagedown
Electron: 后一个 tabctrl+tab
Electron: 后一个 tabctrlcmd+shift+]
Electron Mac: 后一个 tabctrlcmd+ctrl+right
Web: 后一个 tabalt+pagedown
Web: 后一个 tabalt+right
Windows : 下一个光标位置ctrl+shift+-
Mac : 下一个光标位置alt+left
Windows : 上一个光标位置ctrl+-
Mac : 上一个光标位置ctrlcmd+k m
: 修改当前打开的文件的语言ctrlcmd+\
: 向右拆分ctrlcmd+k ctrlcmd+right
: 下一个编辑器组ctrlcmd+k ctrlcmd+left
: 上一个编辑器组alt+ctrlcmd+s
:保存全部文件ctrlcmd+k w
: 关闭全部ctrlcmd+k enter
: 让当前 tab 退出 preview 状态ctrlcmd+k p
: 复制当前 tab 路径ctrlcmd+shift+t
Electron: 重新打开已关闭的文件alt+shift+t
Web: 重新打开已关闭的文件ctrlcmd+n
Electron: 创建一个新文件 tabalt+n
Web: 创建一个新文件 tabctrlcmd+t
Electron: 搜索 workspace symbolctrlcmd+o
Web: 搜索 workspace symbolctrlcmd+1
: 去到第 1 个编辑器组ctrlcmd+2
: 去到第 2 个编辑器组ctrlcmd+3
: 去到第 3 个编辑器组ctrlcmd+4
: 去到第 4 个编辑器组ctrlcmd+5
: 去到第 5 个编辑器组ctrlcmd+6
: 去到第 6 个编辑器组ctrlcmd+7
: 去到第 7 个编辑器组ctrlcmd+8
: 去到第 8 个编辑器组ctrlcmd+9
: 去到第 9 个编辑器组ctrlcmd+k up
: 将当前 tab 移动到上方编辑器组ctrlcmd+k left
: 将当前 tab 移动到左方编辑器组ctrlcmd+k right
: 将当前 tab 移动到右方编辑器组ctrlcmd+k down
: 将当前 tab 移动到下方编辑器组
五、完整示例参考
import React from 'react';
import ReactDOM from 'react-dom';
import Button from 'antd/lib/button';
import 'antd/lib/button/style/index.css';
// codeblitz
import {
AppRenderer,
SlotLocation,
SlotRenderer,
SplitPanel,
BoxPanel,
} from '@codeblitzjs/ide-core/bundle';
import '@codeblitzjs/ide-core/bundle/codeblitz.css';
// codeblitz
// 语法高亮
import '@codeblitzjs/ide-core/languages/html';
import '@codeblitzjs/ide-core/languages/handlebars';
import '@codeblitzjs/ide-core/languages/css';
import '@codeblitzjs/ide-core/languages/scss';
import '@codeblitzjs/ide-core/languages/less';
import '@codeblitzjs/ide-core/languages/javascript';
import '@codeblitzjs/ide-core/languages/typescript';
import '@codeblitzjs/ide-core/languages/json';
// end
// 语言功能
import html from '@codeblitzjs/ide-core/extensions/codeblitz.html-language-features-worker';
import css from '@codeblitzjs/ide-core/extensions/codeblitz.css-language-features-worker';
import typescript from '@codeblitzjs/ide-core/extensions/codeblitz.typescript-language-features-worker';
import json from '@codeblitzjs/ide-core/extensions/codeblitz.json-language-features-worker';
// 布局配置,可根据需要增删模块
export const layoutConfig = {
[SlotLocation.action]: {
modules: [''],
},
[SlotLocation.left]: {
modules: ['@opensumi/ide-explorer'],
},
[SlotLocation.main]: {
modules: ['@opensumi/ide-editor'],
},
// [SlotLocation.bottom]: {
// modules: ['@opensumi/ide-output', '@opensumi/ide-markers'],
// },
[SlotLocation.statusBar]: {
modules: ['@opensumi/ide-status-bar'],
},
};
// 界面布局组件,可根据需要调整
const LayoutComponent = () => (
<BoxPanel direction="top-to-bottom">
<SplitPanel overflow="hidden" id="main-horizontal" flex={1}>
<SlotRenderer slot="left" minResize={220} minSize={49} />
<SplitPanel
id="main-vertical"
minResize={300}
flexGrow={1}
direction="top-to-bottom"
>
<SlotRenderer flex={2} flexGrow={1} minResize={200} slot="main" />
{/* <SlotRenderer flex={1} minResize={160} slot="bottom" /> */}
</SplitPanel>
</SplitPanel>
<SlotRenderer slot="statusBar" />
</BoxPanel>
);
const App: React.FC = () => {
const [key, setKey] = React.useState(0);
return (
<div style={{ width: '100%', height: '100%', padding: 8 }}>
<div style={{ height: 40 }}>
<Button onClick={() => setKey((k) => k + 1)}>重置</Button>
</div>
<div style={{ height: 'calc(100% - 40px)', width: '50%' }}>
{key === 0 && (
<AppRenderer
key={key}
appConfig={{
// 工作空间目录,最好确保不同项目名称不同,如 group/repository 的形式,工作空间目录会挂载到 /workspace 根目录下
workspaceDir: 'playground',
layoutConfig,
layoutComponent: LayoutComponent,
// 默认偏好设置
defaultPreferences: {
'general.theme': 'opensumi-light',
},
// 左侧面板默认宽度
panelSizes: {
[SlotLocation.left]: 220,
},
// 扩展
extensionMetadata: [html, css, typescript, json],
}}
runtimeConfig={{
// 禁止就改文件树,此时无法新增、删除、重命名文件
disableModifyFileTree: true,
// 默认打开文件
defaultOpenFile: 'main.js',
workspace: {
// 文件系统配置
filesystem: {
fs: 'FileIndexSystem',
options: {
// 初始全量文件索引
requestFileIndex() {
return Promise.resolve({
'main.html': '<div id="root"></div>',
'main.css': 'body {}',
'main.js': 'console.log("main")',
'package.json': '{\n "name": "Riddle"\n}',
});
},
},
},
// 文件保存事件
onDidSaveTextDocument(e) {
console.log(e);
},
},
}}
/>
)}
</div>
</div>
);
};
ReactDOM.render(<App />, document.getElementById('main'));