Skip to content

Commit 074a208

Browse files
committed
html main files
1 parent 49c7d66 commit 074a208

File tree

5 files changed

+88
-44
lines changed

5 files changed

+88
-44
lines changed

src/editor/Editor.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const onChange = debounce((code: string) => {
1414
1515
const activeMode = computed(() => {
1616
const { filename } = store.state.activeFile
17-
return filename.endsWith('.vue')
17+
return filename.endsWith('.vue') || filename.endsWith('.html')
1818
? 'htmlmixed'
1919
: filename.endsWith('.css')
2020
? 'css'

src/output/Preview.vue

+6-14
Original file line numberDiff line numberDiff line change
@@ -163,30 +163,22 @@ async function updatePreview() {
163163
console.log(`[@vue/repl] successfully compiled ${modules.length} modules.`)
164164
165165
const codeToEval = [
166-
`window.__modules__ = {};window.__css__ = '';document.body.innerHTML = ''`,
167-
...modules
166+
`window.__modules__ = {};window.__css__ = '';` +
167+
`if (window.__app__) window.__app__.unmount();` +
168+
`document.body.innerHTML = '<div id="app"></div>'`,
169+
...modules,
170+
`document.getElementById('__sfc-styles').innerHTML = window.__css__`
168171
]
169172
170-
// determine app bootstrapping code - if main file is a vue file, mount it.
173+
// if main file is a vue file, mount it.
171174
const mainFile = store.state.mainFile
172175
if (mainFile.endsWith('.vue')) {
173176
codeToEval.push(
174177
`import { createApp as _createApp } from "vue"
175-
176-
if (window.__app__) {
177-
window.__app__.unmount()
178-
}
179-
180-
document.body.innerHTML = '<div id="app"></div>'
181-
document.getElementById('__sfc-styles').innerHTML = window.__css__
182178
const app = window.__app__ = _createApp(__modules__["${mainFile}"].default)
183179
app.config.errorHandler = e => console.error(e)
184180
app.mount('#app')`.trim()
185181
)
186-
} else {
187-
codeToEval.push(
188-
`\ndocument.getElementById('__sfc-styles').innerHTML = window.__css__`
189-
)
190182
}
191183
192184
// eval code in sandbox

src/output/moduleCompiler.ts

+61-17
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,39 @@ function processFile(store: ReplStore, file: File, seen: Set<File>) {
4646
}
4747
seen.add(file)
4848

49-
const { js, css } = file.compiled
49+
if (file.filename.endsWith('.html')) {
50+
return processHtmlFile(store, file.code, file.filename, seen)
51+
}
52+
53+
let [js, importedFiles] = processModule(
54+
store,
55+
file.compiled.js,
56+
file.filename
57+
)
58+
// append css
59+
if (file.compiled.css) {
60+
js += `\nwindow.__css__ += ${JSON.stringify(file.compiled.css)}`
61+
}
62+
// crawl imports
63+
const processed = [js]
64+
if (importedFiles.size) {
65+
for (const imported of importedFiles) {
66+
processed.push(...processFile(store, store.state.files[imported], seen))
67+
}
68+
}
69+
// return a list of files to further process
70+
return processed
71+
}
5072

51-
const s = new MagicString(js)
73+
function processModule(
74+
store: ReplStore,
75+
src: string,
76+
filename: string
77+
): [string, Set<string>] {
78+
const s = new MagicString(src)
5279

53-
const ast = babelParse(js, {
54-
sourceFilename: file.filename,
80+
const ast = babelParse(src, {
81+
sourceFilename: filename,
5582
sourceType: 'module',
5683
plugins: [...babelParserDefaultPlugins]
5784
}).program.body
@@ -86,7 +113,7 @@ function processFile(store: ReplStore, file: File, seen: Set<File>) {
86113
// 0. instantiate module
87114
s.prepend(
88115
`const ${moduleKey} = __modules__[${JSON.stringify(
89-
file.filename
116+
filename
90117
)}] = { [Symbol.toStringTag]: "Module" }\n\n`
91118
)
92119

@@ -236,18 +263,35 @@ function processFile(store: ReplStore, file: File, seen: Set<File>) {
236263
}
237264
})
238265

239-
// append CSS injection code
240-
if (css) {
241-
s.append(`\nwindow.__css__ += ${JSON.stringify(css)}`)
242-
}
266+
return [s.toString(), importedFiles]
267+
}
243268

244-
const processed = [s.toString()]
245-
if (importedFiles.size) {
246-
for (const imported of importedFiles) {
247-
processed.push(...processFile(store, store.state.files[imported], seen))
248-
}
249-
}
269+
const scriptRE = /<script\b(?:\s[^>]*>|>)([^]*?)<\/script>/gi
270+
const scriptModuleRE =
271+
/<script\b[^>]*type\s*=\s*(?:"module"|'module')[^>]*>([^]*?)<\/script>/gi
250272

251-
// return a list of files to further process
252-
return processed
273+
function processHtmlFile(
274+
store: ReplStore,
275+
src: string,
276+
filename: string,
277+
seen: Set<File>
278+
): string[] {
279+
const deps: string[] = []
280+
let jsCode = ''
281+
const html = src
282+
.replace(scriptModuleRE, (_, content) => {
283+
const [code, importedFiles] = processModule(store, content, filename)
284+
if (importedFiles.size) {
285+
for (const imported of importedFiles) {
286+
deps.push(...processFile(store, store.state.files[imported], seen))
287+
}
288+
}
289+
jsCode += '\n' + code
290+
return ''
291+
})
292+
.replace(scriptRE, (_, content) => {
293+
jsCode += '\n' + content
294+
return ''
295+
})
296+
return [jsCode, ...deps, `document.body.innerHTML = ${JSON.stringify(html)}`]
253297
}

src/transform.ts

+18-11
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,25 @@ export async function compileFile(
2424
return
2525
}
2626

27-
if (!filename.endsWith('.vue')) {
28-
if (filename.endsWith('.css')) {
29-
compiled.css = code
30-
} else {
31-
if (shouldTransformRef(code)) {
32-
code = transformRef(code, { filename }).code
33-
}
34-
if (filename.endsWith('.ts')) {
35-
code = await transformTS(code)
36-
}
37-
compiled.js = compiled.ssr = code
27+
if (filename.endsWith('.css')) {
28+
compiled.css = code
29+
store.state.errors = []
30+
return
31+
}
32+
33+
if (filename.endsWith('.js') || filename.endsWith('.ts')) {
34+
if (shouldTransformRef(code)) {
35+
code = transformRef(code, { filename }).code
36+
}
37+
if (filename.endsWith('.ts')) {
38+
code = await transformTS(code)
3839
}
40+
compiled.js = compiled.ssr = code
41+
store.state.errors = []
42+
return
43+
}
44+
45+
if (!filename.endsWith('.vue')) {
3946
store.state.errors = []
4047
return
4148
}

test/main.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ const App = {
1515

1616
setTimeout(() => {
1717
store.setFiles({
18+
'index.html': '<h1>yo</h1>',
1819
'main.js': 'document.body.innerHTML = "<h1>hello</h1>"'
19-
}, 'main.js')
20+
}, 'index.html')
2021
}, 1000);
2122

2223
// store.setVueVersion('3.2.8')

0 commit comments

Comments
 (0)