Skip to content

Commit 11cef05

Browse files
committed
feat(Compilers): allow SFC to import other SFCs encoded as data URLs
1 parent 4f9ede1 commit 11cef05

3 files changed

Lines changed: 23 additions & 8 deletions

File tree

src/livecodes/compiler/import-map.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,25 +144,35 @@ export const isScriptImport = (mod: string) =>
144144
mod.toLowerCase().endsWith('.vue') ||
145145
mod.toLowerCase().endsWith('.svelte')));
146146

147+
const modulesCache: Record<string, string> = {};
148+
const fetchModule = async (mod: string) => {
149+
if (modulesCache[mod]) {
150+
return modulesCache[mod];
151+
}
152+
const res = await fetch(mod);
153+
const content = await res.text();
154+
modulesCache[mod] = content;
155+
return content;
156+
};
157+
147158
export const replaceSFCImports = async (
148159
code: string,
149160
{
150161
filename,
151162
config,
152-
sfcExtension,
163+
isSfc,
153164
getLanguageByAlias,
154165
compileSFC,
155166
external,
156167
}: {
157168
config: Config;
158169
filename: string;
159-
sfcExtension: string;
170+
isSfc: (mod: string) => boolean;
160171
getLanguageByAlias: (alias: string) => Language | undefined;
161172
compileSFC: (code: string, options: { filename: string; config: Config }) => Promise<string>;
162173
external?: string;
163174
},
164175
) => {
165-
const isSfc = (mod: string) => mod.toLowerCase().endsWith(sfcExtension);
166176
const isExtensionless = (mod: string) =>
167177
mod.startsWith('.') && !mod.split('/')[mod.split('/').length - 1].includes('.');
168178
const sfcImports = getImports(code).filter(
@@ -196,8 +206,7 @@ export const replaceSFCImports = async (
196206
? new URL(mod, filename).href
197207
: modulesService.getUrl(mod));
198208

199-
const res = await fetch(url);
200-
const content = await res.text();
209+
const content = await fetchModule(url);
201210
const compiled = isSfc(mod)
202211
? await compileSFC(content, { filename: url, config })
203212
: await replaceSFCImports(
@@ -208,7 +217,7 @@ export const replaceSFCImports = async (
208217
config,
209218
)
210219
).code,
211-
{ filename: url, config, sfcExtension, getLanguageByAlias, compileSFC, external },
220+
{ filename: url, config, isSfc, getLanguageByAlias, compileSFC, external },
212221
);
213222
if (!compiled) return;
214223
const dataUrl = toDataUrl(compiled);

src/livecodes/languages/svelte/lang-svelte-compiler.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@ import { getCompileResult } from '../../compiler';
2020
}
2121
if (!code) return getCompileResult('');
2222

23+
const isSfc = (mod: string) =>
24+
mod.toLowerCase().endsWith('.svelte') || mod.toLowerCase().startsWith('data:text/svelte');
25+
2326
const fullCode = await replaceSFCImports(code, {
2427
config,
2528
filename,
2629
getLanguageByAlias,
27-
sfcExtension: '.svelte',
30+
isSfc,
2831
compileSFC: async (
2932
code: string,
3033
{ config, filename }: { config: Config; filename: string },

src/livecodes/languages/vue/lang-vue-compiler.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,14 @@ import { getLanguageByAlias } from '../utils';
3737
}
3838
if (!code.trim()) return;
3939

40+
const isSfc = (mod: string) =>
41+
mod.toLowerCase().endsWith('.vue') || mod.toLowerCase().startsWith('data:text/vue');
42+
4043
code = await replaceSFCImports(code, {
4144
filename,
4245
config,
43-
sfcExtension: '.vue',
4446
getLanguageByAlias,
47+
isSfc,
4548
compileSFC: async (code, { filename, config }) => {
4649
const compiled = (await compileVueSFC(code, { filename, config }))?.js || '';
4750
importedContent += `\n${filename}\n\n${compiled}\n`;

0 commit comments

Comments
 (0)