This commit is contained in:
zyh 2024-10-19 10:10:00 +00:00
parent 884d546c29
commit bea2de3414

View File

@ -0,0 +1,142 @@
# 浏览器刷新后的项目文件加载流程
本文档详细说明了在 Bolt 系统中,当浏览器刷新后,历史记录中的项目文件代码是如何被重新加载的。这个过程对于理解 Bolt 的持久化机制和用户体验至关重要。
## 1. 概述
Bolt 系统使用了多层机制来确保项目文件在浏览器刷新后能够被正确恢复:
1. WebContainer 持久化
2. 本地存储 (LocalStorage)
3. 文件系统状态管理
## 2. WebContainer 持久化
WebContainer 是 Bolt 系统的核心,它在浏览器中模拟了一个完整的文件系统和运行环境。
### 实现细节
文件位置: `app/lib/webcontainer/index.ts`
```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;
});
}
if (import.meta.hot) {
import.meta.hot.data.webcontainer = webcontainer;
}
```
这段代码确保了 WebContainer 只在客户端环境中初始化,并且在热更新过程中保持持久性。
## 3. 本地存储 (LocalStorage)
Bolt 使用浏览器的 LocalStorage 来存储项目的元数据和文件内容。
### 实现细节
文件位置: `app/lib/persistence/local-storage.ts`
```typescript
export function saveToLocalStorage(key: string, value: unknown): void {
try {
localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error('Error saving to localStorage:', error);
}
}
export function loadFromLocalStorage<T>(key: string): T | null {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : null;
} catch (error) {
console.error('Error loading from localStorage:', error);
return null;
}
}
```
这些函数用于将项目数据保存到 LocalStorage 和从中加载数据。
## 4. 文件系统状态管理
Bolt 使用 `FilesStore` 类来管理文件系统的状态。
### 实现细节
文件位置: `app/lib/stores/files.ts`
```typescript
export class FilesStore {
// ... 其他代码 ...
async loadFiles() {
const savedFiles = loadFromLocalStorage<FileMap>('bolt_files');
if (savedFiles) {
this.files.set(savedFiles);
} else {
// 如果本地存储中没有文件,则加载初始模板
const initialTemplate = await getInitialTemplate();
this.setFiles(initialTemplate);
}
}
// ... 其他代码 ...
}
```
`loadFiles` 方法首先尝试从 LocalStorage 加载保存的文件。如果没有找到,它会加载一个初始模板。
## 5. 运行流程
当浏览器刷新后,项目文件的加载流程如下:
1. WebContainer 初始化:
- `WebContainer.boot()` 方法被调用,初始化 WebContainer 环境。
- 如果是热更新,会使用之前保存的 WebContainer 实例。
2. 文件系统状态恢复:
- `FilesStore``loadFiles` 方法被调用。
- 首先尝试从 LocalStorage 加载保存的文件状态。
- 如果 LocalStorage 中没有保存的文件,则加载默认模板。
3. 编辑器状态恢复:
- `WorkbenchStore` 类负责恢复编辑器的状态,包括当前打开的文件、滚动位置等。
4. UI 更新:
- 一旦文件系统和编辑器状态被恢复,UI 组件(如 `Workbench``EditorPanel`)会重新渲染,显示恢复的项目状态。
## 6. 代码调用示例
以下是一个简化的代码调用流程示例:
```tsx
// 初始化 WebContainer
const webcontainer = await WebContainer.boot({ workdirName: WORK_DIR_NAME });
// 初始化 FilesStore
const filesStore = new FilesStore(webcontainer);
await filesStore.loadFiles();
// 初始化 WorkbenchStore
const workbenchStore = new WorkbenchStore(filesStore);
// 在 React 组件中使用
function App() {
const files = useStore(filesStore.files);
const currentDocument = useStore(workbenchStore.currentDocument);
return <Workbench files={files} currentDocument={currentDocument} />;
}
```
## 结论
Bolt 系统通过结合 WebContainer、LocalStorage 和状态管理,实现了项目文件在浏览器刷新后的持久化和快速恢复。这种设计不仅确保了用户数据的安全性,还提供了流畅的用户体验,使得用户可以在刷新后立即继续他们的工作。