Skip to content

Commit b4416a7

Browse files
authored
fix: make repl more robust (#1393)
- ensure tailwind tokens are preserved when rebundling with cache - ensure cache is created the first time already and available for the second run - more robust resolution - pass better filename for compiler so __svelte_meta.loc.file is more useful (v0 needs this for analysis)
1 parent e8157a9 commit b4416a7

File tree

3 files changed

+34
-15
lines changed

3 files changed

+34
-15
lines changed

apps/svelte.dev/src/routes/(authed)/playground/[id]/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
name = recovered.name;
7474
}
7575
76-
repl.set({ files, tailwind: recovered.tailwind ?? false });
76+
repl.set({ files, tailwind: recovered.tailwind ?? false, aliases: recovered.aliases });
7777
} catch {
7878
alert(`Couldn't load the code from the URL. Make sure you copied the link correctly.`);
7979
}

packages/repl/src/lib/workers/bundler/index.ts

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ const ABORT = { aborted: true };
100100
let previous: {
101101
key: string;
102102
cache: RollupCache | undefined;
103+
/** Needed because if rollup cache hits then we won't be able to pick up all candidates in subsequent runs */
104+
tailwind_candidates: Set<string>;
103105
};
104106

105107
let tailwind: Awaited<ReturnType<typeof init_tailwind>>;
@@ -143,12 +145,14 @@ async function get_bundle(
143145
) {
144146
let bundle;
145147

148+
const key = JSON.stringify(options);
146149
/** A set of package names (without subpaths) to include in pkg.devDependencies when downloading an app */
147150
const imports: Set<string> = new Set();
148151
const warnings: Warning[] = [];
149152
const all_warnings: Array<{ message: string }> = [];
150153

151-
const tailwind_candidates: string[] = [];
154+
const tailwind_candidates =
155+
previous?.key === key ? previous.tailwind_candidates : new Set<string>();
152156

153157
function add_tailwind_candidates(ast: Node | undefined) {
154158
if (!ast) return;
@@ -160,12 +164,16 @@ async function get_bundle(
160164
},
161165
Literal(node) {
162166
if (typeof node.value === 'string' && node.value) {
163-
tailwind_candidates.push(...node.value.split(' '));
167+
for (const candidate of node.value.split(' ')) {
168+
if (candidate) tailwind_candidates.add(candidate);
169+
}
164170
}
165171
},
166172
TemplateElement(node) {
167173
if (node.value.raw) {
168-
tailwind_candidates.push(...node.value.raw.split(' '));
174+
for (const candidate of node.value.raw.split(' ')) {
175+
if (candidate) tailwind_candidates.add(candidate);
176+
}
169177
}
170178
}
171179
});
@@ -283,20 +291,19 @@ async function get_bundle(
283291
transform(code, id) {
284292
if (uid !== current_id) throw ABORT;
285293

286-
const message = `bundling ${id.replace(VIRTUAL + '/', '').replace(NPM + '/', '')}`;
287-
self.postMessage({ type: 'status', message });
294+
const name = id.replace(VIRTUAL + '/', '').replace(NPM + '/', '');
288295

289-
if (!/\.(svelte|js|ts)$/.test(id)) return null;
296+
self.postMessage({ type: 'status', message: `bundling ${name}` });
290297

291-
const name = id.split('/').pop()?.split('.')[0];
298+
if (!/\.(svelte|js|ts)$/.test(id)) return null;
292299

293300
let result: CompileResult;
294301

295302
if (id.endsWith('.svelte')) {
296303
const is_gt_5 = Number(svelte.VERSION.split('.')[0]) >= 5;
297304

298305
const compilerOptions: any = {
299-
filename: name + '.svelte',
306+
filename: name,
300307
generate: is_gt_5 ? 'client' : 'dom',
301308
dev: true,
302309
fragments: options.fragments
@@ -323,7 +330,9 @@ async function get_bundle(
323330
if (Array.isArray(node.value)) {
324331
for (const chunk of node.value) {
325332
if (chunk.type === 'Text') {
326-
tailwind_candidates.push(...chunk.data.split(' '));
333+
for (const candidate of chunk.data.split(' ')) {
334+
if (candidate) tailwind_candidates.add(candidate);
335+
}
327336
}
328337
}
329338
}
@@ -363,7 +372,7 @@ async function get_bundle(
363372
}
364373
} else if (/\.svelte\.(js|ts)$/.test(id)) {
365374
const compilerOptions: any = {
366-
filename: name + '.js',
375+
filename: name,
367376
generate: 'client',
368377
dev: true
369378
};
@@ -400,13 +409,12 @@ async function get_bundle(
400409
}
401410
};
402411

403-
const key = JSON.stringify(options);
404412
const handled_css_ids = new Set<string>();
405413
let user_css = '';
406414

407415
bundle = await rollup({
408416
input: './__entry.js',
409-
cache: previous?.key === key && previous.cache,
417+
cache: previous?.key === key ? previous.cache : true,
410418
plugins: [
411419
alias_plugin(options.aliases, virtual),
412420
typescript_strip_types,
@@ -460,12 +468,12 @@ async function get_bundle(
460468
}
461469
});
462470

463-
previous = { key, cache: bundle.cache };
471+
previous = { key, cache: bundle.cache, tailwind_candidates };
464472

465473
return {
466474
bundle,
467475
css: options.tailwind
468-
? (tailwind ?? (await init_tailwind(user_css))).build(tailwind_candidates)
476+
? (tailwind ?? (await init_tailwind(user_css))).build([...tailwind_candidates])
469477
: user_css
470478
? user_css
471479
: null,

packages/repl/src/lib/workers/bundler/plugins/alias.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,17 @@ export function resolve(virtual: Map<string, File>, importee: string, importer:
5656
}
5757
}
5858

59+
if (url.href.endsWith('.ts') || url.href.endsWith('.js')) {
60+
// One can mean the other (TS encourages you to import .ts files with .js suffixes, and bundlers handle these cases)
61+
const other_suffix = url.href.endsWith('.ts') ? '.js' : '.ts';
62+
const with_other_suffix = `${url.href.slice(VIRTUAL.length + 1, -3)}${other_suffix}`;
63+
const file = virtual.get(with_other_suffix);
64+
65+
if (file) {
66+
return url.href.slice(0, -3) + other_suffix;
67+
}
68+
}
69+
5970
throw new Error(
6071
`'${importee}' (imported by ${importer.replace(VIRTUAL + '/', '')}) does not exist`
6172
);

0 commit comments

Comments
 (0)