mirror of
https://github.com/stackblitz/bolt.new
synced 2025-06-26 18:17:50 +00:00
docs
This commit is contained in:
parent
bea2de3414
commit
6d23441318
180
docs/默认模板配置更新流程.md
Normal file
180
docs/默认模板配置更新流程.md
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
# 默认模板配置更新流程
|
||||||
|
|
||||||
|
本文档详细说明了 Bolt 系统中默认模板的配置更新方法,以及相关的运行流程。这个过程对于理解 Bolt 的初始化和模板管理机制至关重要。
|
||||||
|
|
||||||
|
## 1. 模板定义
|
||||||
|
|
||||||
|
模板定义在 `app/utils/templates.ts` 文件中:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export const templates = {
|
||||||
|
basic: {
|
||||||
|
name: "Basic",
|
||||||
|
template: {
|
||||||
|
'index.js': {
|
||||||
|
file: {
|
||||||
|
contents: console.log('Hello, WebContainer!');,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'package.json': {
|
||||||
|
file: {
|
||||||
|
contents: { "name": "webcontainer-project", "version": "1.0.0", "description": "A basic WebContainer project", "main": "index.js", "scripts": { "start": "node index.js" }},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
react: {
|
||||||
|
name: "React",
|
||||||
|
template: {
|
||||||
|
// 定义 React 项目模板
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 可以添加更多模板...
|
||||||
|
};
|
||||||
|
export type TemplateName = keyof typeof templates;
|
||||||
|
```
|
||||||
|
|
||||||
|
这里定义了不同的项目模板,每个模板包含了初始文件结构和内容。
|
||||||
|
|
||||||
|
## 2. 获取初始模板
|
||||||
|
|
||||||
|
`getInitialTemplate` 函数用于获取指定的模板:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export async function getInitialTemplate(templateName: TemplateName = 'basic'): Promise<FileSystemTree> {
|
||||||
|
return templates[templateName].template;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
这个函数接受一个可选的 `templateName` 参数,默认值为 'basic'。它返回指定模板的文件系统树结构。
|
||||||
|
|
||||||
|
## 3. 模板选择器组件
|
||||||
|
|
||||||
|
在 `app/components/workbench/TemplateSelector.tsx` 中定义了模板选择器组件:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
export const TemplateSelector = memo(({ className, value, onChange }: TemplateSelectorProps) => {
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
options={Object.entries(templates).map(([key, value]) => ({ value: key, label: value.name }))}
|
||||||
|
value={value}
|
||||||
|
onChange={(newValue) => onChange(newValue as TemplateName)}
|
||||||
|
className={className}
|
||||||
|
placeholder="选择模板"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
这个组件允许用户从可用的模板中选择一个。
|
||||||
|
|
||||||
|
## 4. 模板更新流程
|
||||||
|
|
||||||
|
1. 用户界面初始化:
|
||||||
|
|
||||||
|
- 在 `app/components/chat/BaseChat.tsx` 中,初始化时设置默认模板:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const [selectedTemplate, setSelectedTemplate] = useState<TemplateName>('basic');
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 用户选择模板:
|
||||||
|
|
||||||
|
- 用户通过 `TemplateSelector` 组件选择一个新模板。
|
||||||
|
|
||||||
|
3. 模板更新处理:
|
||||||
|
|
||||||
|
- 当用户选择新模板时,触发 `handleTemplateChange` 函数:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const handleTemplateChange = async (templateName: TemplateName) => {
|
||||||
|
setSelectedTemplate(templateName);
|
||||||
|
try {
|
||||||
|
console.log('templateName', templateName);
|
||||||
|
// await workbenchStore.changeTemplate(templateName);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to change template:', error);
|
||||||
|
// 可以在这里添加错误处理,比如显示一个错误提示
|
||||||
|
}
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
4. 工作台状态更新:
|
||||||
|
|
||||||
|
- `workbenchStore.changeTemplate` 方法(目前被注释掉)应该负责更新工作台的状态,包括:
|
||||||
|
- 清除当前的文件系统状态
|
||||||
|
- 调用 `getInitialTemplate` 获取新模板的文件系统树
|
||||||
|
- 使用新的文件系统树初始化 WebContainer
|
||||||
|
- 更新 UI 以反映新的文件结构和内容
|
||||||
|
|
||||||
|
5. WebContainer 初始化:
|
||||||
|
|
||||||
|
- 在 `app/lib/webcontainer/index.ts` 中,WebContainer 的初始化过程应该使用选定的模板:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
export let webcontainer: Promise<WebContainer> = new Promise(() => {
|
||||||
|
// noop for ssr
|
||||||
|
});
|
||||||
|
if (!import.meta.env.SSR) {
|
||||||
|
webcontainer = Promise.resolve()
|
||||||
|
.then(() => {
|
||||||
|
return WebContainer.boot({ workdirName: WORK_DIR_NAME });
|
||||||
|
})
|
||||||
|
.then((webcontainer) => {
|
||||||
|
webcontainerContext.loaded = true;
|
||||||
|
return webcontainer;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
这里的 `WebContainer.boot` 方法应该使用从 `getInitialTemplate` 获取的文件系统树来初始化容器。
|
||||||
|
|
||||||
|
## 代码调用示例
|
||||||
|
|
||||||
|
以下是一个完整的代码调用示例,展示了如何在组件中实现模板选择和更新:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
// 在组件中
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { TemplateSelector } from '~/components/workbench/TemplateSelector';
|
||||||
|
import { getInitialTemplate, TemplateName } from '~/utils/templates';
|
||||||
|
import { workbenchStore } from '~/lib/stores/workbench';
|
||||||
|
function ProjectSetup() {
|
||||||
|
const [selectedTemplate, setSelectedTemplate] = useState<TemplateName>('basic');
|
||||||
|
const handleTemplateChange = async (templateName: TemplateName) => {
|
||||||
|
setSelectedTemplate(templateName);
|
||||||
|
try {
|
||||||
|
const templateTree = await getInitialTemplate(templateName);
|
||||||
|
await workbenchStore.changeTemplate(templateTree);
|
||||||
|
console.log(Template changed to ${templateName});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to change template:', error);
|
||||||
|
// 显示错误提示
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>选择项目模板</h2>
|
||||||
|
<TemplateSelector
|
||||||
|
value={selectedTemplate}
|
||||||
|
onChange={handleTemplateChange}
|
||||||
|
className="w-full mb-4"
|
||||||
|
/>
|
||||||
|
{/ 其他项目设置选项 /}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default ProjectSetup;
|
||||||
|
```
|
||||||
|
|
||||||
|
在这个例子中,`ProjectSetup` 组件允许用户选择一个模板,并在选择改变时更新工作台的状态。
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. 错误处理: 确保在模板更新过程中妥善处理可能出现的错误,并向用户提供适当的反馈。
|
||||||
|
2. 性能优化: 对于大型模板,考虑实现懒加载或分块加载策略。
|
||||||
|
3. 用户体验: 在模板切换过程中,考虑添加加载指示器以提供更好的用户体验。
|
||||||
|
4. 状态管理: 确保模板更新操作正确地与全局状态管理系统(如 nanostores)集成。
|
||||||
|
5. WebContainer 集成: 模板更新应该与 WebContainer 的生命周期管理紧密集成,确保文件系统的一致性。
|
||||||
|
|
||||||
|
通过这种方式,Bolt 系统能够灵活地支持多种项目模板,并允许用户轻松切换between不同的起始配置。这种机制为用户提供了更好的项目初始化体验,同时也为系统的可扩展性奠定了基础。
|
||||||
Loading…
Reference in New Issue
Block a user