0
# File System
1
2
The file system provides the File class and compilation utilities for managing code files with compilation results, editor state persistence, and language detection.
3
4
## Capabilities
5
6
### File Class
7
8
Core file model representing a single file in the REPL with compilation state and editor persistence.
9
10
```typescript { .api }
11
/**
12
* Represents a file in the REPL with code content and compilation results
13
*/
14
class File {
15
/** File path/name relative to project root */
16
filename: string;
17
/** Raw source code content */
18
code: string;
19
/** Whether file is hidden from file explorer UI */
20
hidden: boolean;
21
22
/** Compilation results for different output formats */
23
compiled: {
24
/** Compiled JavaScript code */
25
js: string;
26
/** Extracted/compiled CSS */
27
css: string;
28
/** Server-side rendering compiled code */
29
ssr: string;
30
/** Client-side source map */
31
clientMap: string;
32
/** SSR source map */
33
ssrMap: string;
34
};
35
36
/** Monaco editor view state for cursor/scroll position persistence */
37
editorViewState: editor.ICodeEditorViewState | null;
38
39
/**
40
* Create a new file instance
41
* @param filename - File path/name
42
* @param code - Initial file content
43
* @param hidden - Whether file should be hidden from UI
44
*/
45
constructor(filename: string, code?: string, hidden?: boolean);
46
47
/**
48
* Detected language based on file extension
49
* @returns Language identifier for syntax highlighting
50
*/
51
readonly language: 'vue' | 'html' | 'css' | 'typescript' | 'javascript';
52
}
53
```
54
55
**Usage Examples:**
56
57
```typescript
58
import { File } from "@vue/repl/core";
59
60
// Create new Vue component file
61
const vueFile = new File(
62
'src/components/Button.vue',
63
`<template>
64
<button @click="handleClick">
65
<slot />
66
</button>
67
</template>
68
69
<script setup lang="ts">
70
const emit = defineEmits<{
71
click: [event: MouseEvent]
72
}>();
73
74
const handleClick = (event: MouseEvent) => {
75
emit('click', event);
76
};
77
</script>
78
79
<style scoped>
80
button {
81
padding: 8px 16px;
82
border-radius: 4px;
83
}
84
</style>`
85
);
86
87
// Create TypeScript utility file
88
const tsFile = new File(
89
'src/utils/helpers.ts',
90
`export const formatDate = (date: Date): string => {
91
return date.toLocaleDateString();
92
};
93
94
export const debounce = <T extends (...args: any[]) => any>(
95
fn: T,
96
delay: number
97
): T => {
98
let timeoutId: ReturnType<typeof setTimeout>;
99
return ((...args: any[]) => {
100
clearTimeout(timeoutId);
101
timeoutId = setTimeout(() => fn(...args), delay);
102
}) as T;
103
};`
104
);
105
106
// Create hidden configuration file
107
const configFile = new File(
108
'package.json',
109
JSON.stringify({ name: 'my-app', version: '1.0.0' }),
110
true // hidden from file explorer
111
);
112
113
// Access file properties
114
console.log(vueFile.language); // 'vue'
115
console.log(tsFile.language); // 'typescript'
116
console.log(vueFile.compiled.js); // Compiled JavaScript after compilation
117
```
118
119
### Compilation Function
120
121
Core compilation function that processes different file types into executable code.
122
123
```typescript { .api }
124
/**
125
* Compile a file based on its type and content
126
* Handles Vue SFC, TypeScript/JavaScript, CSS, and JSON files
127
* @param store - Store instance for compiler access and options
128
* @param file - File instance to compile
129
* @returns Promise resolving to array of compilation errors or empty array
130
*/
131
function compileFile(
132
store: Store,
133
file: File
134
): Promise<(string | Error)[]>;
135
```
136
137
**Supported File Types:**
138
139
- **`.vue`**: Vue Single File Components with full SFC compilation
140
- **`.ts`, `.tsx`**: TypeScript files with JSX support
141
- **`.js`, `.jsx`**: JavaScript files with JSX support
142
- **`.css`**: CSS stylesheets (passed through unchanged)
143
- **`.json`**: JSON files (converted to ES module exports)
144
145
**Usage Examples:**
146
147
```typescript
148
import { compileFile, File, useStore } from "@vue/repl/core";
149
150
const store = useStore();
151
const file = new File('src/App.vue', '<template><div>Hello</div></template>');
152
153
// Compile the file
154
const errors = await compileFile(store, file);
155
156
if (errors.length === 0) {
157
console.log('Compiled successfully');
158
console.log(file.compiled.js); // Compiled JavaScript
159
console.log(file.compiled.css); // Extracted CSS
160
} else {
161
console.error('Compilation errors:', errors);
162
}
163
164
// TypeScript file compilation
165
const tsFile = new File('utils.ts', `
166
export const add = (a: number, b: number): number => a + b;
167
`);
168
169
const tsErrors = await compileFile(store, tsFile);
170
console.log(tsFile.compiled.js); // Compiled JavaScript without types
171
```
172
173
### Language Detection
174
175
Files automatically detect their language based on file extensions for proper syntax highlighting and compilation.
176
177
```typescript { .api }
178
/**
179
* Language detection based on file extension
180
*/
181
type FileLanguage = 'vue' | 'html' | 'css' | 'typescript' | 'javascript';
182
183
/**
184
* Language detection mapping
185
*/
186
const languageMap = {
187
'.vue': 'vue',
188
'.html': 'html',
189
'.css': 'css',
190
'.ts': 'typescript',
191
'.tsx': 'typescript',
192
'.js': 'javascript',
193
'.jsx': 'javascript'
194
};
195
```
196
197
**Usage Example:**
198
199
```typescript
200
const files = [
201
new File('App.vue'),
202
new File('utils.ts'),
203
new File('styles.css'),
204
new File('config.json')
205
];
206
207
files.forEach(file => {
208
console.log(`${file.filename}: ${file.language}`);
209
});
210
// Output:
211
// App.vue: vue
212
// utils.ts: typescript
213
// styles.css: css
214
// config.json: javascript (default)
215
```
216
217
### Editor State Persistence
218
219
Files maintain editor view state for cursor position, scroll position, and selections across editor switches.
220
221
```typescript { .api }
222
/**
223
* Monaco editor view state interface
224
*/
225
interface ICodeEditorViewState {
226
cursorState: ICursorState[];
227
viewState: IViewState;
228
contributionsState: { [id: string]: any };
229
}
230
```
231
232
**Usage Example:**
233
234
```typescript
235
// View state is automatically managed by the editor components
236
// No manual intervention needed - handled by Monaco/CodeMirror editors
237
238
// Access view state if needed
239
const file = store.activeFile;
240
if (file.editorViewState) {
241
console.log('File has saved editor state');
242
}
243
```
244
245
### File Naming Conventions
246
247
The file system uses specific naming conventions for special files:
248
249
```typescript { .api }
250
/** Standard filename for import map configuration */
251
const importMapFile = 'import-map.json';
252
253
/** Standard filename for TypeScript configuration */
254
const tsconfigFile = 'tsconfig.json';
255
256
/**
257
* Add src/ prefix to relative file paths
258
* @param file - File path
259
* @returns Path with src/ prefix if needed
260
*/
261
function addSrcPrefix(file: string): string;
262
263
/**
264
* Remove src/ prefix from file paths for export
265
* @param file - File path with potential src/ prefix
266
* @returns Path without src/ prefix
267
*/
268
function stripSrcPrefix(file: string): string;
269
```
270
271
**Usage Examples:**
272
273
```typescript
274
import { stripSrcPrefix } from "@vue/repl/core";
275
276
// File path normalization
277
console.log(addSrcPrefix('App.vue')); // 'src/App.vue'
278
console.log(addSrcPrefix('src/App.vue')); // 'src/App.vue' (unchanged)
279
console.log(stripSrcPrefix('src/App.vue')); // 'App.vue'
280
281
// Special files bypass src/ prefix
282
console.log(addSrcPrefix('import-map.json')); // 'import-map.json'
283
console.log(addSrcPrefix('tsconfig.json')); // 'tsconfig.json'
284
```
285
286
## Compilation Details
287
288
### Vue SFC Compilation
289
290
Vue Single File Components undergo comprehensive compilation:
291
292
1. **Parsing**: Template, script, and style blocks extracted
293
2. **Script compilation**: TypeScript/JavaScript processing with imports
294
3. **Template compilation**: Vue template syntax to render functions
295
4. **Style processing**: CSS extraction and scoping
296
5. **Source map generation**: Debugging support with original source mapping
297
298
**Compilation Options:**
299
300
The compilation process respects store SFC options:
301
302
```typescript
303
// SFC compilation can be customized via store
304
store.sfcOptions = {
305
script: {
306
babelParserPlugins: ['jsx', 'decorators-legacy']
307
},
308
template: {
309
compilerOptions: {
310
isCustomElement: (tag) => tag.startsWith('custom-')
311
}
312
},
313
style: {
314
trim: true
315
}
316
};
317
```
318
319
### Error Handling
320
321
Compilation errors are comprehensive and helpful:
322
323
- **Syntax errors**: Parser errors with line/column information
324
- **Type errors**: TypeScript compilation issues
325
- **Template errors**: Vue template syntax problems
326
- **Import errors**: Module resolution failures
327
- **Preprocessing errors**: Unsupported language features
328
329
```typescript
330
// Errors are returned as array of strings or Error objects
331
const errors = await compileFile(store, file);
332
errors.forEach(error => {
333
if (typeof error === 'string') {
334
console.error('Compilation error:', error);
335
} else {
336
console.error('Exception:', error.message, error.stack);
337
}
338
});
339
```